summaryrefslogtreecommitdiff
path: root/apps/recorder/recording.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/recorder/recording.c')
-rw-r--r--apps/recorder/recording.c250
1 files changed, 140 insertions, 110 deletions
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c
index 0a21d96566..6a053cd12e 100644
--- a/apps/recorder/recording.c
+++ b/apps/recorder/recording.c
@@ -30,8 +30,10 @@
#include "mpeg.h"
#include "audio.h"
#if CONFIG_CODEC == SWCODEC
-#include "pcm_record.h"
+#include "thread.h"
+#include "pcm_playback.h"
#include "playback.h"
+#include "enc_config.h"
#endif
#ifdef HAVE_UDA1380
#include "uda1380.h"
@@ -73,36 +75,40 @@
#define PM_HEIGHT ((LCD_HEIGHT >= 72) ? 2 : 1)
+#if CONFIG_KEYPAD == RECORDER_PAD
bool f2_rec_screen(void);
bool f3_rec_screen(void);
+#endif
#define MAX_FILE_SIZE 0x7F800000 /* 2 GB - 4 MB */
int screen_update = NB_SCREENS;
bool remote_display_on = true;
-const char* const freq_str[6] =
-{
- "44.1kHz",
- "48kHz",
- "32kHz",
- "22.05kHz",
- "24kHz",
- "16kHz"
-};
+/** File name creation **/
#if CONFIG_CODEC == SWCODEC
-#define REC_ENCODER_ID(q) \
- rec_quality_info_afmt[q]
-#define REC_QUALITY_LABEL(q) \
- (audio_formats[REC_ENCODER_ID(q)].label)
-#define REC_FILE_ENDING(q) \
- (audio_formats[REC_ENCODER_ID(q)].ext)
-#else
+
+#ifdef IF_CNFN_NUM
+/* current file number to assist in creating unique numbered filenames
+ without actually having to create the file on disk */
+static int file_number = -1;
+#endif /* IF_CNFN_NUM */
+
+#define REC_FILE_ENDING(rec_format) \
+ (audio_formats[rec_format_afmt[rec_format]].ext_list)
+
+#else /* CONFIG_CODEC != SWCODEC */
+
/* default record file extension for HWCODEC */
-#define REC_QUALITY_LABEL(q) "MP3"
-#define REC_FILE_ENDING(q) ".mp3"
-#endif
+#define REC_FILE_ENDING(rec_format) \
+ (audio_formats[AFMT_MPA_L3].ext_list)
+#endif /* CONFIG_CODEC == SWCODEC */
+
+/* path for current file */
+static char path_buffer[MAX_PATH];
+
+/** Automatic Gain Control (AGC) **/
#ifdef HAVE_AGC
/* Timing counters:
* peak_time is incremented every 0.2s, every 2nd run of record screen loop.
@@ -496,20 +502,24 @@ void adjust_cursor(void)
char *rec_create_filename(char *buffer)
{
+ char ext[16];
+
if(global_settings.rec_directory)
getcwd(buffer, MAX_PATH);
else
strncpy(buffer, rec_base_directory, MAX_PATH);
+ snprintf(ext, sizeof(ext), ".%s",
+ REC_FILE_ENDING(global_settings.rec_format));
#ifdef CONFIG_RTC
- create_datetime_filename(buffer, buffer, "R",
- REC_FILE_ENDING(global_settings.rec_quality));
+ /* We'll wait at least up to the start of the next second so no duplicate
+ names are created */
+ return create_datetime_filename(buffer, buffer, "R", ext, true);
#else
- create_numbered_filename(buffer, buffer, "rec_",
- REC_FILE_ENDING(global_settings.rec_quality), 4);
+ return create_numbered_filename(buffer, buffer, "rec_", ext, 4
+ IF_CNFN_NUM_(, &file_number));
#endif
- return buffer;
}
int rec_create_directory(void)
@@ -557,9 +567,15 @@ static void rec_boost(bool state)
/**
* Selects an audio source for recording or playback
- * powers/unpowers related devices.
+ * powers/unpowers related devices and sets up monitoring.
* Here because it calls app code and used only for HAVE_RECORDING atm.
* Would like it in pcm_record.c.
+ *
+ * Behaves like a firmware function in that it does not use global settings
+ * to determine the state.
+ *
+ * The order of setting monitoring may need tweaking dependent upon the
+ * selected source to get the smoothest transition.
*/
#if defined(HAVE_UDA1380)
#define ac_disable_recording uda1380_disable_recording
@@ -571,7 +587,13 @@ static void rec_boost(bool state)
#define ac_set_monitor tlv320_set_monitor
#endif
-void rec_set_source(int source, int flags)
+#ifdef HAVE_SPDIF_IN
+#define rec_spdif_set_monitor(m) audio_spdif_set_monitor(m)
+#else
+#define rec_spdif_set_monitor(m)
+#endif
+
+void rec_set_source(int source, unsigned flags)
{
/* Prevent pops from unneeded switching */
static int last_source = AUDIO_SRC_PLAYBACK;
@@ -586,7 +608,9 @@ void rec_set_source(int source, int flags)
/** Do power up/down of associated device(s) **/
+ /** SPDIF **/
#ifdef HAVE_SPDIF_IN
+ /* Always boost for SPDIF */
if ((source == AUDIO_SRC_SPDIF) != (source == last_source))
rec_boost(source == AUDIO_SRC_SPDIF);
@@ -595,10 +619,11 @@ void rec_set_source(int source, int flags)
both optical in and out is controlled by the same power source, which is
the case on H1x0. */
spdif_power_enable((source == AUDIO_SRC_SPDIF) ||
- global_settings.spdif_enable);
+ audio_get_spdif_power_setting());
#endif
#endif
+ /** Tuner **/
#ifdef CONFIG_TUNER
/* Switch radio off or on per source and flags. */
if (source != AUDIO_SRC_FMRADIO)
@@ -612,12 +637,15 @@ void rec_set_source(int source, int flags)
switch (source)
{
default: /* playback - no recording */
+ source = AUDIO_SRC_PLAYBACK;
+ case AUDIO_SRC_PLAYBACK:
pm_playback = true;
if (source == last_source)
break;
ac_disable_recording();
ac_set_monitor(false);
pcm_rec_mux(0); /* line in */
+ rec_spdif_set_monitor(-1); /* silence it */
break;
case AUDIO_SRC_MIC: /* recording only */
@@ -625,6 +653,7 @@ void rec_set_source(int source, int flags)
break;
ac_enable_recording(true); /* source mic */
pcm_rec_mux(0); /* line in */
+ rec_spdif_set_monitor(0);
break;
case AUDIO_SRC_LINEIN: /* recording only */
@@ -632,29 +661,20 @@ void rec_set_source(int source, int flags)
break;
pcm_rec_mux(0); /* line in */
ac_enable_recording(false); /* source line */
+ rec_spdif_set_monitor(0);
break;
#ifdef HAVE_SPDIF_IN
case AUDIO_SRC_SPDIF: /* recording only */
- if (recording)
- {
- /* This was originally done in audio_set_recording_options only */
-#ifdef HAVE_SPDIF_POWER
- EBU1CONFIG = global_settings.spdif_enable ? (1 << 2) : 0;
- /* Input source is EBUin1, Feed-through monitoring if desired */
-#else
- EBU1CONFIG = (1 << 2);
- /* Input source is EBUin1, Feed-through monitoring */
-#endif
- }
-
- if (source != last_source)
- uda1380_disable_recording();
+ if (source == last_source)
+ break;
+ ac_disable_recording();
+ audio_spdif_set_monitor(1);
break;
#endif /* HAVE_SPDIF_IN */
#ifdef HAVE_FMRADIO_IN
- case AUDIO_SRC_FMRADIO:
+ case AUDIO_SRC_FMRADIO: /* recording and playback */
if (!recording)
{
audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
@@ -687,6 +707,8 @@ void rec_set_source(int source, int flags)
tlv320_set_monitor(true); /* analog bypass */
}
#endif
+
+ rec_spdif_set_monitor(0);
break;
/* #elif defined(CONFIG_TUNER) */
/* Have radio but cannot record it */
@@ -702,33 +724,50 @@ void rec_set_source(int source, int flags)
} /* rec_set_source */
#endif /* CONFIG_CODEC == SWCODEC && !defined(SIMULATOR) */
-/* steal the mp3 buffer then actually set options */
-void rec_set_recording_options(int frequency, int quality,
- int source, int source_flags,
- int channel_mode, bool editable,
- int prerecord_time)
+void rec_init_recording_options(struct audio_recording_options *options)
+{
+ options->rec_source = global_settings.rec_source;
+ options->rec_frequency = global_settings.rec_frequency;
+ options->rec_channels = global_settings.rec_channels;
+ options->rec_prerecord_time = global_settings.rec_prerecord_time;
+#if CONFIG_CODEC == SWCODEC
+ options->rec_source_flags = 0;
+ options->enc_config.rec_format = global_settings.rec_format;
+ global_to_encoder_config(&options->enc_config);
+#else
+ options->rec_quality = global_settings.rec_quality;
+ options->rec_editable = global_settings.rec_editable;
+#endif
+}
+
+void rec_set_recording_options(struct audio_recording_options *options)
{
#if CONFIG_CODEC != SWCODEC
if (global_settings.rec_prerecord_time)
-#endif
talk_buffer_steal(); /* will use the mp3 buffer */
+#endif
+
+#ifdef HAVE_SPDIF_IN
+#ifdef HAVE_SPDIF_POWER
+ audio_set_spdif_power_setting(global_settings.spdif_enable);
+#endif
+#endif
#if CONFIG_CODEC == SWCODEC
- rec_set_source(source, source_flags | SRCF_RECORDING);
-#else
- (void)source_flags;
+ rec_set_source(options->rec_source,
+ options->rec_source_flags | SRCF_RECORDING);
#endif
- audio_set_recording_options(frequency, quality, source,
- channel_mode, editable, prerecord_time);
+ audio_set_recording_options(options);
}
-static char path_buffer[MAX_PATH];
-
/* steals mp3 buffer, creates unique filename and starts recording */
void rec_record(void)
{
+#if CONFIG_CODEC != SWCODEC
talk_buffer_steal(); /* we use the mp3 buffer */
+#endif
+ IF_CNFN_NUM_(file_number = -1;) /* Hit disk for number */
audio_record(rec_create_filename(path_buffer));
}
@@ -753,7 +792,6 @@ static void trigger_listener(int trigger_status)
case TRIG_GO:
if((audio_status() & AUDIO_STATUS_RECORD) != AUDIO_STATUS_RECORD)
{
- talk_buffer_steal(); /* we use the mp3 buffer */
rec_record();
/* give control to mpeg thread so that it can start
recording */
@@ -831,6 +869,8 @@ bool recording_screen(bool no_source)
ID2P(LANG_GIGABYTE)
};
+ struct audio_recording_options rec_options;
+
global_settings.recscreen_on = true;
cursor = 0;
#if (CONFIG_LED == LED_REAL) && !defined(SIMULATOR)
@@ -838,35 +878,26 @@ bool recording_screen(bool no_source)
#endif
#if CONFIG_CODEC == SWCODEC
- audio_stop();
- voice_stop();
/* recording_menu gets messed up: so reset talk_menu */
talk_menu = global_settings.talk_menu;
global_settings.talk_menu = 0;
+ /* audio_init_recording stops anything playing when it takes the audio
+ buffer */
#else
/* Yes, we use the D/A for monitoring */
peak_meter_enabled = true;
peak_meter_playback(true);
#endif
-#if CONFIG_CODEC == SWCODEC
- audio_init_recording(talk_get_bufsize());
-#else
audio_init_recording(0);
-#endif
sound_set_volume(global_settings.volume);
#ifdef HAVE_AGC
peak_meter_get_peakhold(&peak_l, &peak_r);
#endif
- rec_set_recording_options(global_settings.rec_frequency,
- global_settings.rec_quality,
- global_settings.rec_source,
- 0,
- global_settings.rec_channels,
- global_settings.rec_editable,
- global_settings.rec_prerecord_time);
+ rec_init_recording_options(&rec_options);
+ rec_set_recording_options(&rec_options);
set_gain();
settings_apply_trigger();
@@ -1025,7 +1056,6 @@ bool recording_screen(bool no_source)
{
/* manual recording */
have_recorded = true;
- talk_buffer_steal(); /* we use the mp3 buffer */
rec_record();
last_seconds = 0;
if (talk_menu)
@@ -1253,16 +1283,10 @@ bool recording_screen(bool no_source)
#if CONFIG_CODEC == SWCODEC
/* reinit after submenu exit */
audio_close_recording();
- audio_init_recording(talk_get_bufsize());
+ audio_init_recording(0);
#endif
- rec_set_recording_options(
- global_settings.rec_frequency,
- global_settings.rec_quality,
- global_settings.rec_source,
- 0,
- global_settings.rec_channels,
- global_settings.rec_editable,
- global_settings.rec_prerecord_time);
+ rec_init_recording_options(&rec_options);
+ rec_set_recording_options(&rec_options);
if(rec_create_directory() > 0)
have_recorded = true;
@@ -1739,11 +1763,7 @@ bool recording_screen(bool no_source)
}
} /* end while(!done) */
-#if CONFIG_CODEC == SWCODEC
- audio_stat = pcm_rec_status();
-#else
audio_stat = audio_status();
-#endif
if (audio_stat & AUDIO_STATUS_ERROR)
{
gui_syncsplash(0, true, str(LANG_SYSFONT_DISK_FULL));
@@ -1804,11 +1824,22 @@ bool recording_screen(bool no_source)
#if CONFIG_KEYPAD == RECORDER_PAD
bool f2_rec_screen(void)
{
+ static const char* const freq_str[6] =
+ {
+ "44.1kHz",
+ "48kHz",
+ "32kHz",
+ "22.05kHz",
+ "24kHz",
+ "16kHz"
+ };
+
bool exit = false;
bool used = false;
int w, h, i;
char buf[32];
int button;
+ struct audio_recording_options rec_options;
FOR_NB_SCREENS(i)
{
@@ -1919,13 +1950,8 @@ bool f2_rec_screen(void)
}
}
- rec_set_recording_options(global_settings.rec_frequency,
- global_settings.rec_quality,
- global_settings.rec_source,
- 0,
- global_settings.rec_channels,
- global_settings.rec_editable,
- global_settings.rec_prerecord_time);
+ rec_init_recording_options(&rec_options);
+ rec_set_recording_options(&rec_options);
set_gain();
@@ -1948,6 +1974,8 @@ bool f3_rec_screen(void)
str(LANG_SYSFONT_RECORDING_SRC_LINE),
str(LANG_SYSFONT_RECORDING_SRC_DIGITAL)
};
+ struct audio_recording_options rec_options;
+
FOR_NB_SCREENS(i)
{
screens[i].setfont(FONT_SYSFIXED);
@@ -2019,13 +2047,8 @@ bool f3_rec_screen(void)
}
}
- rec_set_recording_options(global_settings.rec_frequency,
- global_settings.rec_quality,
- global_settings.rec_source,
- 0,
- global_settings.rec_channels,
- global_settings.rec_editable,
- global_settings.rec_prerecord_time);
+ rec_init_recording_options(&rec_options);
+ rec_set_recording_options(&rec_options);
set_gain();
@@ -2066,23 +2089,30 @@ unsigned long audio_num_recorded_bytes(void)
}
#if CONFIG_CODEC == SWCODEC
-void rec_set_source(int source, int flags)
+void rec_set_source(int source, unsigned flags)
{
source = source;
flags = flags;
}
-#endif
-void audio_set_recording_options(int frequency, int quality,
- int source, int channel_mode,
- bool editable, int prerecord_time)
+#ifdef HAVE_SPDIF_IN
+#ifdef HAVE_SPDIF_POWER
+void audio_set_spdif_power_setting(bool on)
{
- frequency = frequency;
- quality = quality;
- source = source;
- channel_mode = channel_mode;
- editable = editable;
- prerecord_time = prerecord_time;
+ on = on;
+}
+
+bool audio_get_spdif_power_setting(void)
+{
+ return true;
+}
+#endif /* HAVE_SPDIF_POWER */
+#endif /* HAVE_SPDIF_IN */
+#endif /* CONFIG_CODEC == SWCODEC */
+
+void audio_set_recording_options(struct audio_recording_options *options)
+{
+ options = options;
}
void audio_set_recording_gain(int left, int right, int type)
@@ -2104,7 +2134,7 @@ void audio_resume_recording(void)
{
}
-void pcm_rec_get_peaks(int *left, int *right)
+void pcm_calculate_rec_peaks(int *left, int *right)
{
if (left)
*left = 0;