diff options
Diffstat (limited to 'apps/sound_menu.c')
-rw-r--r-- | apps/sound_menu.c | 288 |
1 files changed, 210 insertions, 78 deletions
diff --git a/apps/sound_menu.c b/apps/sound_menu.c index c10ba9417e..fb766d604c 100644 --- a/apps/sound_menu.c +++ b/apps/sound_menu.c | |||
@@ -54,6 +54,10 @@ | |||
54 | #include "dsp.h" | 54 | #include "dsp.h" |
55 | #include "eq_menu.h" | 55 | #include "eq_menu.h" |
56 | #include "pcmbuf.h" | 56 | #include "pcmbuf.h" |
57 | #ifdef HAVE_RECORDING | ||
58 | #include "enc_config.h" | ||
59 | #endif | ||
60 | #include "general.h" | ||
57 | #endif | 61 | #endif |
58 | #include "action.h" | 62 | #include "action.h" |
59 | 63 | ||
@@ -308,22 +312,20 @@ static bool recsource(void) | |||
308 | { | 312 | { |
309 | int n_opts = AUDIO_NUM_SOURCES; | 313 | int n_opts = AUDIO_NUM_SOURCES; |
310 | 314 | ||
311 | struct opt_items names[AUDIO_NUM_SOURCES] = { | 315 | static const struct opt_items names[AUDIO_NUM_SOURCES] = { |
312 | { STR(LANG_RECORDING_SRC_MIC) }, | 316 | [AUDIO_SRC_MIC] = { STR(LANG_RECORDING_SRC_MIC) }, |
313 | { STR(LANG_RECORDING_SRC_LINE) }, | 317 | [AUDIO_SRC_LINEIN] = { STR(LANG_RECORDING_SRC_LINE) }, |
314 | #ifdef HAVE_SPDIF_IN | 318 | #ifdef HAVE_SPDIF_IN |
315 | { STR(LANG_RECORDING_SRC_DIGITAL) }, | 319 | [AUDIO_SRC_SPDIF] = { STR(LANG_RECORDING_SRC_DIGITAL) }, |
320 | #endif | ||
321 | #ifdef HAVE_FMRADIO_IN | ||
322 | [AUDIO_SRC_FMRADIO] = { STR(LANG_FM_RADIO) } | ||
316 | #endif | 323 | #endif |
317 | }; | 324 | }; |
318 | 325 | ||
319 | /* caveat: assumes it's the last item! */ | 326 | /* caveat: assumes it's the last item! */ |
320 | #ifdef HAVE_FMRADIO_IN | 327 | #ifdef HAVE_FMRADIO_IN |
321 | if (radio_hardware_present()) | 328 | if (!radio_hardware_present()) |
322 | { | ||
323 | names[AUDIO_SRC_FMRADIO].string = ID2P(LANG_FM_RADIO); | ||
324 | names[AUDIO_SRC_FMRADIO].voice_id = LANG_FM_RADIO; | ||
325 | } | ||
326 | else | ||
327 | n_opts--; | 329 | n_opts--; |
328 | #endif | 330 | #endif |
329 | 331 | ||
@@ -332,28 +334,7 @@ static bool recsource(void) | |||
332 | n_opts, NULL ); | 334 | n_opts, NULL ); |
333 | } | 335 | } |
334 | 336 | ||
335 | /* To be removed when we add support for sample rates and channel settings */ | 337 | #if CONFIG_CODEC == MAS3587F |
336 | #if CONFIG_CODEC == SWCODEC | ||
337 | static bool recquality(void) | ||
338 | { | ||
339 | static const struct opt_items names[] = { | ||
340 | { "MP3 64 kBit/s", TALK_ID( 64, UNIT_KBIT) }, | ||
341 | { "MP3 96 kBit/s", TALK_ID( 96, UNIT_KBIT) }, | ||
342 | { "MP3 128 kBit/s", TALK_ID( 128, UNIT_KBIT) }, | ||
343 | { "MP3 160 kBit/s", TALK_ID( 160, UNIT_KBIT) }, | ||
344 | { "MP3 192 kBit/s", TALK_ID( 192, UNIT_KBIT) }, | ||
345 | { "MP3 224 kBit/s", TALK_ID( 224, UNIT_KBIT) }, | ||
346 | { "MP3 320 kBit/s", TALK_ID( 320, UNIT_KBIT) }, | ||
347 | { "WV 900 kBit/s", TALK_ID( 900, UNIT_KBIT) }, | ||
348 | { "WAV 1411 kBit/s", TALK_ID(1411, UNIT_KBIT) } | ||
349 | }; | ||
350 | |||
351 | return set_option(str(LANG_RECORDING_QUALITY), | ||
352 | &global_settings.rec_quality, INT, | ||
353 | names, sizeof (names)/sizeof(struct opt_items), | ||
354 | NULL ); | ||
355 | } | ||
356 | #elif CONFIG_CODEC == MAS3587F | ||
357 | static bool recquality(void) | 338 | static bool recquality(void) |
358 | { | 339 | { |
359 | return set_int(str(LANG_RECORDING_QUALITY), "", UNIT_INT, | 340 | return set_int(str(LANG_RECORDING_QUALITY), "", UNIT_INT, |
@@ -368,32 +349,182 @@ static bool receditable(void) | |||
368 | } | 349 | } |
369 | #endif /* CONFIG_CODEC == MAS3587F */ | 350 | #endif /* CONFIG_CODEC == MAS3587F */ |
370 | 351 | ||
352 | #if CONFIG_CODEC == SWCODEC | ||
353 | /* Makes an options list from a source list of options and indexes */ | ||
354 | void make_options_from_indexes(const struct opt_items *src_names, | ||
355 | const long *src_indexes, | ||
356 | int n_indexes, | ||
357 | struct opt_items *dst_names) | ||
358 | { | ||
359 | while (--n_indexes >= 0) | ||
360 | dst_names[n_indexes] = src_names[src_indexes[n_indexes]]; | ||
361 | } /* make_options_from_indexes */ | ||
362 | |||
363 | static bool recformat(void) | ||
364 | { | ||
365 | static const struct opt_items names[REC_NUM_FORMATS] = { | ||
366 | [REC_FORMAT_MPA_L3] = { STR(LANG_AFMT_MPA_L3) }, | ||
367 | [REC_FORMAT_WAVPACK] = { STR(LANG_AFMT_WAVPACK) }, | ||
368 | [REC_FORMAT_PCM_WAV] = { STR(LANG_AFMT_PCM_WAV) }, | ||
369 | }; | ||
370 | |||
371 | int rec_format = global_settings.rec_format; | ||
372 | bool res = set_option(str(LANG_RECORDING_FORMAT), &rec_format, INT, | ||
373 | names, REC_NUM_FORMATS, NULL ); | ||
374 | |||
375 | if (rec_format != global_settings.rec_format) | ||
376 | { | ||
377 | global_settings.rec_format = rec_format; | ||
378 | enc_global_settings_apply(); | ||
379 | } | ||
380 | |||
381 | return res; | ||
382 | } /* recformat */ | ||
383 | |||
384 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
385 | |||
371 | static bool recfrequency(void) | 386 | static bool recfrequency(void) |
372 | { | 387 | { |
373 | static const struct opt_items names[] = { | 388 | #if CONFIG_CODEC == MAS3587F |
389 | static const struct opt_items names[6] = { | ||
374 | { "44.1kHz", TALK_ID(44, UNIT_KHZ) }, | 390 | { "44.1kHz", TALK_ID(44, UNIT_KHZ) }, |
375 | #if CONFIG_CODEC != SWCODEC /* This is temporary */ | ||
376 | { "48kHz", TALK_ID(48, UNIT_KHZ) }, | 391 | { "48kHz", TALK_ID(48, UNIT_KHZ) }, |
377 | { "32kHz", TALK_ID(32, UNIT_KHZ) }, | 392 | { "32kHz", TALK_ID(32, UNIT_KHZ) }, |
378 | { "22.05kHz", TALK_ID(22, UNIT_KHZ) }, | 393 | { "22.05kHz", TALK_ID(22, UNIT_KHZ) }, |
379 | { "24kHz", TALK_ID(24, UNIT_KHZ) }, | 394 | { "24kHz", TALK_ID(24, UNIT_KHZ) }, |
380 | { "16kHz", TALK_ID(16, UNIT_KHZ) } | 395 | { "16kHz", TALK_ID(16, UNIT_KHZ) } |
381 | #endif | ||
382 | }; | 396 | }; |
383 | return set_option(str(LANG_RECORDING_FREQUENCY), | 397 | return set_option(str(LANG_RECORDING_FREQUENCY), |
384 | &global_settings.rec_frequency, INT, | 398 | &global_settings.rec_frequency, INT, |
385 | names, sizeof(names)/sizeof(*names), NULL ); | 399 | names, 6, NULL ); |
400 | #endif /* CONFIG_CODEC == MAS3587F */ | ||
401 | |||
402 | #if CONFIG_CODEC == SWCODEC | ||
403 | static const struct opt_items names[REC_NUM_FREQ] = { | ||
404 | REC_HAVE_96_([REC_FREQ_96] = { "96kHz", TALK_ID(96, UNIT_KHZ) },) | ||
405 | REC_HAVE_88_([REC_FREQ_88] = { "88.2kHz", TALK_ID(88, UNIT_KHZ) },) | ||
406 | REC_HAVE_64_([REC_FREQ_64] = { "64kHz", TALK_ID(64, UNIT_KHZ) },) | ||
407 | REC_HAVE_48_([REC_FREQ_48] = { "48kHz", TALK_ID(48, UNIT_KHZ) },) | ||
408 | REC_HAVE_44_([REC_FREQ_44] = { "44.1kHz", TALK_ID(44, UNIT_KHZ) },) | ||
409 | REC_HAVE_32_([REC_FREQ_32] = { "32kHz", TALK_ID(32, UNIT_KHZ) },) | ||
410 | REC_HAVE_24_([REC_FREQ_24] = { "24kHz", TALK_ID(24, UNIT_KHZ) },) | ||
411 | REC_HAVE_22_([REC_FREQ_22] = { "22.05kHz", TALK_ID(22, UNIT_KHZ) },) | ||
412 | REC_HAVE_16_([REC_FREQ_16] = { "16kHz", TALK_ID(16, UNIT_KHZ) },) | ||
413 | REC_HAVE_12_([REC_FREQ_12] = { "12kHz", TALK_ID(12, UNIT_KHZ) },) | ||
414 | REC_HAVE_11_([REC_FREQ_11] = { "11.025kHz", TALK_ID(11, UNIT_KHZ) },) | ||
415 | REC_HAVE_8_( [REC_FREQ_8 ] = { "8kHz", TALK_ID( 8, UNIT_KHZ) },) | ||
416 | }; | ||
417 | |||
418 | struct opt_items opts[REC_NUM_FREQ]; | ||
419 | unsigned long table[REC_NUM_FREQ]; | ||
420 | int n_opts; | ||
421 | int rec_frequency; | ||
422 | bool ret; | ||
423 | |||
424 | #ifdef HAVE_SPDIF_IN | ||
425 | if (global_settings.rec_source == AUDIO_SRC_SPDIF) | ||
426 | { | ||
427 | /* Inform user that frequency follows the source's frequency */ | ||
428 | opts[0].string = ID2P(LANG_SOURCE_FREQUENCY); | ||
429 | opts[0].voice_id = LANG_SOURCE_FREQUENCY; | ||
430 | n_opts = 1; | ||
431 | rec_frequency = 0; | ||
386 | } | 432 | } |
433 | else | ||
434 | #endif | ||
435 | { | ||
436 | struct encoder_caps caps; | ||
437 | struct encoder_config cfg; | ||
438 | |||
439 | cfg.rec_format = global_settings.rec_format; | ||
440 | global_to_encoder_config(&cfg); | ||
441 | |||
442 | if (!enc_get_caps(&cfg, &caps, true)) | ||
443 | return false; | ||
444 | |||
445 | /* Construct samplerate menu based upon encoder settings */ | ||
446 | n_opts = make_list_from_caps32(REC_SAMPR_CAPS, NULL, | ||
447 | caps.samplerate_caps, table); | ||
448 | |||
449 | if (n_opts == 0) | ||
450 | return false; /* No common flags...?? */ | ||
451 | |||
452 | make_options_from_indexes(names, table, n_opts, opts); | ||
453 | |||
454 | /* Find closest rate that the potentially restricted list | ||
455 | comes to */ | ||
456 | make_list_from_caps32(REC_SAMPR_CAPS, rec_freq_sampr, | ||
457 | caps.samplerate_caps, table); | ||
458 | |||
459 | rec_frequency = round_value_to_list32( | ||
460 | rec_freq_sampr[global_settings.rec_frequency], | ||
461 | table, n_opts, false); | ||
462 | } | ||
463 | |||
464 | ret = set_option(str(LANG_RECORDING_FREQUENCY), | ||
465 | &rec_frequency, INT, opts, n_opts, NULL ); | ||
466 | |||
467 | if (!ret | ||
468 | #ifdef HAVE_SPDIF_IN | ||
469 | && global_settings.rec_source != AUDIO_SRC_SPDIF | ||
470 | #endif | ||
471 | ) | ||
472 | { | ||
473 | /* Translate back to full index */ | ||
474 | global_settings.rec_frequency = | ||
475 | round_value_to_list32(table[rec_frequency], | ||
476 | rec_freq_sampr, | ||
477 | REC_NUM_FREQ, | ||
478 | false); | ||
479 | } | ||
480 | |||
481 | return ret; | ||
482 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
483 | } /* recfrequency */ | ||
387 | 484 | ||
388 | static bool recchannels(void) | 485 | static bool recchannels(void) |
389 | { | 486 | { |
390 | static const struct opt_items names[] = { | 487 | static const struct opt_items names[CHN_NUM_MODES] = { |
391 | { STR(LANG_CHANNEL_STEREO) }, | 488 | [CHN_MODE_STEREO] = { STR(LANG_CHANNEL_STEREO) }, |
392 | { STR(LANG_CHANNEL_MONO) } | 489 | [CHN_MODE_MONO] = { STR(LANG_CHANNEL_MONO) } |
393 | }; | 490 | }; |
491 | #if CONFIG_CODEC == MAS3587F | ||
394 | return set_option(str(LANG_RECORDING_CHANNELS), | 492 | return set_option(str(LANG_RECORDING_CHANNELS), |
395 | &global_settings.rec_channels, INT, | 493 | &global_settings.rec_channels, INT, |
396 | names, 2, NULL ); | 494 | names, CHN_NUM_MODES, NULL ); |
495 | #endif /* CONFIG_CODEC == MAS3587F */ | ||
496 | |||
497 | #if CONFIG_CODEC == SWCODEC | ||
498 | struct opt_items opts[CHN_NUM_MODES]; | ||
499 | long table[CHN_NUM_MODES]; | ||
500 | struct encoder_caps caps; | ||
501 | struct encoder_config cfg; | ||
502 | int n_opts; | ||
503 | int rec_channels; | ||
504 | bool ret; | ||
505 | |||
506 | cfg.rec_format = global_settings.rec_format; | ||
507 | global_to_encoder_config(&cfg); | ||
508 | |||
509 | if (!enc_get_caps(&cfg, &caps, true)) | ||
510 | return false; | ||
511 | |||
512 | n_opts = make_list_from_caps32(CHN_CAP_ALL, NULL, | ||
513 | caps.channel_caps, table); | ||
514 | |||
515 | rec_channels = round_value_to_list32(global_settings.rec_channels, | ||
516 | table, n_opts, false); | ||
517 | |||
518 | make_options_from_indexes(names, table, n_opts, opts); | ||
519 | |||
520 | ret = set_option(str(LANG_RECORDING_CHANNELS), &rec_channels, | ||
521 | INT, opts, n_opts, NULL ); | ||
522 | |||
523 | if (!ret) | ||
524 | global_settings.rec_channels = table[rec_channels]; | ||
525 | |||
526 | return ret; | ||
527 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
397 | } | 528 | } |
398 | 529 | ||
399 | static bool rectimesplit(void) | 530 | static bool rectimesplit(void) |
@@ -1049,58 +1180,59 @@ bool rectrigger(void) | |||
1049 | action_signalscreenchange(); | 1180 | action_signalscreenchange(); |
1050 | return retval; | 1181 | return retval; |
1051 | } | 1182 | } |
1052 | #endif | 1183 | #endif /* !defined(SIMULATOR) && CONFIG_CODEC == MAS3587F */ |
1053 | 1184 | ||
1054 | bool recording_menu(bool no_source) | 1185 | bool recording_menu(bool no_source) |
1055 | { | 1186 | { |
1056 | int m; | 1187 | static const struct menu_item static_items[] = { |
1057 | int i = 0; | 1188 | #if CONFIG_CODEC == MAS3587F |
1058 | struct menu_item items[13]; | 1189 | { ID2P(LANG_RECORDING_QUALITY), recquality }, |
1059 | bool result; | ||
1060 | |||
1061 | #if CONFIG_CODEC == MAS3587F || CONFIG_CODEC == SWCODEC | ||
1062 | items[i].desc = ID2P(LANG_RECORDING_QUALITY); | ||
1063 | items[i++].function = recquality; | ||
1064 | #endif | 1190 | #endif |
1065 | items[i].desc = ID2P(LANG_RECORDING_FREQUENCY); | 1191 | #if CONFIG_CODEC == SWCODEC |
1066 | items[i++].function = recfrequency; | 1192 | { ID2P(LANG_RECORDING_FORMAT), recformat }, |
1067 | if(!no_source) { | 1193 | { ID2P(LANG_ENCODER_SETTINGS), enc_global_config_menu }, |
1068 | items[i].desc = ID2P(LANG_RECORDING_SOURCE); | 1194 | #endif |
1069 | items[i++].function = recsource; | 1195 | { ID2P(LANG_RECORDING_FREQUENCY), recfrequency }, |
1070 | } | 1196 | { ID2P(LANG_RECORDING_SOURCE), recsource }, /* not shown if no_source */ |
1071 | items[i].desc = ID2P(LANG_RECORDING_CHANNELS); | 1197 | { ID2P(LANG_RECORDING_CHANNELS), recchannels }, |
1072 | items[i++].function = recchannels; | ||
1073 | #if CONFIG_CODEC == MAS3587F | 1198 | #if CONFIG_CODEC == MAS3587F |
1074 | items[i].desc = ID2P(LANG_RECORDING_EDITABLE); | 1199 | { ID2P(LANG_RECORDING_EDITABLE), receditable }, |
1075 | items[i++].function = receditable; | ||
1076 | #endif | 1200 | #endif |
1077 | items[i].desc = ID2P(LANG_RECORD_TIMESPLIT); | 1201 | { ID2P(LANG_RECORD_TIMESPLIT), filesplitoptionsmenu }, |
1078 | items[i++].function = filesplitoptionsmenu; | 1202 | { ID2P(LANG_RECORD_PRERECORD_TIME), recprerecord }, |
1079 | items[i].desc = ID2P(LANG_RECORD_PRERECORD_TIME); | 1203 | { ID2P(LANG_RECORD_DIRECTORY), recdirectory }, |
1080 | items[i++].function = recprerecord; | 1204 | { ID2P(LANG_RECORD_STARTUP), reconstartup }, |
1081 | items[i].desc = ID2P(LANG_RECORD_DIRECTORY); | ||
1082 | items[i++].function = recdirectory; | ||
1083 | items[i].desc = ID2P(LANG_RECORD_STARTUP); | ||
1084 | items[i++].function = reconstartup; | ||
1085 | #ifdef CONFIG_BACKLIGHT | 1205 | #ifdef CONFIG_BACKLIGHT |
1086 | items[i].desc = ID2P(LANG_CLIP_LIGHT); | 1206 | { ID2P(LANG_CLIP_LIGHT), cliplight }, |
1087 | items[i++].function = cliplight; | ||
1088 | #endif | 1207 | #endif |
1089 | #if !defined(SIMULATOR) && CONFIG_CODEC == MAS3587F | 1208 | #if !defined(SIMULATOR) && CONFIG_CODEC == MAS3587F |
1090 | items[i].desc = ID2P(LANG_RECORD_TRIGGER); | 1209 | { ID2P(LANG_RECORD_TRIGGER), rectrigger }, |
1091 | items[i++].function = rectrigger; | ||
1092 | #endif | 1210 | #endif |
1093 | #ifdef HAVE_AGC | 1211 | #ifdef HAVE_AGC |
1094 | items[i].desc = ID2P(LANG_RECORD_AGC_PRESET); | 1212 | { ID2P(LANG_RECORD_AGC_PRESET), agc_preset }, |
1095 | items[i++].function = agc_preset; | 1213 | { ID2P(LANG_RECORD_AGC_CLIPTIME), agc_cliptime }, |
1096 | items[i].desc = ID2P(LANG_RECORD_AGC_CLIPTIME); | ||
1097 | items[i++].function = agc_cliptime; | ||
1098 | #endif | 1214 | #endif |
1215 | }; | ||
1099 | 1216 | ||
1100 | m=menu_init( items, i, NULL, NULL, NULL, NULL); | 1217 | struct menu_item items[ARRAYLEN(static_items)]; |
1218 | int i, n_items; | ||
1219 | int m; | ||
1220 | |||
1221 | bool result; | ||
1222 | |||
1223 | for (i = 0, n_items = 0; i < (int)ARRAYLEN(items); i++) | ||
1224 | { | ||
1225 | const struct menu_item *mi = &static_items[i]; | ||
1226 | if (no_source && mi->function == recsource) | ||
1227 | continue; | ||
1228 | items[n_items++] = *mi; | ||
1229 | } | ||
1230 | |||
1231 | m = menu_init(items, n_items, NULL, NULL, NULL, NULL); | ||
1101 | result = menu_run(m); | 1232 | result = menu_run(m); |
1102 | menu_exit(m); | 1233 | menu_exit(m); |
1103 | 1234 | ||
1104 | return result; | 1235 | return result; |
1105 | } | 1236 | } /* recording_menu */ |
1106 | #endif | 1237 | |
1238 | #endif /* HAVE_RECORDING */ | ||