summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2006-12-07 19:34:26 +0000
committerMichael Sevakis <jethead71@rockbox.org>2006-12-07 19:34:26 +0000
commit0d768a37f970b40575ef2be169e670fd6b5d424a (patch)
tree2dbc6fe2211a3a2b1fe3aa0693196b8790b3ec78 /firmware
parent5652b2528d59b77e804f72d4f7c9854275e05b5a (diff)
downloadrockbox-0d768a37f970b40575ef2be169e670fd6b5d424a.tar.gz
rockbox-0d768a37f970b40575ef2be169e670fd6b5d424a.zip
SWCODEC Recording: 1) Fix minor bug of not subtracting line aligment adjustment from buffer size. 2) Handle stop and pause better and let pcmrec thread lock the DMA as that could cause prerecording to get disabled internally 3) Make sure to snapshot DMA write index to ensure compiler doesn't perform multiple access when calculating available data (probably just paranoia on my part) 4) Handle USB connect in recording thread a little better by resetting hardware to defaults after closing 5) Make power managment stop recording properly when powering off (ie. no yield() from interrupt handler! :)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11685 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/pcm_record.c61
-rw-r--r--firmware/powermgmt.c19
2 files changed, 41 insertions, 39 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)
244 return 0; 244 return 0;
245} /* pcm_rec_have_more */ 245} /* pcm_rec_have_more */
246 246
247static void reset_hardware(void)
248{
249 /* reset pcm to defaults (playback only) */
250 pcm_set_frequency(HW_SAMPR_DEFAULT);
251 audio_set_output_source(AUDIO_SRC_PLAYBACK);
252 pcm_apply_settings(true);
253}
254
247/** pcm_rec_* group **/ 255/** pcm_rec_* group **/
248void pcm_rec_error_clear(void) 256void pcm_rec_error_clear(void)
249{ 257{
@@ -328,10 +336,7 @@ void audio_close_recording(void)
328{ 336{
329 pcm_thread_wait_for_stop(); 337 pcm_thread_wait_for_stop();
330 pcm_thread_sync_post(PCMREC_CLOSE, NULL); 338 pcm_thread_sync_post(PCMREC_CLOSE, NULL);
331 /* reset pcm to defaults (playback only) */ 339 reset_hardware();
332 pcm_set_frequency(HW_SAMPR_DEFAULT);
333 audio_set_output_source(AUDIO_SRC_PLAYBACK);
334 pcm_apply_settings(true);
335 audio_remove_encoder(); 340 audio_remove_encoder();
336} /* audio_close_recording */ 341} /* audio_close_recording */
337 342
@@ -460,10 +465,6 @@ void audio_stop_recording(void)
460 logf("audio_stop_recording"); 465 logf("audio_stop_recording");
461 466
462 pcm_thread_wait_for_stop(); 467 pcm_thread_wait_for_stop();
463
464 if (is_recording)
465 dma_lock = true; /* fix DMA write ptr at current position */
466
467 pcm_thread_sync_post(PCMREC_STOP, NULL); 468 pcm_thread_sync_post(PCMREC_STOP, NULL);
468 469
469 logf("audio_stop_recording done"); 470 logf("audio_stop_recording done");
@@ -474,11 +475,8 @@ void audio_pause_recording(void)
474 logf("audio_pause_recording"); 475 logf("audio_pause_recording");
475 476
476 pcm_thread_wait_for_stop(); 477 pcm_thread_wait_for_stop();
477
478 if (is_recording)
479 dma_lock = true; /* fix DMA write ptr at current position */
480
481 pcm_thread_sync_post(PCMREC_PAUSE, NULL); 478 pcm_thread_sync_post(PCMREC_PAUSE, NULL);
479
482 logf("audio_pause_recording done"); 480 logf("audio_pause_recording done");
483} /* audio_pause_recording */ 481} /* audio_pause_recording */
484 482
@@ -1006,6 +1004,8 @@ static void pcmrec_new_stream(const char *filename, /* next file name */
1006/* PCMREC_INIT */ 1004/* PCMREC_INIT */
1007static void pcmrec_init(void) 1005static void pcmrec_init(void)
1008{ 1006{
1007 unsigned char *buffer;
1008
1009 rec_fdata.rec_file = -1; 1009 rec_fdata.rec_file = -1;
1010 1010
1011 /* pcm FIFO */ 1011 /* pcm FIFO */
@@ -1035,11 +1035,13 @@ static void pcmrec_init(void)
1035 is_stopping = false; 1035 is_stopping = false;
1036 is_error = false; 1036 is_error = false;
1037 1037
1038 pcm_buffer = audio_get_recording_buffer(&rec_buffer_size); 1038 buffer = audio_get_recording_buffer(&rec_buffer_size);
1039 /* Line align pcm_buffer 2^4=16 bytes */ 1039 /* Line align pcm_buffer 2^4=16 bytes */
1040 pcm_buffer = (unsigned char *)ALIGN_UP_P2((unsigned)pcm_buffer, 4); 1040 pcm_buffer = (unsigned char *)ALIGN_UP_P2((unsigned long)buffer, 4);
1041 enc_buffer = pcm_buffer + ALIGN_UP_P2(PCM_NUM_CHUNKS*PCM_CHUNK_SIZE + 1041 enc_buffer = pcm_buffer + ALIGN_UP_P2(PCM_NUM_CHUNKS*PCM_CHUNK_SIZE +
1042 PCM_MAX_FEED_SIZE, 2); 1042 PCM_MAX_FEED_SIZE, 2);
1043 /* Adjust available buffer for possible align advancement */
1044 rec_buffer_size -= pcm_buffer - buffer;
1043 1045
1044 pcm_init_recording(); 1046 pcm_init_recording();
1045 pcm_thread_signal_event(PCMREC_INIT); 1047 pcm_thread_signal_event(PCMREC_INIT);
@@ -1132,8 +1134,8 @@ static void pcmrec_start(const char *filename)
1132 pcmrec_fnq_set_empty(); 1134 pcmrec_fnq_set_empty();
1133 } 1135 }
1134 1136
1135 dma_lock = false; 1137 dma_lock = false;
1136 is_paused = false; 1138 is_paused = false;
1137 is_recording = true; 1139 is_recording = true;
1138 1140
1139 pcmrec_new_stream(filename, 1141 pcmrec_new_stream(filename,
@@ -1187,11 +1189,8 @@ static void pcmrec_finish_stop(void)
1187 pcmrec_flush(-1); 1189 pcmrec_flush(-1);
1188 1190
1189 /* wait for encoder to finish remaining data */ 1191 /* wait for encoder to finish remaining data */
1190 if (!is_error) 1192 while (!is_error && !wav_queue_empty)
1191 { 1193 yield();
1192 while (!wav_queue_empty)
1193 yield();
1194 }
1195 1194
1196 /* end stream at last data */ 1195 /* end stream at last data */
1197 pcmrec_new_stream(NULL, CHUNKF_END_FILE, 0); 1196 pcmrec_new_stream(NULL, CHUNKF_END_FILE, 0);
@@ -1307,7 +1306,7 @@ static void pcmrec_thread(void)
1307 1306
1308 while(1) 1307 while(1)
1309 { 1308 {
1310 if (is_recording) 1309 if (is_recording && !is_stopping)
1311 { 1310 {
1312 /* Poll periodically to flush data */ 1311 /* Poll periodically to flush data */
1313 queue_wait_w_tmo(&pcmrec_queue, &ev, HZ/5); 1312 queue_wait_w_tmo(&pcmrec_queue, &ev, HZ/5);
@@ -1363,12 +1362,12 @@ static void pcmrec_thread(void)
1363 break; 1362 break;
1364 1363
1365 case SYS_USB_CONNECTED: 1364 case SYS_USB_CONNECTED:
1366 if (!is_recording) 1365 if (is_recording)
1367 { 1366 break;
1368 pcmrec_close(); 1367 pcmrec_close();
1369 usb_acknowledge(SYS_USB_CONNECTED_ACK); 1368 reset_hardware();
1370 usb_wait_for_disconnect(&pcmrec_queue); 1369 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1371 } 1370 usb_wait_for_disconnect(&pcmrec_queue);
1372 break; 1371 break;
1373 } /* end switch */ 1372 } /* end switch */
1374 } /* end while */ 1373 } /* end while */
@@ -1554,7 +1553,8 @@ void enc_finish_chunk(void)
1554int enc_pcm_buf_near_empty(void) 1553int enc_pcm_buf_near_empty(void)
1555{ 1554{
1556 /* less than 1sec raw data? => unboost encoder */ 1555 /* less than 1sec raw data? => unboost encoder */
1557 size_t avail = (dma_wr_pos - pcm_rd_pos) & PCM_CHUNK_MASK; 1556 int wp = dma_wr_pos;
1557 size_t avail = (wp - pcm_rd_pos) & PCM_CHUNK_MASK;
1558 return avail < (sample_rate << 2) ? 1 : 0; 1558 return avail < (sample_rate << 2) ? 1 : 0;
1559} /* enc_pcm_buf_near_empty */ 1559} /* enc_pcm_buf_near_empty */
1560 1560
@@ -1562,7 +1562,8 @@ int enc_pcm_buf_near_empty(void)
1562/* TODO: this really should give the actual size returned */ 1562/* TODO: this really should give the actual size returned */
1563unsigned char * enc_get_pcm_data(size_t size) 1563unsigned char * enc_get_pcm_data(size_t size)
1564{ 1564{
1565 size_t avail = (dma_wr_pos - pcm_rd_pos) & PCM_CHUNK_MASK; 1565 int wp = dma_wr_pos;
1566 size_t avail = (wp - pcm_rd_pos) & PCM_CHUNK_MASK;
1566 1567
1567 /* limit the requested pcm data size */ 1568 /* limit the requested pcm data size */
1568 if (size > PCM_MAX_FEED_SIZE) 1569 if (size > PCM_MAX_FEED_SIZE)
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index e59e2d50b9..458745f0d9 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -1266,16 +1266,17 @@ void sys_poweroff(void)
1266{ 1266{
1267 logf("sys_poweroff()"); 1267 logf("sys_poweroff()");
1268 /* If the main thread fails to shut down the system, we will force a 1268 /* If the main thread fails to shut down the system, we will force a
1269 power off after an 20 second timeout */ 1269 power off after an 20 second timeout - 28 seconds if recording */
1270 shutdown_timeout = HZ*20; 1270#if defined(IAUDIO_X5) && !defined (SIMULATOR)
1271#if defined(HAVE_RECORDING) 1271 if (shutdown_timeout == 0)
1272 int audio_stat = audio_status(); 1272 pcf50606_reset_timeout(); /* Reset timer on first attempt only */
1273 if (audio_stat & AUDIO_STATUS_RECORD) {
1274 audio_stop_recording();
1275 shutdown_timeout += 8*HZ;
1276 }
1277#endif 1273#endif
1278 1274#ifdef HAVE_RECORDING
1275 if (audio_status() & AUDIO_STATUS_RECORD)
1276 shutdown_timeout += HZ*8;
1277#endif
1278
1279 shutdown_timeout = HZ*20;
1279 queue_post(&button_queue, SYS_POWEROFF, NULL); 1280 queue_post(&button_queue, SYS_POWEROFF, NULL);
1280} 1281}
1281 1282