summaryrefslogtreecommitdiff
path: root/firmware/pcm_record.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/pcm_record.c')
-rw-r--r--firmware/pcm_record.c61
1 files changed, 31 insertions, 30 deletions
diff --git a/firmware/pcm_record.c b/firmware/pcm_record.c
index a72641baa6..93a6e067b1 100644
--- a/firmware/pcm_record.c
+++ b/firmware/pcm_record.c
@@ -244,6 +244,14 @@ static int pcm_rec_have_more(int status)
return 0;
} /* pcm_rec_have_more */
+static void reset_hardware(void)
+{
+ /* reset pcm to defaults (playback only) */
+ pcm_set_frequency(HW_SAMPR_DEFAULT);
+ audio_set_output_source(AUDIO_SRC_PLAYBACK);
+ pcm_apply_settings(true);
+}
+
/** pcm_rec_* group **/
void pcm_rec_error_clear(void)
{
@@ -328,10 +336,7 @@ void audio_close_recording(void)
{
pcm_thread_wait_for_stop();
pcm_thread_sync_post(PCMREC_CLOSE, NULL);
- /* reset pcm to defaults (playback only) */
- pcm_set_frequency(HW_SAMPR_DEFAULT);
- audio_set_output_source(AUDIO_SRC_PLAYBACK);
- pcm_apply_settings(true);
+ reset_hardware();
audio_remove_encoder();
} /* audio_close_recording */
@@ -460,10 +465,6 @@ void audio_stop_recording(void)
logf("audio_stop_recording");
pcm_thread_wait_for_stop();
-
- if (is_recording)
- dma_lock = true; /* fix DMA write ptr at current position */
-
pcm_thread_sync_post(PCMREC_STOP, NULL);
logf("audio_stop_recording done");
@@ -474,11 +475,8 @@ void audio_pause_recording(void)
logf("audio_pause_recording");
pcm_thread_wait_for_stop();
-
- if (is_recording)
- dma_lock = true; /* fix DMA write ptr at current position */
-
pcm_thread_sync_post(PCMREC_PAUSE, NULL);
+
logf("audio_pause_recording done");
} /* audio_pause_recording */
@@ -1006,6 +1004,8 @@ static void pcmrec_new_stream(const char *filename, /* next file name */
/* PCMREC_INIT */
static void pcmrec_init(void)
{
+ unsigned char *buffer;
+
rec_fdata.rec_file = -1;
/* pcm FIFO */
@@ -1035,11 +1035,13 @@ static void pcmrec_init(void)
is_stopping = false;
is_error = false;
- pcm_buffer = audio_get_recording_buffer(&rec_buffer_size);
+ buffer = audio_get_recording_buffer(&rec_buffer_size);
/* Line align pcm_buffer 2^4=16 bytes */
- pcm_buffer = (unsigned char *)ALIGN_UP_P2((unsigned)pcm_buffer, 4);
+ pcm_buffer = (unsigned char *)ALIGN_UP_P2((unsigned long)buffer, 4);
enc_buffer = pcm_buffer + ALIGN_UP_P2(PCM_NUM_CHUNKS*PCM_CHUNK_SIZE +
PCM_MAX_FEED_SIZE, 2);
+ /* Adjust available buffer for possible align advancement */
+ rec_buffer_size -= pcm_buffer - buffer;
pcm_init_recording();
pcm_thread_signal_event(PCMREC_INIT);
@@ -1132,8 +1134,8 @@ static void pcmrec_start(const char *filename)
pcmrec_fnq_set_empty();
}
- dma_lock = false;
- is_paused = false;
+ dma_lock = false;
+ is_paused = false;
is_recording = true;
pcmrec_new_stream(filename,
@@ -1187,11 +1189,8 @@ static void pcmrec_finish_stop(void)
pcmrec_flush(-1);
/* wait for encoder to finish remaining data */
- if (!is_error)
- {
- while (!wav_queue_empty)
- yield();
- }
+ while (!is_error && !wav_queue_empty)
+ yield();
/* end stream at last data */
pcmrec_new_stream(NULL, CHUNKF_END_FILE, 0);
@@ -1307,7 +1306,7 @@ static void pcmrec_thread(void)
while(1)
{
- if (is_recording)
+ if (is_recording && !is_stopping)
{
/* Poll periodically to flush data */
queue_wait_w_tmo(&pcmrec_queue, &ev, HZ/5);
@@ -1363,12 +1362,12 @@ static void pcmrec_thread(void)
break;
case SYS_USB_CONNECTED:
- if (!is_recording)
- {
- pcmrec_close();
- usb_acknowledge(SYS_USB_CONNECTED_ACK);
- usb_wait_for_disconnect(&pcmrec_queue);
- }
+ if (is_recording)
+ break;
+ pcmrec_close();
+ reset_hardware();
+ usb_acknowledge(SYS_USB_CONNECTED_ACK);
+ usb_wait_for_disconnect(&pcmrec_queue);
break;
} /* end switch */
} /* end while */
@@ -1554,7 +1553,8 @@ void enc_finish_chunk(void)
int enc_pcm_buf_near_empty(void)
{
/* less than 1sec raw data? => unboost encoder */
- size_t avail = (dma_wr_pos - pcm_rd_pos) & PCM_CHUNK_MASK;
+ int wp = dma_wr_pos;
+ size_t avail = (wp - pcm_rd_pos) & PCM_CHUNK_MASK;
return avail < (sample_rate << 2) ? 1 : 0;
} /* enc_pcm_buf_near_empty */
@@ -1562,7 +1562,8 @@ int enc_pcm_buf_near_empty(void)
/* TODO: this really should give the actual size returned */
unsigned char * enc_get_pcm_data(size_t size)
{
- size_t avail = (dma_wr_pos - pcm_rd_pos) & PCM_CHUNK_MASK;
+ int wp = dma_wr_pos;
+ size_t avail = (wp - pcm_rd_pos) & PCM_CHUNK_MASK;
/* limit the requested pcm data size */
if (size > PCM_MAX_FEED_SIZE)