summaryrefslogtreecommitdiff
path: root/apps/recorder/pcm_record.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2013-05-31 02:41:02 -0400
committerMichael Sevakis <jethead71@rockbox.org>2013-05-31 03:20:35 -0400
commit5857c44017a1641fce7f00da7f16c143daacbaf6 (patch)
treeb8a7ff134977ee8dd6b25b5591f4eb81172f74ab /apps/recorder/pcm_record.c
parentdf6e1bcce5071e02b5cd46736bff87ca0dcceffe (diff)
downloadrockbox-5857c44017a1641fce7f00da7f16c143daacbaf6.tar.gz
rockbox-5857c44017a1641fce7f00da7f16c143daacbaf6.zip
Refactor audio thread to run both recording and playback.
Eliminates the pcmrec thread and keeps playback and recording engine operation mutually-exclusive. audio_thread.c contains the audio thread which branches to the correct engine depending upon the request. It also handles the main audio initialization. Moves pcm_init into main.c just before dsp_init because I don't want that one in audio_init in the new file. (Also makes revision df6e1bc pointless ;) Change-Id: Ifc1db24404e6d8dd9ac42d9f4dfbc207aa9a26e1
Diffstat (limited to 'apps/recorder/pcm_record.c')
-rw-r--r--apps/recorder/pcm_record.c305
1 files changed, 135 insertions, 170 deletions
diff --git a/apps/recorder/pcm_record.c b/apps/recorder/pcm_record.c
index fe7a54a565..a45dcc2d11 100644
--- a/apps/recorder/pcm_record.c
+++ b/apps/recorder/pcm_record.c
@@ -38,11 +38,13 @@
38#ifdef HAVE_SPDIF_IN 38#ifdef HAVE_SPDIF_IN
39#include "spdif.h" 39#include "spdif.h"
40#endif 40#endif
41#include "audio_thread.h"
41 42
42/***************************************************************************/ 43/***************************************************************************/
43 44
45extern struct event_queue audio_queue;
46
44/** General recording state **/ 47/** General recording state **/
45static bool is_initialized = false; /* Subsystem ready? */
46static bool is_recording; /* We are recording */ 48static bool is_recording; /* We are recording */
47static bool is_paused; /* We have paused */ 49static bool is_paused; /* We have paused */
48static unsigned long errors; /* An error has occured */ 50static unsigned long errors; /* An error has occured */
@@ -230,14 +232,6 @@ enum
230 232
231/***************************************************************************/ 233/***************************************************************************/
232 234
233static struct event_queue pcmrec_queue SHAREDBSS_ATTR;
234static struct queue_sender_list pcmrec_queue_send SHAREDBSS_ATTR;
235static long pcmrec_stack[3*DEFAULT_STACK_SIZE/sizeof(long)];
236static const char pcmrec_thread_name[] = "pcmrec";
237static unsigned int pcmrec_thread_id = 0;
238
239static void pcmrec_thread(void);
240
241enum 235enum
242{ 236{
243 PCMREC_NULL = 0, 237 PCMREC_NULL = 0,
@@ -248,14 +242,23 @@ enum
248 PCMREC_STOP, /* stop the current recording */ 242 PCMREC_STOP, /* stop the current recording */
249 PCMREC_PAUSE, /* pause the current recording */ 243 PCMREC_PAUSE, /* pause the current recording */
250 PCMREC_RESUME, /* resume the current recording */ 244 PCMREC_RESUME, /* resume the current recording */
251#if 0
252 PCMREC_FLUSH_NUM, /* flush a number of files out */
253#endif
254}; 245};
255 246
256/*******************************************************************/ 247/*******************************************************************/
257/* Functions that are not executing in the pcmrec_thread first */ 248/* Functions that are not executing in the audio thread first */
258/*******************************************************************/ 249/*******************************************************************/
250
251static void pcmrec_raise_error_status(unsigned long e)
252{
253 pcm_rec_lock(); /* DMA sets this too */
254 errors |= e;
255 pcm_rec_unlock();
256}
257
258static void pcmrec_raise_warning_status(unsigned long w)
259{
260 warnings |= w;
261}
259 262
260/* Callback for when more data is ready - called in interrupt context */ 263/* Callback for when more data is ready - called in interrupt context */
261static void pcm_rec_have_more(void **start, size_t *size) 264static void pcm_rec_have_more(void **start, size_t *size)
@@ -268,7 +271,7 @@ static void pcm_rec_have_more(void **start, size_t *size)
268 /* set pcm ovf if processing start position is inside current 271 /* set pcm ovf if processing start position is inside current
269 write chunk */ 272 write chunk */
270 if ((unsigned)(pcm_enc_pos - next_pos) < PCM_CHUNK_SIZE) 273 if ((unsigned)(pcm_enc_pos - next_pos) < PCM_CHUNK_SIZE)
271 warnings |= PCMREC_W_PCM_BUFFER_OVF; 274 pcmrec_raise_warning_status(PCMREC_W_PCM_BUFFER_OVF);
272 275
273 dma_wr_pos = next_pos; 276 dma_wr_pos = next_pos;
274 } 277 }
@@ -285,7 +288,7 @@ static enum pcm_dma_status pcm_rec_status_callback(enum pcm_dma_status status)
285 if (status == PCM_DMAST_ERR_DMA) 288 if (status == PCM_DMAST_ERR_DMA)
286 { 289 {
287 /* Flush recorded data to disk and stop recording */ 290 /* Flush recorded data to disk and stop recording */
288 queue_post(&pcmrec_queue, PCMREC_STOP, 0); 291 errors |= PCMREC_E_DMA;
289 return status; 292 return status;
290 } 293 }
291 /* else try again next transmission - frame is invalid */ 294 /* else try again next transmission - frame is invalid */
@@ -315,9 +318,9 @@ void pcm_rec_error_clear(void)
315/** 318/**
316 * Check mode, errors and warnings 319 * Check mode, errors and warnings
317 */ 320 */
318unsigned long pcm_rec_status(void) 321unsigned int pcm_rec_status(void)
319{ 322{
320 unsigned long ret = 0; 323 unsigned int ret = 0;
321 324
322 if (is_recording) 325 if (is_recording)
323 ret |= AUDIO_STATUS_RECORD; 326 ret |= AUDIO_STATUS_RECORD;
@@ -379,20 +382,6 @@ unsigned long pcm_rec_sample_rate(void)
379} /* audio_get_sample_rate */ 382} /* audio_get_sample_rate */
380#endif 383#endif
381 384
382/**
383 * Creates pcmrec_thread
384 */
385void pcm_rec_init(void)
386{
387 queue_init(&pcmrec_queue, true);
388 pcmrec_thread_id =
389 create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack),
390 0, pcmrec_thread_name IF_PRIO(, PRIORITY_RECORDING)
391 IF_COP(, CPU));
392 queue_enable_queue_send(&pcmrec_queue, &pcmrec_queue_send,
393 pcmrec_thread_id);
394} /* pcm_rec_init */
395
396/** audio_* group **/ 385/** audio_* group **/
397 386
398/** 387/**
@@ -401,7 +390,7 @@ void pcm_rec_init(void)
401void audio_init_recording(void) 390void audio_init_recording(void)
402{ 391{
403 logf("audio_init_recording"); 392 logf("audio_init_recording");
404 queue_send(&pcmrec_queue, PCMREC_INIT, 0); 393 queue_send(&audio_queue, Q_AUDIO_INIT_RECORDING, 1);
405 logf("audio_init_recording done"); 394 logf("audio_init_recording done");
406} /* audio_init_recording */ 395} /* audio_init_recording */
407 396
@@ -411,7 +400,7 @@ void audio_init_recording(void)
411void audio_close_recording(void) 400void audio_close_recording(void)
412{ 401{
413 logf("audio_close_recording"); 402 logf("audio_close_recording");
414 queue_send(&pcmrec_queue, PCMREC_CLOSE, 0); 403 queue_send(&audio_queue, Q_AUDIO_CLOSE_RECORDING, 0);
415 logf("audio_close_recording done"); 404 logf("audio_close_recording done");
416} /* audio_close_recording */ 405} /* audio_close_recording */
417 406
@@ -421,7 +410,7 @@ void audio_close_recording(void)
421void audio_set_recording_options(struct audio_recording_options *options) 410void audio_set_recording_options(struct audio_recording_options *options)
422{ 411{
423 logf("audio_set_recording_options"); 412 logf("audio_set_recording_options");
424 queue_send(&pcmrec_queue, PCMREC_OPTIONS, (intptr_t)options); 413 queue_send(&audio_queue, Q_AUDIO_RECORDING_OPTIONS, (intptr_t)options);
425 logf("audio_set_recording_options done"); 414 logf("audio_set_recording_options done");
426} /* audio_set_recording_options */ 415} /* audio_set_recording_options */
427 416
@@ -432,7 +421,7 @@ void audio_record(const char *filename)
432{ 421{
433 logf("audio_record: %s", filename); 422 logf("audio_record: %s", filename);
434 flush_interrupt(); 423 flush_interrupt();
435 queue_send(&pcmrec_queue, PCMREC_RECORD, (intptr_t)filename); 424 queue_send(&audio_queue, Q_AUDIO_RECORD, (intptr_t)filename);
436 logf("audio_record_done"); 425 logf("audio_record_done");
437} /* audio_record */ 426} /* audio_record */
438 427
@@ -451,7 +440,7 @@ void audio_stop_recording(void)
451{ 440{
452 logf("audio_stop_recording"); 441 logf("audio_stop_recording");
453 flush_interrupt(); 442 flush_interrupt();
454 queue_post(&pcmrec_queue, PCMREC_STOP, 0); 443 queue_post(&audio_queue, Q_AUDIO_STOP, 0);
455 logf("audio_stop_recording done"); 444 logf("audio_stop_recording done");
456} /* audio_stop_recording */ 445} /* audio_stop_recording */
457 446
@@ -462,7 +451,7 @@ void audio_pause_recording(void)
462{ 451{
463 logf("audio_pause_recording"); 452 logf("audio_pause_recording");
464 flush_interrupt(); 453 flush_interrupt();
465 queue_post(&pcmrec_queue, PCMREC_PAUSE, 0); 454 queue_post(&audio_queue, Q_AUDIO_PAUSE, 0);
466 logf("audio_pause_recording done"); 455 logf("audio_pause_recording done");
467} /* audio_pause_recording */ 456} /* audio_pause_recording */
468 457
@@ -472,7 +461,7 @@ void audio_pause_recording(void)
472void audio_resume_recording(void) 461void audio_resume_recording(void)
473{ 462{
474 logf("audio_resume_recording"); 463 logf("audio_resume_recording");
475 queue_post(&pcmrec_queue, PCMREC_RESUME, 0); 464 queue_post(&audio_queue, Q_AUDIO_RESUME, 0);
476 logf("audio_resume_recording done"); 465 logf("audio_resume_recording done");
477} /* audio_resume_recording */ 466} /* audio_resume_recording */
478 467
@@ -517,10 +506,46 @@ unsigned long audio_num_recorded_bytes(void)
517 506
518/***************************************************************************/ 507/***************************************************************************/
519/* */ 508/* */
520/* Functions that execute in the context of pcmrec_thread */ 509/* Functions that execute in the context of audio thread */
521/* */ 510/* */
522/***************************************************************************/ 511/***************************************************************************/
523 512
513static void pcmrec_init_state(void)
514{
515 flush_interrupts = 0;
516
517 /* warings and errors */
518 warnings =
519 errors = 0;
520
521 /* pcm FIFO */
522 dma_lock = true;
523 pcm_rd_pos = 0;
524 dma_wr_pos = 0;
525 pcm_enc_pos = 0;
526
527 /* encoder FIFO */
528 enc_wr_index = 0;
529 enc_rd_index = 0;
530
531 /* filename queue */
532 fnq_rd_pos = 0;
533 fnq_wr_pos = 0;
534
535 /* stats */
536 num_rec_bytes = 0;
537 num_rec_samples = 0;
538#if 0
539 accum_rec_bytes = 0;
540 accum_pcm_samples = 0;
541#endif
542
543 pre_record_ticks = 0;
544
545 is_recording = false;
546 is_paused = false;
547} /* pcmrec_init_state */
548
524/** Filename Queue **/ 549/** Filename Queue **/
525 550
526/* returns true if the queue is empty */ 551/* returns true if the queue is empty */
@@ -594,7 +619,7 @@ static void pcmrec_close_file(int *fd_p)
594 return; /* preserve error */ 619 return; /* preserve error */
595 620
596 if (close(*fd_p) != 0) 621 if (close(*fd_p) != 0)
597 errors |= PCMREC_E_IO; 622 pcmrec_raise_error_status(PCMREC_E_IO);
598 623
599 *fd_p = -1; 624 *fd_p = -1;
600} /* pcmrec_close_file */ 625} /* pcmrec_close_file */
@@ -646,7 +671,7 @@ static void pcmrec_start_file(void)
646 { 671 {
647 logf("start file: fnq empty"); 672 logf("start file: fnq empty");
648 *filename = '\0'; 673 *filename = '\0';
649 errors |= PCMREC_E_FNQ_DESYNC; 674 pcmrec_raise_error_status(PCMREC_E_FNQ_DESYNC);
650 } 675 }
651 else if (errors != 0) 676 else if (errors != 0)
652 { 677 {
@@ -656,7 +681,7 @@ static void pcmrec_start_file(void)
656 { 681 {
657 /* Any previous file should have been closed */ 682 /* Any previous file should have been closed */
658 logf("start file: file already open"); 683 logf("start file: file already open");
659 errors |= PCMREC_E_FNQ_DESYNC; 684 pcmrec_raise_error_status(PCMREC_E_FNQ_DESYNC);
660 } 685 }
661 686
662 if (errors != 0) 687 if (errors != 0)
@@ -671,7 +696,7 @@ static void pcmrec_start_file(void)
671 if (errors == 0 && (rec_fdata.chunk->flags & CHUNKF_ERROR)) 696 if (errors == 0 && (rec_fdata.chunk->flags & CHUNKF_ERROR))
672 { 697 {
673 logf("start file: enc error"); 698 logf("start file: enc error");
674 errors |= PCMREC_E_ENCODER; 699 pcmrec_raise_error_status(PCMREC_E_ENCODER);
675 } 700 }
676 701
677 if (errors != 0) 702 if (errors != 0)
@@ -706,7 +731,7 @@ static inline void pcmrec_write_chunk(void)
706 { 731 {
707 logf("wr chk enc error %lu %lu", 732 logf("wr chk enc error %lu %lu",
708 rec_fdata.chunk->enc_size, rec_fdata.chunk->num_pcm); 733 rec_fdata.chunk->enc_size, rec_fdata.chunk->num_pcm);
709 errors |= PCMREC_E_ENCODER; 734 pcmrec_raise_error_status(PCMREC_E_ENCODER);
710 } 735 }
711} /* pcmrec_write_chunk */ 736} /* pcmrec_write_chunk */
712 737
@@ -725,7 +750,7 @@ static void pcmrec_end_file(void)
725 if (rec_fdata.chunk->flags & CHUNKF_ERROR) 750 if (rec_fdata.chunk->flags & CHUNKF_ERROR)
726 { 751 {
727 logf("end file: enc error"); 752 logf("end file: enc error");
728 errors |= PCMREC_E_ENCODER; 753 pcmrec_raise_error_status(PCMREC_E_ENCODER);
729 } 754 }
730 else 755 else
731 { 756 {
@@ -946,7 +971,7 @@ static void pcmrec_flush(unsigned flush_num)
946 971
947 /* sync file */ 972 /* sync file */
948 if (rec_fdata.rec_file >= 0 && fsync(rec_fdata.rec_file) != 0) 973 if (rec_fdata.rec_file >= 0 && fsync(rec_fdata.rec_file) != 0)
949 errors |= PCMREC_E_IO; 974 pcmrec_raise_error_status(PCMREC_E_IO);
950 975
951 cpu_boost(false); 976 cpu_boost(false);
952 977
@@ -1001,7 +1026,7 @@ static void pcmrec_new_stream(const char *filename, /* next file name */
1001 1026
1002 if (filename) 1027 if (filename)
1003 strlcpy(path, filename, MAX_PATH); 1028 strlcpy(path, filename, MAX_PATH);
1004 queue_reply(&pcmrec_queue, 0); /* We have all we need */ 1029 queue_reply(&audio_queue, 0); /* We have all we need */
1005 1030
1006 data.pre_chunk = NULL; 1031 data.pre_chunk = NULL;
1007 data.chunk = GET_ENC_CHUNK(enc_wr_index); 1032 data.chunk = GET_ENC_CHUNK(enc_wr_index);
@@ -1129,51 +1154,18 @@ static void pcmrec_new_stream(const char *filename, /* next file name */
1129 pcmrec_flush(PCMREC_FLUSH_IF_HIGH); 1154 pcmrec_flush(PCMREC_FLUSH_IF_HIGH);
1130} /* pcmrec_new_stream */ 1155} /* pcmrec_new_stream */
1131 1156
1157
1132/** event handlers for pcmrec thread */ 1158/** event handlers for pcmrec thread */
1133 1159
1134/* PCMREC_INIT */ 1160/* PCMREC_INIT */
1135static void pcmrec_init(void) 1161static void pcmrec_init(void)
1136{ 1162{
1137 is_initialized = true;
1138
1139 unsigned char *buffer;
1140 send_event(RECORDING_EVENT_START, NULL); 1163 send_event(RECORDING_EVENT_START, NULL);
1141
1142 /* warings and errors */
1143 warnings =
1144 errors = 0;
1145
1146 pcmrec_close_file(&rec_fdata.rec_file); 1164 pcmrec_close_file(&rec_fdata.rec_file);
1147 rec_fdata.rec_file = -1;
1148 1165
1149 /* pcm FIFO */ 1166 pcmrec_init_state();
1150 dma_lock = true;
1151 pcm_rd_pos = 0;
1152 dma_wr_pos = 0;
1153 pcm_enc_pos = 0;
1154 1167
1155 /* encoder FIFO */ 1168 unsigned char *buffer = audio_get_buffer(true, &rec_buffer_size);
1156 enc_wr_index = 0;
1157 enc_rd_index = 0;
1158
1159 /* filename queue */
1160 fnq_rd_pos = 0;
1161 fnq_wr_pos = 0;
1162
1163 /* stats */
1164 num_rec_bytes = 0;
1165 num_rec_samples = 0;
1166#if 0
1167 accum_rec_bytes = 0;
1168 accum_pcm_samples = 0;
1169#endif
1170
1171 pre_record_ticks = 0;
1172
1173 is_recording = false;
1174 is_paused = false;
1175
1176 buffer = audio_get_recording_buffer(&rec_buffer_size);
1177 1169
1178 /* Line align pcm_buffer 2^5=32 bytes */ 1170 /* Line align pcm_buffer 2^5=32 bytes */
1179 pcm_buffer = (unsigned char *)ALIGN_UP_P2((uintptr_t)buffer, 5); 1171 pcm_buffer = (unsigned char *)ALIGN_UP_P2((uintptr_t)buffer, 5);
@@ -1188,23 +1180,25 @@ static void pcmrec_init(void)
1188/* PCMREC_CLOSE */ 1180/* PCMREC_CLOSE */
1189static void pcmrec_close(void) 1181static void pcmrec_close(void)
1190{ 1182{
1191 is_initialized = false;
1192 dma_lock = true; 1183 dma_lock = true;
1193 pre_record_ticks = 0; /* Can't be prerecording any more */ 1184 pre_record_ticks = 0; /* Can't be prerecording any more */
1194 warnings = 0; 1185 warnings = 0;
1186 codec_unload();
1195 pcm_close_recording(); 1187 pcm_close_recording();
1196 reset_hardware(); 1188 reset_hardware();
1197 audio_remove_encoder();
1198 send_event(RECORDING_EVENT_STOP, NULL); 1189 send_event(RECORDING_EVENT_STOP, NULL);
1199} /* pcmrec_close */ 1190} /* pcmrec_close */
1200 1191
1201/* PCMREC_OPTIONS */ 1192/* PCMREC_OPTIONS */
1202static void pcmrec_set_recording_options( 1193static void pcmrec_set_recording_options(
1194 struct event_queue *q,
1203 struct audio_recording_options *options) 1195 struct audio_recording_options *options)
1204{ 1196{
1205 /* stop DMA transfer */ 1197 /* stop everything */
1206 dma_lock = true; 1198 dma_lock = true;
1199 codec_unload();
1207 pcm_stop_recording(); 1200 pcm_stop_recording();
1201 pcmrec_init_state();
1208 1202
1209 rec_frequency = options->rec_frequency; 1203 rec_frequency = options->rec_frequency;
1210 rec_source = options->rec_source; 1204 rec_source = options->rec_source;
@@ -1243,10 +1237,13 @@ static void pcmrec_set_recording_options(
1243 /* apply hardware setting to start monitoring now */ 1237 /* apply hardware setting to start monitoring now */
1244 pcm_apply_settings(); 1238 pcm_apply_settings();
1245 1239
1246 queue_reply(&pcmrec_queue, 0); /* Release sender */ 1240 if (codec_load(-1, enc_config.afmt | CODEC_TYPE_ENCODER))
1247
1248 if (audio_load_encoder(enc_config.afmt))
1249 { 1241 {
1242 queue_reply(q, true);
1243
1244 /* run immediately */
1245 codec_go();
1246
1250 /* start DMA transfer */ 1247 /* start DMA transfer */
1251 dma_lock = pre_record_ticks == 0; 1248 dma_lock = pre_record_ticks == 0;
1252 pcm_record_data(pcm_rec_have_more, pcm_rec_status_callback, 1249 pcm_record_data(pcm_rec_have_more, pcm_rec_status_callback,
@@ -1255,7 +1252,7 @@ static void pcmrec_set_recording_options(
1255 else 1252 else
1256 { 1253 {
1257 logf("set rec opt: enc load failed"); 1254 logf("set rec opt: enc load failed");
1258 errors |= PCMREC_E_LOAD_ENCODER; 1255 pcmrec_raise_error_status(PCMREC_E_LOAD_ENCODER);
1259 } 1256 }
1260} /* pcmrec_set_recording_options */ 1257} /* pcmrec_set_recording_options */
1261 1258
@@ -1468,97 +1465,65 @@ static void pcmrec_resume(void)
1468 logf("pcmrec_resume done"); 1465 logf("pcmrec_resume done");
1469} /* pcmrec_resume */ 1466} /* pcmrec_resume */
1470 1467
1471static void pcmrec_thread(void) NORETURN_ATTR; 1468/* Called by audio thread when recording is initialized */
1472static void pcmrec_thread(void) 1469void audio_recording_handler(struct queue_event *ev)
1473{ 1470{
1474 struct queue_event ev; 1471 logf("audio recording start");
1475
1476 logf("thread pcmrec start");
1477 1472
1478 while(1) 1473 while (1)
1479 { 1474 {
1480 if (is_recording) 1475 switch (ev->id)
1481 { 1476 {
1482 /* Poll periodically to flush data */ 1477 case Q_AUDIO_INIT_RECORDING:
1483 queue_wait_w_tmo(&pcmrec_queue, &ev, HZ/5); 1478 pcmrec_init();
1484 1479 break;
1485 if (ev.id == SYS_TIMEOUT)
1486 {
1487 /* Messages that interrupt this will complete it */
1488 pcmrec_flush(PCMREC_FLUSH_IF_HIGH |
1489 PCMREC_FLUSH_INTERRUPTABLE);
1490 continue;
1491 }
1492 }
1493 else
1494 {
1495 /* Not doing anything - sit and wait for commands */
1496 queue_wait(&pcmrec_queue, &ev);
1497
1498 /* Some messages must be handled even if not initialized */
1499 switch (ev.id)
1500 {
1501 case PCMREC_INIT:
1502 case SYS_USB_CONNECTED:
1503 break;
1504 default:
1505 if (!is_initialized)
1506 continue;
1507 }
1508 }
1509
1510 switch (ev.id)
1511 {
1512 case PCMREC_INIT:
1513 pcmrec_init();
1514 break;
1515
1516 case PCMREC_CLOSE:
1517 pcmrec_close();
1518 break;
1519 1480
1520 case PCMREC_OPTIONS: 1481 case SYS_USB_CONNECTED:
1521 pcmrec_set_recording_options( 1482 if (is_recording)
1522 (struct audio_recording_options *)ev.data);
1523 break; 1483 break;
1484 /* Fall-through */
1485 case Q_AUDIO_CLOSE_RECORDING:
1486 pcmrec_close();
1487 return; /* no more recording */
1488
1489 case Q_AUDIO_RECORDING_OPTIONS:
1490 pcmrec_set_recording_options(&audio_queue,
1491 (struct audio_recording_options *)ev->data);
1492 break;
1524 1493
1525 case PCMREC_RECORD: 1494 case Q_AUDIO_RECORD:
1526 clear_flush_interrupt(); 1495 clear_flush_interrupt();
1527 pcmrec_record((const char *)ev.data); 1496 pcmrec_record((const char *)ev->data);
1528 break; 1497 break;
1529 1498
1530 case PCMREC_STOP: 1499 case Q_AUDIO_STOP:
1531 clear_flush_interrupt(); 1500 clear_flush_interrupt();
1532 pcmrec_stop(); 1501 pcmrec_stop();
1533 break; 1502 break;
1534 1503
1535 case PCMREC_PAUSE: 1504 case Q_AUDIO_PAUSE:
1536 clear_flush_interrupt(); 1505 clear_flush_interrupt();
1537 pcmrec_pause(); 1506 pcmrec_pause();
1538 break; 1507 break;
1539 1508
1540 case PCMREC_RESUME: 1509 case Q_AUDIO_RESUME:
1541 pcmrec_resume(); 1510 pcmrec_resume();
1542 break; 1511 break;
1543#if 0
1544 case PCMREC_FLUSH_NUM:
1545 pcmrec_flush((unsigned)ev.data);
1546 break;
1547#endif
1548 case SYS_USB_CONNECTED:
1549 if (is_recording)
1550 break;
1551 1512
1552 if (is_initialized) 1513 case SYS_TIMEOUT:
1553 pcmrec_close(); 1514 /* Messages that interrupt this will complete it */
1515 pcmrec_flush(PCMREC_FLUSH_IF_HIGH |
1516 PCMREC_FLUSH_INTERRUPTABLE);
1554 1517
1555 usb_acknowledge(SYS_USB_CONNECTED_ACK); 1518 if (errors & PCMREC_E_DMA)
1556 usb_wait_for_disconnect(&pcmrec_queue); 1519 queue_post(&audio_queue, Q_AUDIO_STOP, 0);
1557 flush_interrupts = 0; 1520 break;
1558 break;
1559 } /* end switch */ 1521 } /* end switch */
1522
1523 queue_wait_w_tmo(&audio_queue, ev,
1524 is_recording ? HZ/5 : TIMEOUT_BLOCK);
1560 } /* end while */ 1525 } /* end while */
1561} /* pcmrec_thread */ 1526} /* audio_recording_handler */
1562 1527
1563/****************************************************************************/ 1528/****************************************************************************/
1564/* */ 1529/* */
@@ -1696,7 +1661,7 @@ struct enc_chunk_hdr * enc_get_chunk(void)
1696#ifdef DEBUG 1661#ifdef DEBUG
1697 if (chunk->id != ENC_CHUNK_MAGIC || *wrap_id_p != ENC_CHUNK_MAGIC) 1662 if (chunk->id != ENC_CHUNK_MAGIC || *wrap_id_p != ENC_CHUNK_MAGIC)
1698 { 1663 {
1699 errors |= PCMREC_E_CHUNK_OVF; 1664 pcmrec_raise_error_status(PCMREC_E_CHUNK_OVF);
1700 logf("finish chk ovf: %d", enc_wr_index); 1665 logf("finish chk ovf: %d", enc_wr_index);
1701 } 1666 }
1702#endif 1667#endif
@@ -1718,7 +1683,7 @@ void enc_finish_chunk(void)
1718 if ((long)chunk->flags < 0) 1683 if ((long)chunk->flags < 0)
1719 { 1684 {
1720 /* encoder set error flag */ 1685 /* encoder set error flag */
1721 errors |= PCMREC_E_ENCODER; 1686 pcmrec_raise_error_status(PCMREC_E_ENCODER);
1722 logf("finish chk enc error"); 1687 logf("finish chk enc error");
1723 } 1688 }
1724 1689
@@ -1737,7 +1702,7 @@ void enc_finish_chunk(void)
1737 else if (is_recording) /* buffer full */ 1702 else if (is_recording) /* buffer full */
1738 { 1703 {
1739 /* keep current position and put up warning flag */ 1704 /* keep current position and put up warning flag */
1740 warnings |= PCMREC_W_ENC_BUFFER_OVF; 1705 pcmrec_raise_warning_status(PCMREC_W_ENC_BUFFER_OVF);
1741 logf("enc_buffer ovf"); 1706 logf("enc_buffer ovf");
1742 DEC_ENC_INDEX(enc_wr_index); 1707 DEC_ENC_INDEX(enc_wr_index);
1743 if (pcmrec_context) 1708 if (pcmrec_context)