diff options
author | Peter D'Hoye <peter.dhoye@gmail.com> | 2006-08-16 23:26:55 +0000 |
---|---|---|
committer | Peter D'Hoye <peter.dhoye@gmail.com> | 2006-08-16 23:26:55 +0000 |
commit | 5fc66e58dd8a62099cfb1c3f7ae48d7115376be3 (patch) | |
tree | 0dc6123bb179a5eba4953d62155a4b48dea75869 | |
parent | c5a24c69221dbd8f2c55f007d9d7eaa2222fa5df (diff) | |
download | rockbox-5fc66e58dd8a62099cfb1c3f7ae48d7115376be3.tar.gz rockbox-5fc66e58dd8a62099cfb1c3f7ae48d7115376be3.zip |
Automatic Gain Control during recording. At this point only compiled for iriver h1x0 and h3x0. Patch FS#4748 by Jvo Studer, Martin Scarratt and myself.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10625 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/lang/english.lang | 117 | ||||
-rw-r--r-- | apps/recorder/peakmeter.c | 29 | ||||
-rw-r--r-- | apps/recorder/peakmeter.h | 4 | ||||
-rw-r--r-- | apps/recorder/recording.c | 518 | ||||
-rw-r--r-- | apps/settings.c | 8 | ||||
-rw-r--r-- | apps/settings.h | 20 | ||||
-rw-r--r-- | apps/sound_menu.c | 41 | ||||
-rw-r--r-- | firmware/export/config-h100.h | 2 | ||||
-rw-r--r-- | firmware/export/config-h120.h | 2 | ||||
-rw-r--r-- | firmware/export/config-h300.h | 2 |
10 files changed, 738 insertions, 5 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 984aa1be95..6a7d752ec6 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang | |||
@@ -9660,3 +9660,120 @@ | |||
9660 | *: "Full Path" | 9660 | *: "Full Path" |
9661 | </voice> | 9661 | </voice> |
9662 | </phrase> | 9662 | </phrase> |
9663 | <phrase> | ||
9664 | id: LANG_RECORD_AGC_PRESET | ||
9665 | desc: automatic gain control in record settings | ||
9666 | <source> | ||
9667 | *: "Automatic Gain Control" | ||
9668 | </source> | ||
9669 | <dest> | ||
9670 | *: "Automatic Gain Control" | ||
9671 | </dest> | ||
9672 | <voice> | ||
9673 | *: "pixels" | ||
9674 | </voice> | ||
9675 | </phrase> | ||
9676 | <phrase> | ||
9677 | id: LANG_AGC_SAFETY | ||
9678 | desc: AGC preset | ||
9679 | <source> | ||
9680 | *: "Safety (clip)" | ||
9681 | </source> | ||
9682 | <dest> | ||
9683 | *: "Safety (clip)" | ||
9684 | </dest> | ||
9685 | <voice> | ||
9686 | *: "pixels" | ||
9687 | </voice> | ||
9688 | </phrase> | ||
9689 | <phrase> | ||
9690 | id: LANG_AGC_LIVE | ||
9691 | desc: AGC preset | ||
9692 | <source> | ||
9693 | *: "Live (slow)" | ||
9694 | </source> | ||
9695 | <dest> | ||
9696 | *: "Live (slow)" | ||
9697 | </dest> | ||
9698 | <voice> | ||
9699 | *: "pixels" | ||
9700 | </voice> | ||
9701 | </phrase> | ||
9702 | <phrase> | ||
9703 | id: LANG_AGC_DJSET | ||
9704 | desc: AGC preset | ||
9705 | <source> | ||
9706 | *: "DJ-Set (slow)" | ||
9707 | </source> | ||
9708 | <dest> | ||
9709 | *: "DJ-Set (slow)" | ||
9710 | </dest> | ||
9711 | <voice> | ||
9712 | *: "pixels" | ||
9713 | </voice> | ||
9714 | </phrase> | ||
9715 | <phrase> | ||
9716 | id: LANG_AGC_MEDIUM | ||
9717 | desc: AGC preset | ||
9718 | <source> | ||
9719 | *: "Medium" | ||
9720 | </source> | ||
9721 | <dest> | ||
9722 | *: "Medium" | ||
9723 | </dest> | ||
9724 | <voice> | ||
9725 | *: "pixels" | ||
9726 | </voice> | ||
9727 | </phrase> | ||
9728 | <phrase> | ||
9729 | id: LANG_AGC_VOICE | ||
9730 | desc: AGC preset | ||
9731 | <source> | ||
9732 | *: "Voice (fast)" | ||
9733 | </source> | ||
9734 | <dest> | ||
9735 | *: "Voice (fast)" | ||
9736 | </dest> | ||
9737 | <voice> | ||
9738 | *: "pixels" | ||
9739 | </voice> | ||
9740 | </phrase> | ||
9741 | <phrase> | ||
9742 | id: LANG_RECORD_AGC_CLIPTIME | ||
9743 | desc: in record settings | ||
9744 | <source> | ||
9745 | *: "AGC clip time" | ||
9746 | </source> | ||
9747 | <dest> | ||
9748 | *: "AGC clip time" | ||
9749 | </dest> | ||
9750 | <voice> | ||
9751 | *: "pixels" | ||
9752 | </voice> | ||
9753 | </phrase> | ||
9754 | <phrase> | ||
9755 | id: LANG_RECORDING_AGC_PRESET | ||
9756 | desc: automatic gain control in recording screen | ||
9757 | <source> | ||
9758 | *: "AGC" | ||
9759 | </source> | ||
9760 | <dest> | ||
9761 | *: "AGC" | ||
9762 | </dest> | ||
9763 | <voice> | ||
9764 | *: "pixels" | ||
9765 | </voice> | ||
9766 | </phrase> | ||
9767 | <phrase> | ||
9768 | id: LANG_RECORDING_AGC_MAXGAIN | ||
9769 | desc: AGC maximum gain in recording screen | ||
9770 | <source> | ||
9771 | *: "AGC max. gain" | ||
9772 | </source> | ||
9773 | <dest> | ||
9774 | *: "AGC max. gain" | ||
9775 | </dest> | ||
9776 | <voice> | ||
9777 | *: "pixels" | ||
9778 | </voice> | ||
9779 | </phrase> | ||
diff --git a/apps/recorder/peakmeter.c b/apps/recorder/peakmeter.c index 0f8da98308..58c85b2161 100644 --- a/apps/recorder/peakmeter.c +++ b/apps/recorder/peakmeter.c | |||
@@ -62,6 +62,10 @@ static int pm_cur_left; /* current values (last peak_meter_peek) */ | |||
62 | static int pm_cur_right; | 62 | static int pm_cur_right; |
63 | static int pm_max_left; /* maximum values between peak meter draws */ | 63 | static int pm_max_left; /* maximum values between peak meter draws */ |
64 | static int pm_max_right; | 64 | static int pm_max_right; |
65 | #ifdef HAVE_AGC | ||
66 | static int pm_peakhold_left; /* max. peak values between peakhold calls */ | ||
67 | static int pm_peakhold_right; /* used for AGC and histogram display */ | ||
68 | #endif | ||
65 | 69 | ||
66 | /* Clip hold */ | 70 | /* Clip hold */ |
67 | static bool pm_clip_left = false; /* when true a clip has occurred */ | 71 | static bool pm_clip_left = false; /* when true a clip has occurred */ |
@@ -716,6 +720,10 @@ static int peak_meter_read_l(void) | |||
716 | by peak_meter_peek since the last call of peak_meter_read_l */ | 720 | by peak_meter_peek since the last call of peak_meter_read_l */ |
717 | int retval = pm_max_left; | 721 | int retval = pm_max_left; |
718 | 722 | ||
723 | #ifdef HAVE_AGC | ||
724 | /* store max peak value for peak_meter_get_peakhold_x readout */ | ||
725 | pm_peakhold_left = MAX(pm_max_left, pm_peakhold_left); | ||
726 | #endif | ||
719 | #ifdef PM_DEBUG | 727 | #ifdef PM_DEBUG |
720 | peek_calls = 0; | 728 | peek_calls = 0; |
721 | #endif | 729 | #endif |
@@ -737,6 +745,10 @@ static int peak_meter_read_r(void) | |||
737 | by peak_meter_peek since the last call of peak_meter_read_r */ | 745 | by peak_meter_peek since the last call of peak_meter_read_r */ |
738 | int retval = pm_max_right; | 746 | int retval = pm_max_right; |
739 | 747 | ||
748 | #ifdef HAVE_AGC | ||
749 | /* store max peak value for peak_meter_get_peakhold_x readout */ | ||
750 | pm_peakhold_right = MAX(pm_max_right, pm_peakhold_right); | ||
751 | #endif | ||
740 | #ifdef PM_DEBUG | 752 | #ifdef PM_DEBUG |
741 | peek_calls = 0; | 753 | peek_calls = 0; |
742 | #endif | 754 | #endif |
@@ -746,6 +758,23 @@ static int peak_meter_read_r(void) | |||
746 | return retval; | 758 | return retval; |
747 | } | 759 | } |
748 | 760 | ||
761 | #ifdef HAVE_AGC | ||
762 | /** | ||
763 | * Reads out the current peak-hold values since the last call. | ||
764 | * This is used by the histogram feature in the recording screen. | ||
765 | * Values are in the range 0 <= peak_x < MAX_PEAK. MAX_PEAK is typ 32767. | ||
766 | */ | ||
767 | extern void peak_meter_get_peakhold(int *peak_left, int *peak_right) | ||
768 | { | ||
769 | if (peak_left) | ||
770 | *peak_left = pm_peakhold_left; | ||
771 | if (peak_right) | ||
772 | *peak_right = pm_peakhold_right; | ||
773 | pm_peakhold_left = 0; | ||
774 | pm_peakhold_right = 0; | ||
775 | } | ||
776 | #endif | ||
777 | |||
749 | /** | 778 | /** |
750 | * Reset the detected clips. This method is for | 779 | * Reset the detected clips. This method is for |
751 | * use by the user interface. | 780 | * use by the user interface. |
diff --git a/apps/recorder/peakmeter.h b/apps/recorder/peakmeter.h index 5456419181..548b95b7da 100644 --- a/apps/recorder/peakmeter.h +++ b/apps/recorder/peakmeter.h | |||
@@ -34,7 +34,9 @@ extern void peak_meter_set_clip_hold(int time); | |||
34 | extern void peak_meter_peek(void); | 34 | extern void peak_meter_peek(void); |
35 | extern void peak_meter_init_range( bool dbfs, int range_min, int range_max); | 35 | extern void peak_meter_init_range( bool dbfs, int range_min, int range_max); |
36 | extern void peak_meter_init_times(int release, int hold, int clip_hold); | 36 | extern void peak_meter_init_times(int release, int hold, int clip_hold); |
37 | 37 | #ifdef HAVE_AGC | |
38 | extern void peak_meter_get_peakhold(int *peak_left, int *peak_right); | ||
39 | #endif | ||
38 | extern void peak_meter_set_min(int newmin); | 40 | extern void peak_meter_set_min(int newmin); |
39 | extern int peak_meter_get_min(void); | 41 | extern int peak_meter_get_min(void); |
40 | extern void peak_meter_set_max(int newmax); | 42 | extern void peak_meter_set_max(int newmax); |
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c index 47d2cce674..0d4f12742f 100644 --- a/apps/recorder/recording.c +++ b/apps/recorder/recording.c | |||
@@ -168,6 +168,63 @@ const char* const freq_str[6] = | |||
168 | "16kHz" | 168 | "16kHz" |
169 | }; | 169 | }; |
170 | 170 | ||
171 | #ifdef HAVE_AGC | ||
172 | /* Timing counters: | ||
173 | * peak_time is incremented every 0.2s, every 2nd run of record screen loop. | ||
174 | * hist_time is incremented every 0.5s, display update. | ||
175 | * peak_time is the counter of the peak hold read and agc process, | ||
176 | * overflow every 13 years 8-) | ||
177 | */ | ||
178 | static long peak_time = 0; | ||
179 | static long hist_time = 0; | ||
180 | |||
181 | static short peak_valid_mem[4]; | ||
182 | #define BAL_MEM_SIZE 24 | ||
183 | static short balance_mem[BAL_MEM_SIZE]; | ||
184 | |||
185 | /* Automatic Gain Control */ | ||
186 | #define AGC_MODE_SIZE 5 | ||
187 | static char* agc_preset_str[] = | ||
188 | { "Off", "S", "L", "D", "M", "V" }; | ||
189 | /* "Off", | ||
190 | "Safety (clip)", | ||
191 | "Live (slow)", | ||
192 | "DJ-Set (slow)", | ||
193 | "Medium", | ||
194 | "Voice (fast)" */ | ||
195 | #define AGC_CLIP 32766 | ||
196 | #define AGC_PEAK 29883 /* fast gain reduction threshold -0.8dB */ | ||
197 | #define AGC_HIGH 27254 /* accelerated gain reduction threshold -1.6dB */ | ||
198 | #define AGC_IMG 823 /* threshold for balance control -32dB */ | ||
199 | /* autogain high level thresholds (-3dB, -7dB, -4dB, -5dB, -5dB) */ | ||
200 | const short agc_th_hi[AGC_MODE_SIZE] = | ||
201 | { 23197, 14637, 21156, 18428, 18426 }; | ||
202 | /* autogain low level thresholds (-14dB, -11dB, -6dB, -7dB, -8dB) */ | ||
203 | const short agc_th_lo[AGC_MODE_SIZE] = | ||
204 | { 6538, 9235, 16422, 14636, 13045 }; | ||
205 | /* autogain threshold times [1/5s] or [200ms] */ | ||
206 | const short agc_tdrop[AGC_MODE_SIZE] = | ||
207 | { 900, 225, 150, 60, 8 }; | ||
208 | const short agc_trise[AGC_MODE_SIZE] = | ||
209 | { 9000, 750, 400, 150, 20 }; | ||
210 | const short agc_tbal[AGC_MODE_SIZE] = | ||
211 | { 4500, 500, 300, 100, 15 }; | ||
212 | /* AGC operation */ | ||
213 | static bool agc_enable = true; | ||
214 | static short agc_preset; | ||
215 | /* AGC levels */ | ||
216 | static int agc_left = 0; | ||
217 | static int agc_right = 0; | ||
218 | /* AGC time since high target volume was exceeded */ | ||
219 | static short agc_droptime = 0; | ||
220 | /* AGC time since volume fallen below low target */ | ||
221 | static short agc_risetime = 0; | ||
222 | /* AGC balance time exceeding +/- 0.7dB */ | ||
223 | static short agc_baltime = 0; | ||
224 | /* AGC maximum gain */ | ||
225 | static short agc_maxgain; | ||
226 | #endif /* HAVE_AGC */ | ||
227 | |||
171 | static void set_gain(void) | 228 | static void set_gain(void) |
172 | { | 229 | { |
173 | if(global_settings.rec_source == SOURCE_MIC) | 230 | if(global_settings.rec_source == SOURCE_MIC) |
@@ -183,6 +240,229 @@ static void set_gain(void) | |||
183 | } | 240 | } |
184 | } | 241 | } |
185 | 242 | ||
243 | #ifdef HAVE_AGC | ||
244 | /* Read peak meter values & calculate balance. | ||
245 | * Returns validity of peak values. | ||
246 | * Used for automatic gain control and history diagram. | ||
247 | */ | ||
248 | bool read_peak_levels(int *peak_l, int *peak_r, int *balance) | ||
249 | { | ||
250 | peak_meter_get_peakhold(peak_l, peak_r); | ||
251 | peak_valid_mem[peak_time % 3] = *peak_l; | ||
252 | if (((peak_valid_mem[0] == peak_valid_mem[1]) && | ||
253 | (peak_valid_mem[1] == peak_valid_mem[2])) && | ||
254 | ((*peak_l < 32767) | ||
255 | #ifndef SIMULATOR | ||
256 | || ata_disk_is_active() | ||
257 | #endif | ||
258 | )) | ||
259 | return false; | ||
260 | |||
261 | if (*peak_r > *peak_l) | ||
262 | balance_mem[peak_time % BAL_MEM_SIZE] = | ||
263 | MIN((10000 * *peak_r) / *peak_l - 10000, 15118); | ||
264 | else | ||
265 | balance_mem[peak_time % BAL_MEM_SIZE] = | ||
266 | MAX(10000 - (10000 * *peak_l) / *peak_r, -15118); | ||
267 | *balance = 0; | ||
268 | int i; | ||
269 | for (i = 0; i < BAL_MEM_SIZE; i++) | ||
270 | *balance += balance_mem[i]; | ||
271 | *balance = *balance / BAL_MEM_SIZE; | ||
272 | |||
273 | return true; | ||
274 | } | ||
275 | |||
276 | /* AGC helper function to check if maximum gain is reached */ | ||
277 | bool agc_gain_is_max(bool left, bool right) | ||
278 | { | ||
279 | /* range -128...+108 [0.5dB] */ | ||
280 | short gain_current_l; | ||
281 | short gain_current_r; | ||
282 | |||
283 | if (agc_preset == 0) | ||
284 | return false; | ||
285 | |||
286 | if (global_settings.rec_source == SOURCE_LINE) | ||
287 | { | ||
288 | gain_current_l = global_settings.rec_left_gain; | ||
289 | gain_current_r = global_settings.rec_right_gain; | ||
290 | } else | ||
291 | { | ||
292 | gain_current_l = global_settings.rec_mic_gain; | ||
293 | gain_current_r = global_settings.rec_mic_gain; | ||
294 | } | ||
295 | |||
296 | return ((left && (gain_current_l >= agc_maxgain)) || | ||
297 | (right && (gain_current_r >= agc_maxgain))); | ||
298 | } | ||
299 | |||
300 | void change_recording_gain(bool increment, bool left, bool right) | ||
301 | { | ||
302 | int factor = (increment ? 1 : -1); | ||
303 | |||
304 | if (global_settings.rec_source == SOURCE_LINE) | ||
305 | { | ||
306 | if(left) global_settings.rec_left_gain += factor; | ||
307 | if (right) global_settings.rec_right_gain += factor; | ||
308 | } | ||
309 | else | ||
310 | { | ||
311 | global_settings.rec_mic_gain += factor; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | /* | ||
316 | * Handle automatic gain control (AGC). | ||
317 | * Change recording gain if peak_x levels are above or below | ||
318 | * target volume for specified timeouts. | ||
319 | */ | ||
320 | void auto_gain_control(int *peak_l, int *peak_r, int *balance) | ||
321 | { | ||
322 | int agc_mono; | ||
323 | short agc_mode; | ||
324 | bool increment; | ||
325 | |||
326 | if (*peak_l > agc_left) | ||
327 | agc_left = *peak_l; | ||
328 | else | ||
329 | agc_left -= (agc_left - *peak_l + 3) >> 2; | ||
330 | if (*peak_r > agc_right) | ||
331 | agc_right = *peak_r; | ||
332 | else | ||
333 | agc_right -= (agc_right - *peak_r + 3) >> 2; | ||
334 | agc_mono = (agc_left + agc_right) / 2; | ||
335 | |||
336 | agc_mode = abs(agc_preset) - 1; | ||
337 | if (agc_mode < 0) { | ||
338 | agc_enable = false; | ||
339 | return; | ||
340 | } | ||
341 | |||
342 | /* Automatic balance control */ | ||
343 | if ((agc_left > AGC_IMG) && (agc_right > AGC_IMG)) | ||
344 | { | ||
345 | if (*balance < -556) | ||
346 | { | ||
347 | if (*balance > -900) | ||
348 | agc_baltime -= !(peak_time % 4); /* 0.47 - 0.75dB */ | ||
349 | else if (*balance > -4125) | ||
350 | agc_baltime--; /* 0.75 - 3.00dB */ | ||
351 | else if (*balance > -7579) | ||
352 | agc_baltime -= 2; /* 3.00 - 4.90dB */ | ||
353 | else | ||
354 | agc_baltime -= !(peak_time % 8); /* 4.90 - inf dB */ | ||
355 | if (agc_baltime > 0) | ||
356 | agc_baltime -= (peak_time % 2); | ||
357 | } | ||
358 | else if (*balance > 556) | ||
359 | { | ||
360 | if (*balance < 900) | ||
361 | agc_baltime += !(peak_time % 4); | ||
362 | else if (*balance < 4125) | ||
363 | agc_baltime++; | ||
364 | else if (*balance < 7579) | ||
365 | agc_baltime += 2; | ||
366 | else | ||
367 | agc_baltime += !(peak_time % 8); | ||
368 | if (agc_baltime < 0) | ||
369 | agc_baltime += (peak_time % 2); | ||
370 | } | ||
371 | |||
372 | if ((*balance * agc_baltime) < 0) | ||
373 | { | ||
374 | if (*balance < 0) | ||
375 | agc_baltime -= peak_time % 2; | ||
376 | else | ||
377 | agc_baltime += peak_time % 2; | ||
378 | } | ||
379 | |||
380 | increment = ((agc_risetime / 2) > agc_droptime); | ||
381 | |||
382 | if (agc_baltime < -agc_tbal[agc_mode]) | ||
383 | { | ||
384 | if (!increment || !agc_gain_is_max(!increment, increment)) { | ||
385 | change_recording_gain(increment, !increment, increment); | ||
386 | set_gain(); | ||
387 | } | ||
388 | agc_baltime = 0; | ||
389 | } | ||
390 | else if (agc_baltime > +agc_tbal[agc_mode]) | ||
391 | { | ||
392 | if (!increment || !agc_gain_is_max(increment, !increment)) { | ||
393 | change_recording_gain(increment, increment, !increment); | ||
394 | set_gain(); | ||
395 | } | ||
396 | agc_baltime = 0; | ||
397 | } | ||
398 | } | ||
399 | else if (!(hist_time % 4)) | ||
400 | { | ||
401 | if (agc_baltime < 0) | ||
402 | agc_baltime++; | ||
403 | else | ||
404 | agc_baltime--; | ||
405 | } | ||
406 | |||
407 | /* Automatic gain control */ | ||
408 | if ((agc_left > agc_th_hi[agc_mode]) || (agc_right > agc_th_hi[agc_mode])) | ||
409 | { | ||
410 | if ((agc_left > AGC_CLIP) || (agc_right > AGC_CLIP)) | ||
411 | agc_droptime += agc_tdrop[agc_mode] / | ||
412 | (global_settings.rec_agc_cliptime + 1); | ||
413 | if (agc_left > AGC_HIGH) { | ||
414 | agc_droptime++; | ||
415 | agc_risetime=0; | ||
416 | if (agc_left > AGC_PEAK) | ||
417 | agc_droptime += 2; | ||
418 | } | ||
419 | if (agc_right > AGC_HIGH) { | ||
420 | agc_droptime++; | ||
421 | agc_risetime=0; | ||
422 | if (agc_right > AGC_PEAK) | ||
423 | agc_droptime += 2; | ||
424 | } | ||
425 | if (agc_mono > agc_th_hi[agc_mode]) | ||
426 | agc_droptime++; | ||
427 | else | ||
428 | agc_droptime += !(peak_time % 2); | ||
429 | |||
430 | if (agc_droptime >= agc_tdrop[agc_mode]) | ||
431 | { | ||
432 | change_recording_gain(false, true, true); | ||
433 | agc_droptime = 0; | ||
434 | agc_risetime = 0; | ||
435 | set_gain(); | ||
436 | } | ||
437 | agc_risetime = MAX(agc_risetime - 1, 0); | ||
438 | } | ||
439 | else if (agc_mono < agc_th_lo[agc_mode]) | ||
440 | { | ||
441 | if (agc_mono < (agc_th_lo[agc_mode] / 8)) | ||
442 | agc_risetime += !(peak_time % 5); | ||
443 | else if (agc_mono < (agc_th_lo[agc_mode] / 2)) | ||
444 | agc_risetime += 2; | ||
445 | else | ||
446 | agc_risetime++; | ||
447 | |||
448 | if (agc_risetime >= agc_trise[agc_mode]) { | ||
449 | if (!agc_gain_is_max(true, true)) { | ||
450 | change_recording_gain(true, true, true); | ||
451 | set_gain(); | ||
452 | } | ||
453 | agc_risetime = 0; | ||
454 | agc_droptime = 0; | ||
455 | } | ||
456 | agc_droptime = MAX(agc_droptime - 1, 0); | ||
457 | } | ||
458 | else if (!(peak_time % 6)) /* on target level every 1.2 sec */ | ||
459 | { | ||
460 | agc_risetime = MAX(agc_risetime - 1, 0); | ||
461 | agc_droptime = MAX(agc_droptime - 1, 0); | ||
462 | } | ||
463 | } | ||
464 | #endif /* HAVE_AGC */ | ||
465 | |||
186 | static const char* const fmtstr[] = | 466 | static const char* const fmtstr[] = |
187 | { | 467 | { |
188 | "%c%d %s", /* no decimals */ | 468 | "%c%d %s", /* no decimals */ |
@@ -226,6 +506,22 @@ void adjust_cursor(void) | |||
226 | if(cursor < 0) | 506 | if(cursor < 0) |
227 | cursor = 0; | 507 | cursor = 0; |
228 | 508 | ||
509 | #ifdef HAVE_AGC | ||
510 | switch(global_settings.rec_source) | ||
511 | { | ||
512 | case SOURCE_MIC: | ||
513 | if(cursor == 2) | ||
514 | cursor = 4; | ||
515 | else if(cursor == 3) | ||
516 | cursor = 1; | ||
517 | case SOURCE_LINE: | ||
518 | max_cursor = 5; | ||
519 | break; | ||
520 | default: | ||
521 | max_cursor = 0; | ||
522 | break; | ||
523 | } | ||
524 | #else | ||
229 | switch(global_settings.rec_source) | 525 | switch(global_settings.rec_source) |
230 | { | 526 | { |
231 | case SOURCE_MIC: | 527 | case SOURCE_MIC: |
@@ -238,6 +534,7 @@ void adjust_cursor(void) | |||
238 | max_cursor = 0; | 534 | max_cursor = 0; |
239 | break; | 535 | break; |
240 | } | 536 | } |
537 | #endif /* HAVE_AGC */ | ||
241 | 538 | ||
242 | if(cursor > max_cursor) | 539 | if(cursor > max_cursor) |
243 | cursor = max_cursor; | 540 | cursor = max_cursor; |
@@ -353,6 +650,14 @@ bool recording_screen(void) | |||
353 | bool led_state = false; | 650 | bool led_state = false; |
354 | int led_countdown = 2; | 651 | int led_countdown = 2; |
355 | #endif | 652 | #endif |
653 | #ifdef HAVE_AGC | ||
654 | bool peak_read = false; | ||
655 | bool peak_valid = false; | ||
656 | int peak_l, peak_r; | ||
657 | int balance = 0; | ||
658 | bool display_agc[NB_SCREENS]; | ||
659 | #endif | ||
660 | int line[NB_SCREENS]; | ||
356 | int i; | 661 | int i; |
357 | int filename_offset[NB_SCREENS]; | 662 | int filename_offset[NB_SCREENS]; |
358 | int pm_y[NB_SCREENS]; | 663 | int pm_y[NB_SCREENS]; |
@@ -392,6 +697,9 @@ bool recording_screen(void) | |||
392 | peak_meter_playback(true); | 697 | peak_meter_playback(true); |
393 | #endif | 698 | #endif |
394 | peak_meter_enabled = true; | 699 | peak_meter_enabled = true; |
700 | #ifdef HAVE_AGC | ||
701 | peak_meter_get_peakhold(&peak_l, &peak_r); | ||
702 | #endif | ||
395 | 703 | ||
396 | #if CONFIG_CODEC != SWCODEC | 704 | #if CONFIG_CODEC != SWCODEC |
397 | if (global_settings.rec_prerecord_time) | 705 | if (global_settings.rec_prerecord_time) |
@@ -414,6 +722,23 @@ bool recording_screen(void) | |||
414 | 722 | ||
415 | settings_apply_trigger(); | 723 | settings_apply_trigger(); |
416 | 724 | ||
725 | #ifdef HAVE_AGC | ||
726 | agc_preset_str[0] = str(LANG_OFF); | ||
727 | agc_preset_str[1] = str(LANG_AGC_SAFETY); | ||
728 | agc_preset_str[2] = str(LANG_AGC_LIVE); | ||
729 | agc_preset_str[3] = str(LANG_AGC_DJSET); | ||
730 | agc_preset_str[4] = str(LANG_AGC_MEDIUM); | ||
731 | agc_preset_str[5] = str(LANG_AGC_VOICE); | ||
732 | if (global_settings.rec_source == SOURCE_MIC) { | ||
733 | agc_preset = global_settings.rec_agc_preset_mic; | ||
734 | agc_maxgain = global_settings.rec_agc_maxgain_mic; | ||
735 | } | ||
736 | else { | ||
737 | agc_preset = global_settings.rec_agc_preset_line; | ||
738 | agc_maxgain = global_settings.rec_agc_maxgain_line; | ||
739 | } | ||
740 | #endif | ||
741 | |||
417 | FOR_NB_SCREENS(i) | 742 | FOR_NB_SCREENS(i) |
418 | { | 743 | { |
419 | screens[i].setfont(FONT_SYSFIXED); | 744 | screens[i].setfont(FONT_SYSFIXED); |
@@ -698,6 +1023,33 @@ bool recording_screen(void) | |||
698 | sound_max(SOUND_RIGHT_GAIN)) | 1023 | sound_max(SOUND_RIGHT_GAIN)) |
699 | global_settings.rec_right_gain++; | 1024 | global_settings.rec_right_gain++; |
700 | break; | 1025 | break; |
1026 | #ifdef HAVE_AGC | ||
1027 | case 4: | ||
1028 | agc_preset = MIN(agc_preset + 1, AGC_MODE_SIZE); | ||
1029 | agc_enable = (agc_preset != 0); | ||
1030 | if (global_settings.rec_source == SOURCE_MIC) { | ||
1031 | global_settings.rec_agc_preset_mic = agc_preset; | ||
1032 | agc_maxgain = global_settings.rec_agc_maxgain_mic; | ||
1033 | } else { | ||
1034 | global_settings.rec_agc_preset_line = agc_preset; | ||
1035 | agc_maxgain = global_settings.rec_agc_maxgain_line; | ||
1036 | } | ||
1037 | break; | ||
1038 | case 5: | ||
1039 | if (global_settings.rec_source == SOURCE_MIC) | ||
1040 | { | ||
1041 | agc_maxgain = MIN(agc_maxgain + 1, | ||
1042 | sound_max(SOUND_MIC_GAIN)); | ||
1043 | global_settings.rec_agc_maxgain_mic = agc_maxgain; | ||
1044 | } | ||
1045 | else | ||
1046 | { | ||
1047 | agc_maxgain = MIN(agc_maxgain + 1, | ||
1048 | sound_max(SOUND_LEFT_GAIN)); | ||
1049 | global_settings.rec_agc_maxgain_line = agc_maxgain; | ||
1050 | } | ||
1051 | break; | ||
1052 | #endif | ||
701 | } | 1053 | } |
702 | set_gain(); | 1054 | set_gain(); |
703 | update_countdown = 1; /* Update immediately */ | 1055 | update_countdown = 1; /* Update immediately */ |
@@ -744,6 +1096,33 @@ bool recording_screen(void) | |||
744 | sound_min(SOUND_RIGHT_GAIN)) | 1096 | sound_min(SOUND_RIGHT_GAIN)) |
745 | global_settings.rec_right_gain--; | 1097 | global_settings.rec_right_gain--; |
746 | break; | 1098 | break; |
1099 | #ifdef HAVE_AGC | ||
1100 | case 4: | ||
1101 | agc_preset = MAX(agc_preset - 1, 0); | ||
1102 | agc_enable = (agc_preset != 0); | ||
1103 | if (global_settings.rec_source == SOURCE_MIC) { | ||
1104 | global_settings.rec_agc_preset_mic = agc_preset; | ||
1105 | agc_maxgain = global_settings.rec_agc_maxgain_mic; | ||
1106 | } else { | ||
1107 | global_settings.rec_agc_preset_line = agc_preset; | ||
1108 | agc_maxgain = global_settings.rec_agc_maxgain_line; | ||
1109 | } | ||
1110 | break; | ||
1111 | case 5: | ||
1112 | if (global_settings.rec_source == SOURCE_MIC) | ||
1113 | { | ||
1114 | agc_maxgain = MAX(agc_maxgain - 1, | ||
1115 | sound_min(SOUND_MIC_GAIN)); | ||
1116 | global_settings.rec_agc_maxgain_mic = agc_maxgain; | ||
1117 | } | ||
1118 | else | ||
1119 | { | ||
1120 | agc_maxgain = MAX(agc_maxgain - 1, | ||
1121 | sound_min(SOUND_LEFT_GAIN)); | ||
1122 | global_settings.rec_agc_maxgain_line = agc_maxgain; | ||
1123 | } | ||
1124 | break; | ||
1125 | #endif | ||
747 | } | 1126 | } |
748 | set_gain(); | 1127 | set_gain(); |
749 | update_countdown = 1; /* Update immediately */ | 1128 | update_countdown = 1; /* Update immediately */ |
@@ -777,6 +1156,16 @@ bool recording_screen(void) | |||
777 | global_settings.rec_channels, | 1156 | global_settings.rec_channels, |
778 | global_settings.rec_editable, | 1157 | global_settings.rec_editable, |
779 | global_settings.rec_prerecord_time); | 1158 | global_settings.rec_prerecord_time); |
1159 | #ifdef HAVE_AGC | ||
1160 | if (global_settings.rec_source == SOURCE_MIC) { | ||
1161 | agc_preset = global_settings.rec_agc_preset_mic; | ||
1162 | agc_maxgain = global_settings.rec_agc_maxgain_mic; | ||
1163 | } | ||
1164 | else { | ||
1165 | agc_preset = global_settings.rec_agc_preset_line; | ||
1166 | agc_maxgain = global_settings.rec_agc_maxgain_line; | ||
1167 | } | ||
1168 | #endif | ||
780 | 1169 | ||
781 | adjust_cursor(); | 1170 | adjust_cursor(); |
782 | set_gain(); | 1171 | set_gain(); |
@@ -854,6 +1243,18 @@ bool recording_screen(void) | |||
854 | if (button != BUTTON_NONE) | 1243 | if (button != BUTTON_NONE) |
855 | lastbutton = button; | 1244 | lastbutton = button; |
856 | 1245 | ||
1246 | #ifdef HAVE_AGC | ||
1247 | peak_read = !peak_read; | ||
1248 | if (peak_read) { /* every 2nd run of loop */ | ||
1249 | peak_time++; | ||
1250 | peak_valid = read_peak_levels(&peak_l, &peak_r, &balance); | ||
1251 | } | ||
1252 | |||
1253 | /* Handle AGC every 200ms when enabled and peak data is valid */ | ||
1254 | if (peak_read && agc_enable && peak_valid) | ||
1255 | auto_gain_control(&peak_l, &peak_r, &balance); | ||
1256 | #endif | ||
1257 | |||
857 | FOR_NB_SCREENS(i) | 1258 | FOR_NB_SCREENS(i) |
858 | screens[i].setfont(FONT_SYSFIXED); | 1259 | screens[i].setfont(FONT_SYSFIXED); |
859 | 1260 | ||
@@ -1041,10 +1442,101 @@ bool recording_screen(void) | |||
1041 | screens[i].puts(0, filename_offset[i] + | 1442 | screens[i].puts(0, filename_offset[i] + |
1042 | PM_HEIGHT + 4, buf); | 1443 | PM_HEIGHT + 4, buf); |
1043 | } | 1444 | } |
1445 | } | ||
1446 | |||
1447 | FOR_NB_SCREENS(i) | ||
1448 | { | ||
1449 | if (global_settings.rec_source == SOURCE_LINE) | ||
1450 | line[i] = 5; | ||
1451 | else if (global_settings.rec_source == SOURCE_MIC) | ||
1452 | line[i] = 4; | ||
1453 | #ifdef HAVE_SPDIF_IN | ||
1454 | else if (global_settings.rec_source == SOURCE_SPDIF) | ||
1455 | line[i] = 3; | ||
1456 | #endif | ||
1457 | #ifdef HAVE_AGC | ||
1458 | if (screens[i].height < h * (2 + filename_offset[i] + PM_HEIGHT + line[i])) | ||
1459 | { | ||
1460 | line[i] -= 1; | ||
1461 | display_agc[i] = false; | ||
1462 | } | ||
1463 | else | ||
1464 | display_agc[i] = true; | ||
1465 | |||
1466 | if ((cursor==4) || (cursor==5)) | ||
1467 | display_agc[i] = true; | ||
1468 | } | ||
1469 | |||
1470 | /************** AGC test info ****************** | ||
1471 | snprintf(buf, 32, "D:%d U:%d", | ||
1472 | (agc_droptime+2)/5, (agc_risetime+2)/5); | ||
1473 | lcd_putsxy(1, LCD_HEIGHT - 8, buf); | ||
1474 | snprintf(buf, 32, "B:%d", | ||
1475 | (agc_baltime+2)/5); | ||
1476 | lcd_putsxy(LCD_WIDTH/2 + 3, LCD_HEIGHT - 8, buf); | ||
1477 | ***********************************************/ | ||
1478 | |||
1479 | if (cursor == 5) | ||
1480 | snprintf(buf, 32, "%s: %s", | ||
1481 | str(LANG_RECORDING_AGC_MAXGAIN), | ||
1482 | fmt_gain(SOUND_LEFT_GAIN, | ||
1483 | agc_maxgain, buf2, sizeof(buf2))); | ||
1484 | else if (agc_preset == 0) | ||
1485 | snprintf(buf, 32, "%s: %s", | ||
1486 | str(LANG_RECORDING_AGC_PRESET), | ||
1487 | agc_preset_str[agc_preset]); | ||
1488 | else if (global_settings.rec_source == SOURCE_MIC) | ||
1489 | snprintf(buf, 32, "%s: %s%s", | ||
1490 | str(LANG_RECORDING_AGC_PRESET), | ||
1491 | agc_preset_str[agc_preset], | ||
1492 | fmt_gain(SOUND_LEFT_GAIN, | ||
1493 | agc_maxgain - | ||
1494 | global_settings.rec_mic_gain, | ||
1495 | buf2, sizeof(buf2))); | ||
1496 | else | ||
1497 | snprintf(buf, 32, "%s: %s%s", | ||
1498 | str(LANG_RECORDING_AGC_PRESET), | ||
1499 | agc_preset_str[agc_preset], | ||
1500 | fmt_gain(SOUND_LEFT_GAIN, | ||
1501 | agc_maxgain - | ||
1502 | (global_settings.rec_left_gain + | ||
1503 | global_settings.rec_right_gain)/2, | ||
1504 | buf2, sizeof(buf2))); | ||
1044 | 1505 | ||
1506 | if(global_settings.invert_cursor && ((cursor==4) || (cursor==5))) | ||
1507 | { | ||
1508 | for(i = 0; i < screen_update; i++) | ||
1509 | screens[i].puts_style_offset(0, filename_offset[i] + | ||
1510 | PM_HEIGHT + line[i], buf, STYLE_INVERT,0); | ||
1045 | } | 1511 | } |
1512 | else if ((global_settings.rec_source == SOURCE_MIC) | ||
1513 | || (global_settings.rec_source == SOURCE_LINE)) | ||
1514 | { | ||
1515 | for(i = 0; i < screen_update; i++) { | ||
1516 | if (display_agc[i]) { | ||
1517 | screens[i].puts(0, filename_offset[i] + | ||
1518 | PM_HEIGHT + line[i], buf); | ||
1519 | } | ||
1520 | } | ||
1521 | } | ||
1522 | |||
1523 | if (global_settings.rec_source == SOURCE_MIC) | ||
1524 | { | ||
1525 | if(agc_maxgain < (global_settings.rec_mic_gain)) | ||
1526 | change_recording_gain(false, true, true); | ||
1527 | } | ||
1528 | else | ||
1529 | { | ||
1530 | if(agc_maxgain < (global_settings.rec_left_gain)) | ||
1531 | change_recording_gain(false, true, false); | ||
1532 | if(agc_maxgain < (global_settings.rec_right_gain)) | ||
1533 | change_recording_gain(false, false, true); | ||
1534 | } | ||
1535 | #else | ||
1536 | } | ||
1537 | #endif /* HAVE_AGC */ | ||
1046 | 1538 | ||
1047 | if(!global_settings.invert_cursor){ | 1539 | if(!global_settings.invert_cursor) { |
1048 | switch(cursor) | 1540 | switch(cursor) |
1049 | { | 1541 | { |
1050 | case 1: | 1542 | case 1: |
@@ -1073,6 +1565,15 @@ bool recording_screen(void) | |||
1073 | filename_offset[i] + | 1565 | filename_offset[i] + |
1074 | PM_HEIGHT + 4, true); | 1566 | PM_HEIGHT + 4, true); |
1075 | break; | 1567 | break; |
1568 | #ifdef HAVE_AGC | ||
1569 | case 4: | ||
1570 | case 5: | ||
1571 | for(i = 0; i < screen_update; i++) | ||
1572 | screen_put_cursorxy(&screens[i], 0, | ||
1573 | filename_offset[i] + | ||
1574 | PM_HEIGHT + line[i], true); | ||
1575 | break; | ||
1576 | #endif /* HAVE_AGC */ | ||
1076 | default: | 1577 | default: |
1077 | for(i = 0; i < screen_update; i++) | 1578 | for(i = 0; i < screen_update; i++) |
1078 | screen_put_cursorxy(&screens[i], 0, | 1579 | screen_put_cursorxy(&screens[i], 0, |
@@ -1096,9 +1597,20 @@ bool recording_screen(void) | |||
1096 | global_settings.rec_channels ? | 1597 | global_settings.rec_channels ? |
1097 | str(LANG_SYSFONT_CHANNEL_MONO) : | 1598 | str(LANG_SYSFONT_CHANNEL_MONO) : |
1098 | str(LANG_SYSFONT_CHANNEL_STEREO)); | 1599 | str(LANG_SYSFONT_CHANNEL_STEREO)); |
1099 | for(i = 0; i < screen_update; i++) | ||
1100 | screens[i].puts(0, filename_offset[i] + PM_HEIGHT + 5, buf); | ||
1101 | 1600 | ||
1601 | for(i = 0; i < screen_update; i++) { | ||
1602 | #ifdef HAVE_AGC | ||
1603 | if ((global_settings.rec_source == SOURCE_MIC) | ||
1604 | || (global_settings.rec_source == SOURCE_LINE)) | ||
1605 | screens[i].puts(0, filename_offset[i] + PM_HEIGHT + line[i] + 1, buf); | ||
1606 | else | ||
1607 | #endif | ||
1608 | screens[i].puts(0, filename_offset[i] + PM_HEIGHT + line[i], buf); | ||
1609 | } | ||
1610 | |||
1611 | #ifdef HAVE_AGC | ||
1612 | hist_time++; | ||
1613 | #endif | ||
1102 | for(i = 0; i < screen_update; i++) | 1614 | for(i = 0; i < screen_update; i++) |
1103 | { | 1615 | { |
1104 | gui_statusbar_draw(&(statusbars.statusbars[i]), true); | 1616 | gui_statusbar_draw(&(statusbars.statusbars[i]), true); |
diff --git a/apps/settings.c b/apps/settings.c index f70e29696b..cd984254d9 100644 --- a/apps/settings.c +++ b/apps/settings.c | |||
@@ -615,7 +615,13 @@ static const struct bit_entry hd_bits[] = | |||
615 | {1, S_O(hold_lr_for_scroll_in_list), true, "hold_lr_for_scroll_in_list", off_on }, | 615 | {1, S_O(hold_lr_for_scroll_in_list), true, "hold_lr_for_scroll_in_list", off_on }, |
616 | 616 | ||
617 | {2, S_O(show_path_in_browser), 0, "show path in browser", "off,current directory,full path" }, | 617 | {2, S_O(show_path_in_browser), 0, "show path in browser", "off,current directory,full path" }, |
618 | 618 | #ifdef HAVE_AGC | |
619 | {4, S_O(rec_agc_preset_mic), 1, "agc mic preset", NULL}, /* 0...5 */ | ||
620 | {4, S_O(rec_agc_preset_line), 1, "agc line preset", NULL}, /* 0...5 */ | ||
621 | {8|SIGNED, S_O(rec_agc_maxgain_mic), 104, "agc maximum mic gain", NULL}, | ||
622 | {8|SIGNED, S_O(rec_agc_maxgain_line), 96, "agc maximum line gain", NULL}, | ||
623 | {3, S_O(rec_agc_cliptime), 1, "agc cliptime", "0.2s,0.4s,0.6s,0.8,1s"}, | ||
624 | #endif | ||
619 | /* If values are just added to the end, no need to bump the version. */ | 625 | /* If values are just added to the end, no need to bump the version. */ |
620 | /* new stuff to be added at the end */ | 626 | /* new stuff to be added at the end */ |
621 | 627 | ||
diff --git a/apps/settings.h b/apps/settings.h index 27f00584a6..d87bc5ee06 100644 --- a/apps/settings.h +++ b/apps/settings.h | |||
@@ -180,6 +180,26 @@ struct user_settings | |||
180 | int rec_stop_gap; /* index of trig_durations */ | 180 | int rec_stop_gap; /* index of trig_durations */ |
181 | int rec_trigger_mode; /* see TRIG_MODE_XXX constants */ | 181 | int rec_trigger_mode; /* see TRIG_MODE_XXX constants */ |
182 | 182 | ||
183 | #ifdef HAVE_AGC | ||
184 | int rec_agc_preset_mic; /* AGC mic preset modes: | ||
185 | 0 = Off | ||
186 | 1 = Safety (clip) | ||
187 | 2 = Live (slow) | ||
188 | 3 = DJ-Set (slow) | ||
189 | 4 = Medium | ||
190 | 5 = Voice (fast) */ | ||
191 | int rec_agc_preset_line; /* AGC line-in preset modes: | ||
192 | 0 = Off | ||
193 | 1 = Safety (clip) | ||
194 | 2 = Live (slow) | ||
195 | 3 = DJ-Set (slow) | ||
196 | 4 = Medium | ||
197 | 5 = Voice (fast) */ | ||
198 | int rec_agc_maxgain_mic; /* AGC maximum mic gain */ | ||
199 | int rec_agc_maxgain_line; /* AGC maximum line-in gain */ | ||
200 | int rec_agc_cliptime; /* 0.2, 0.4, 0.6, 0.8, 1s */ | ||
201 | #endif | ||
202 | |||
183 | /* device settings */ | 203 | /* device settings */ |
184 | 204 | ||
185 | #ifdef HAVE_LCD_CONTRAST | 205 | #ifdef HAVE_LCD_CONTRAST |
diff --git a/apps/sound_menu.c b/apps/sound_menu.c index 280fe52169..34ed9af000 100644 --- a/apps/sound_menu.c +++ b/apps/sound_menu.c | |||
@@ -516,6 +516,41 @@ static bool cliplight(void) | |||
516 | } | 516 | } |
517 | #endif /*CONFIG_BACKLIGHT */ | 517 | #endif /*CONFIG_BACKLIGHT */ |
518 | 518 | ||
519 | #ifdef HAVE_AGC | ||
520 | static bool agc_preset(void) | ||
521 | { | ||
522 | static const struct opt_items names[] = { | ||
523 | { STR(LANG_OFF) }, | ||
524 | { STR(LANG_AGC_SAFETY) }, | ||
525 | { STR(LANG_AGC_LIVE) }, | ||
526 | { STR(LANG_AGC_DJSET) }, | ||
527 | { STR(LANG_AGC_MEDIUM) }, | ||
528 | { STR(LANG_AGC_VOICE) }, | ||
529 | }; | ||
530 | if (global_settings.rec_source) | ||
531 | return set_option(str(LANG_RECORD_AGC_PRESET), | ||
532 | &global_settings.rec_agc_preset_line, | ||
533 | INT, names, 6, NULL ); | ||
534 | else | ||
535 | return set_option(str(LANG_RECORD_AGC_PRESET), | ||
536 | &global_settings.rec_agc_preset_mic, | ||
537 | INT, names, 6, NULL ); | ||
538 | } | ||
539 | |||
540 | static bool agc_cliptime(void) | ||
541 | { | ||
542 | static const struct opt_items names[] = { | ||
543 | { "200ms", TALK_ID(200, UNIT_MS) }, | ||
544 | { "400ms", TALK_ID(400, UNIT_MS) }, | ||
545 | { "600ms", TALK_ID(600, UNIT_MS) }, | ||
546 | { "800ms", TALK_ID(800, UNIT_MS) }, | ||
547 | { "1s", TALK_ID(1, UNIT_SEC) } | ||
548 | }; | ||
549 | return set_option(str(LANG_RECORD_AGC_CLIPTIME), | ||
550 | &global_settings.rec_agc_cliptime, | ||
551 | INT, names, 5, NULL ); | ||
552 | } | ||
553 | #endif /* HAVE_AGC */ | ||
519 | #endif /* HAVE_RECORDING */ | 554 | #endif /* HAVE_RECORDING */ |
520 | 555 | ||
521 | static bool chanconf(void) | 556 | static bool chanconf(void) |
@@ -1015,6 +1050,12 @@ bool recording_menu(bool no_source) | |||
1015 | items[i].desc = ID2P(LANG_RECORD_TRIGGER); | 1050 | items[i].desc = ID2P(LANG_RECORD_TRIGGER); |
1016 | items[i++].function = rectrigger; | 1051 | items[i++].function = rectrigger; |
1017 | #endif | 1052 | #endif |
1053 | #ifdef HAVE_AGC | ||
1054 | items[i].desc = ID2P(LANG_RECORD_AGC_PRESET); | ||
1055 | items[i++].function = agc_preset; | ||
1056 | items[i].desc = ID2P(LANG_RECORD_AGC_CLIPTIME); | ||
1057 | items[i++].function = agc_cliptime; | ||
1058 | #endif | ||
1018 | 1059 | ||
1019 | m=menu_init( items, i, NULL, NULL, NULL, NULL); | 1060 | m=menu_init( items, i, NULL, NULL, NULL, NULL); |
1020 | result = menu_run(m); | 1061 | result = menu_run(m); |
diff --git a/firmware/export/config-h100.h b/firmware/export/config-h100.h index 52f7625760..c21c8a1dcd 100644 --- a/firmware/export/config-h100.h +++ b/firmware/export/config-h100.h | |||
@@ -74,6 +74,8 @@ | |||
74 | /* define this if you have recording possibility */ | 74 | /* define this if you have recording possibility */ |
75 | #define HAVE_RECORDING 1 | 75 | #define HAVE_RECORDING 1 |
76 | 76 | ||
77 | #define HAVE_AGC | ||
78 | |||
77 | #ifndef SIMULATOR | 79 | #ifndef SIMULATOR |
78 | 80 | ||
79 | /* Define this if you have a Motorola SCF5249 */ | 81 | /* Define this if you have a Motorola SCF5249 */ |
diff --git a/firmware/export/config-h120.h b/firmware/export/config-h120.h index 69fd565c23..5ff567cae4 100644 --- a/firmware/export/config-h120.h +++ b/firmware/export/config-h120.h | |||
@@ -68,6 +68,8 @@ | |||
68 | /* define this if you have recording possibility */ | 68 | /* define this if you have recording possibility */ |
69 | #define HAVE_RECORDING 1 | 69 | #define HAVE_RECORDING 1 |
70 | 70 | ||
71 | #define HAVE_AGC | ||
72 | |||
71 | #define BATTERY_CAPACITY_DEFAULT 1300 /* default battery capacity */ | 73 | #define BATTERY_CAPACITY_DEFAULT 1300 /* default battery capacity */ |
72 | 74 | ||
73 | #ifndef SIMULATOR | 75 | #ifndef SIMULATOR |
diff --git a/firmware/export/config-h300.h b/firmware/export/config-h300.h index a310a4eef3..d5c54d858f 100644 --- a/firmware/export/config-h300.h +++ b/firmware/export/config-h300.h | |||
@@ -68,6 +68,8 @@ | |||
68 | /* define this if you have recording possibility */ | 68 | /* define this if you have recording possibility */ |
69 | #define HAVE_RECORDING 1 | 69 | #define HAVE_RECORDING 1 |
70 | 70 | ||
71 | #define HAVE_AGC | ||
72 | |||
71 | #define BATTERY_CAPACITY_DEFAULT 1300 /* default battery capacity */ | 73 | #define BATTERY_CAPACITY_DEFAULT 1300 /* default battery capacity */ |
72 | 74 | ||
73 | #ifndef SIMULATOR | 75 | #ifndef SIMULATOR |