mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
Commit the kinds of changes that queue_send is mean for.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11778 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
8b4970031f
commit
42b0208253
2 changed files with 101 additions and 121 deletions
131
apps/playback.c
131
apps/playback.c
|
@ -141,7 +141,9 @@ enum {
|
||||||
Q_AUDIO_LOAD_ENCODER,
|
Q_AUDIO_LOAD_ENCODER,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
Q_CODEC_REQUEST_PENDING,
|
Q_CODEC_REQUEST_PENDING,
|
||||||
|
#endif
|
||||||
Q_CODEC_REQUEST_COMPLETE,
|
Q_CODEC_REQUEST_COMPLETE,
|
||||||
Q_CODEC_REQUEST_FAILED,
|
Q_CODEC_REQUEST_FAILED,
|
||||||
|
|
||||||
|
@ -195,7 +197,6 @@ static bool audio_is_initialized = false;
|
||||||
/* TBD: Split out "audio" and "playback" (ie. calling) threads */
|
/* TBD: Split out "audio" and "playback" (ie. calling) threads */
|
||||||
|
|
||||||
/* Main state control */
|
/* Main state control */
|
||||||
static struct event_queue codec_callback_queue; /* Queue for codec callback responses */
|
|
||||||
static volatile bool audio_codec_loaded; /* Is codec loaded? (C/A-) */
|
static volatile bool audio_codec_loaded; /* Is codec loaded? (C/A-) */
|
||||||
static volatile bool playing; /* Is audio playing? (A) */
|
static volatile bool playing; /* Is audio playing? (A) */
|
||||||
static volatile bool paused; /* Is audio paused? (A/C-) */
|
static volatile bool paused; /* Is audio paused? (A/C-) */
|
||||||
|
@ -251,13 +252,17 @@ static size_t conf_filechunk; /* Largest chunk the codec accep
|
||||||
static size_t conf_preseek; /* Codec pre-seek margin (A/C) FIXME */
|
static size_t conf_preseek; /* Codec pre-seek margin (A/C) FIXME */
|
||||||
static size_t buffer_margin; /* Buffer margin aka anti-skip buffer (A/C-) */
|
static size_t buffer_margin; /* Buffer margin aka anti-skip buffer (A/C-) */
|
||||||
static bool v1first = false; /* ID3 data control, true if V1 then V2 (A) */
|
static bool v1first = false; /* ID3 data control, true if V1 then V2 (A) */
|
||||||
|
#if MEM > 8
|
||||||
|
static size_t high_watermark; /* High watermark for rebuffer (A/V/other) */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Multiple threads */
|
/* Multiple threads */
|
||||||
static const char *get_codec_filename(int enc_spec); /* Returns codec filename (A-/C-/V-) */
|
static const char *get_codec_filename(int enc_spec); /* Returns codec filename (A-/C-/V-) */
|
||||||
static void set_filebuf_watermark(int seconds); /* Set low watermark (A/C) FIXME */
|
static void set_filebuf_watermark(int seconds); /* Set low watermark (A/C) FIXME */
|
||||||
|
|
||||||
/* Audio thread */
|
/* Audio thread */
|
||||||
static struct event_queue audio_queue;
|
static struct event_queue audio_queue;
|
||||||
|
static struct queue_sender_list audio_queue_sender_list;
|
||||||
static long audio_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
|
static long audio_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
|
||||||
static const char audio_thread_name[] = "audio";
|
static const char audio_thread_name[] = "audio";
|
||||||
|
|
||||||
|
@ -832,9 +837,8 @@ void audio_preinit(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
queue_init(&audio_queue, true);
|
queue_init(&audio_queue, true);
|
||||||
|
queue_enable_queue_send(&audio_queue, &audio_queue_sender_list);
|
||||||
queue_init(&codec_queue, true);
|
queue_init(&codec_queue, true);
|
||||||
/* create a private queue */
|
|
||||||
queue_init(&codec_callback_queue, false);
|
|
||||||
|
|
||||||
create_thread(audio_thread, audio_stack, sizeof(audio_stack),
|
create_thread(audio_thread, audio_stack, sizeof(audio_stack),
|
||||||
audio_thread_name IF_PRIO(, PRIORITY_BUFFERING));
|
audio_thread_name IF_PRIO(, PRIORITY_BUFFERING));
|
||||||
|
@ -1569,26 +1573,25 @@ static void codec_advance_buffer_callback(size_t amount)
|
||||||
|
|
||||||
if (amount > CUR_TI->available)
|
if (amount > CUR_TI->available)
|
||||||
{
|
{
|
||||||
struct event ev;
|
int result;
|
||||||
|
LOGFQUEUE("codec >| audio Q_AUDIO_REBUFFER_SEEK");
|
||||||
|
|
||||||
LOGFQUEUE("codec > audio Q_AUDIO_REBUFFER_SEEK");
|
result = (int)queue_send(&audio_queue, Q_AUDIO_REBUFFER_SEEK,
|
||||||
queue_post(&audio_queue,
|
(void *)(ci.curpos + amount));
|
||||||
Q_AUDIO_REBUFFER_SEEK, (void *)(ci.curpos + amount));
|
|
||||||
|
switch (result)
|
||||||
queue_wait(&codec_callback_queue, &ev);
|
|
||||||
switch (ev.id)
|
|
||||||
{
|
{
|
||||||
case Q_CODEC_REQUEST_FAILED:
|
case Q_CODEC_REQUEST_FAILED:
|
||||||
LOGFQUEUE("codec < Q_CODEC_REQUEST_FAILED");
|
LOGFQUEUE("codec |< Q_CODEC_REQUEST_FAILED");
|
||||||
ci.stop_codec = true;
|
ci.stop_codec = true;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case Q_CODEC_REQUEST_COMPLETE:
|
case Q_CODEC_REQUEST_COMPLETE:
|
||||||
LOGFQUEUE("codec < Q_CODEC_REQUEST_COMPLETE");
|
LOGFQUEUE("codec |< Q_CODEC_REQUEST_COMPLETE");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOGFQUEUE("codec < default");
|
LOGFQUEUE("codec |< default");
|
||||||
ci.stop_codec = true;
|
ci.stop_codec = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1713,25 +1716,25 @@ static bool codec_seek_buffer_callback(size_t newpos)
|
||||||
/* We need to reload the song. */
|
/* We need to reload the song. */
|
||||||
if (newpos < CUR_TI->start_pos)
|
if (newpos < CUR_TI->start_pos)
|
||||||
{
|
{
|
||||||
struct event ev;
|
int result;
|
||||||
|
|
||||||
LOGFQUEUE("codec > audio Q_AUDIO_REBUFFER_SEEK");
|
LOGFQUEUE("codec >| audio Q_AUDIO_REBUFFER_SEEK");
|
||||||
queue_post(&audio_queue, Q_AUDIO_REBUFFER_SEEK, (void *)newpos);
|
result = (int)queue_send(&audio_queue, Q_AUDIO_REBUFFER_SEEK,
|
||||||
|
(void *)newpos);
|
||||||
|
|
||||||
queue_wait(&codec_callback_queue, &ev);
|
switch (result)
|
||||||
switch (ev.id)
|
|
||||||
{
|
{
|
||||||
case Q_CODEC_REQUEST_COMPLETE:
|
case Q_CODEC_REQUEST_COMPLETE:
|
||||||
LOGFQUEUE("codec < Q_CODEC_REQUEST_COMPLETE");
|
LOGFQUEUE("codec |< Q_CODEC_REQUEST_COMPLETE");
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Q_CODEC_REQUEST_FAILED:
|
case Q_CODEC_REQUEST_FAILED:
|
||||||
LOGFQUEUE("codec < Q_CODEC_REQUEST_FAILED");
|
LOGFQUEUE("codec |< Q_CODEC_REQUEST_FAILED");
|
||||||
ci.stop_codec = true;
|
ci.stop_codec = true;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOGFQUEUE("codec < default");
|
LOGFQUEUE("codec |< default");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1831,7 +1834,7 @@ static void codec_track_skip_done(bool was_manual)
|
||||||
|
|
||||||
static bool codec_load_next_track(void)
|
static bool codec_load_next_track(void)
|
||||||
{
|
{
|
||||||
struct event ev;
|
int result;
|
||||||
|
|
||||||
prev_track_elapsed = CUR_TI->id3.elapsed;
|
prev_track_elapsed = CUR_TI->id3.elapsed;
|
||||||
|
|
||||||
|
@ -1851,8 +1854,10 @@ static bool codec_load_next_track(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
trigger_cpu_boost();
|
trigger_cpu_boost();
|
||||||
LOGFQUEUE("codec > audio Q_AUDIO_CHECK_NEW_TRACK");
|
LOGFQUEUE("codec >| audio Q_AUDIO_CHECK_NEW_TRACK");
|
||||||
queue_post(&audio_queue, Q_AUDIO_CHECK_NEW_TRACK, 0);
|
result = (int)queue_send(&audio_queue, Q_AUDIO_CHECK_NEW_TRACK, NULL);
|
||||||
|
|
||||||
|
#if 0 /* Q_CODEC_REQUEST_PENDING never posted anyway */
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
queue_wait(&codec_callback_queue, &ev);
|
queue_wait(&codec_callback_queue, &ev);
|
||||||
|
@ -1864,22 +1869,23 @@ static bool codec_load_next_track(void)
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (ev.id)
|
switch (result)
|
||||||
{
|
{
|
||||||
case Q_CODEC_REQUEST_COMPLETE:
|
case Q_CODEC_REQUEST_COMPLETE:
|
||||||
LOGFQUEUE("codec < Q_CODEC_REQUEST_COMPLETE");
|
LOGFQUEUE("codec |< Q_CODEC_REQUEST_COMPLETE");
|
||||||
codec_track_skip_done(!automatic_skip);
|
codec_track_skip_done(!automatic_skip);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Q_CODEC_REQUEST_FAILED:
|
case Q_CODEC_REQUEST_FAILED:
|
||||||
LOGFQUEUE("codec < Q_CODEC_REQUEST_FAILED");
|
LOGFQUEUE("codec |< Q_CODEC_REQUEST_FAILED");
|
||||||
ci.new_track = 0;
|
ci.new_track = 0;
|
||||||
ci.stop_codec = true;
|
ci.stop_codec = true;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOGFQUEUE("codec < default");
|
LOGFQUEUE("codec |< default");
|
||||||
ci.stop_codec = true;
|
ci.stop_codec = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2945,7 +2951,8 @@ static void audio_fill_file_buffer(
|
||||||
static void audio_rebuffer(void)
|
static void audio_rebuffer(void)
|
||||||
{
|
{
|
||||||
logf("Forcing rebuffer");
|
logf("Forcing rebuffer");
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Notify the codec that this will take a while */
|
/* Notify the codec that this will take a while */
|
||||||
/* Currently this can cause some problems (logf in reverse order):
|
/* Currently this can cause some problems (logf in reverse order):
|
||||||
* Codec load error:-1
|
* Codec load error:-1
|
||||||
|
@ -2962,8 +2969,9 @@ static void audio_rebuffer(void)
|
||||||
* Clearing tracks:5/5, 1
|
* Clearing tracks:5/5, 1
|
||||||
* Re-buffering song w/seek
|
* Re-buffering song w/seek
|
||||||
*/
|
*/
|
||||||
//if (!filling)
|
if (!filling)
|
||||||
// queue_post(&codec_callback_queue, Q_CODEC_REQUEST_PENDING, 0);
|
queue_post(&codec_callback_queue, Q_CODEC_REQUEST_PENDING, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Stop in progress fill, and clear open file descriptor */
|
/* Stop in progress fill, and clear open file descriptor */
|
||||||
if (current_fd >= 0)
|
if (current_fd >= 0)
|
||||||
|
@ -2991,7 +2999,7 @@ static void audio_rebuffer(void)
|
||||||
audio_fill_file_buffer(false, true, 0);
|
audio_fill_file_buffer(false, true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void audio_check_new_track(void)
|
static int audio_check_new_track(void)
|
||||||
{
|
{
|
||||||
int track_count = audio_track_count();
|
int track_count = audio_track_count();
|
||||||
int old_track_ridx = track_ridx;
|
int old_track_ridx = track_ridx;
|
||||||
|
@ -3009,9 +3017,8 @@ static void audio_check_new_track(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOGFQUEUE("audio > codec Q_CODEC_REQUEST_FAILED");
|
LOGFQUEUE("audio >|= codec Q_CODEC_REQUEST_FAILED");
|
||||||
queue_post(&codec_callback_queue, Q_CODEC_REQUEST_FAILED, 0);
|
return Q_CODEC_REQUEST_FAILED;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3023,17 +3030,15 @@ static void audio_check_new_track(void)
|
||||||
{
|
{
|
||||||
if (ci.new_track >= 0)
|
if (ci.new_track >= 0)
|
||||||
{
|
{
|
||||||
LOGFQUEUE("audio > codec Q_CODEC_REQUEST_FAILED");
|
LOGFQUEUE("audio >|= codec Q_CODEC_REQUEST_FAILED");
|
||||||
queue_post(&codec_callback_queue, Q_CODEC_REQUEST_FAILED, 0);
|
return Q_CODEC_REQUEST_FAILED;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
/* Find the beginning backward if the user over-skips it */
|
/* Find the beginning backward if the user over-skips it */
|
||||||
while (!playlist_check(++ci.new_track))
|
while (!playlist_check(++ci.new_track))
|
||||||
if (ci.new_track >= 0)
|
if (ci.new_track >= 0)
|
||||||
{
|
{
|
||||||
LOGFQUEUE("audio > codec Q_CODEC_REQUEST_FAILED");
|
LOGFQUEUE("audio >|= codec Q_CODEC_REQUEST_FAILED");
|
||||||
queue_post(&codec_callback_queue, Q_CODEC_REQUEST_FAILED, 0);
|
return Q_CODEC_REQUEST_FAILED;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Update the playlist */
|
/* Update the playlist */
|
||||||
|
@ -3041,9 +3046,8 @@ static void audio_check_new_track(void)
|
||||||
|
|
||||||
if (playlist_next(ci.new_track) < 0)
|
if (playlist_next(ci.new_track) < 0)
|
||||||
{
|
{
|
||||||
LOGFQUEUE("audio > codec Q_CODEC_REQUEST_FAILED");
|
LOGFQUEUE("audio >|= codec Q_CODEC_REQUEST_FAILED");
|
||||||
queue_post(&codec_callback_queue, Q_CODEC_REQUEST_FAILED, 0);
|
return Q_CODEC_REQUEST_FAILED;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_playlist)
|
if (new_playlist)
|
||||||
|
@ -3127,11 +3131,11 @@ static void audio_check_new_track(void)
|
||||||
|
|
||||||
skip_done:
|
skip_done:
|
||||||
audio_update_trackinfo();
|
audio_update_trackinfo();
|
||||||
LOGFQUEUE("audio > codec Q_CODEC_REQUEST_COMPLETE");
|
LOGFQUEUE("audio >|= codec Q_CODEC_REQUEST_COMPLETE");
|
||||||
queue_post(&codec_callback_queue, Q_CODEC_REQUEST_COMPLETE, 0);
|
return Q_CODEC_REQUEST_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void audio_rebuffer_and_seek(size_t newpos)
|
static int audio_rebuffer_and_seek(size_t newpos)
|
||||||
{
|
{
|
||||||
size_t real_preseek;
|
size_t real_preseek;
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -3142,9 +3146,8 @@ static void audio_rebuffer_and_seek(size_t newpos)
|
||||||
fd = open(trackname, O_RDONLY);
|
fd = open(trackname, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
LOGFQUEUE("audio > codec Q_CODEC_REQUEST_FAILED");
|
LOGFQUEUE("audio >|= codec Q_CODEC_REQUEST_FAILED");
|
||||||
queue_post(&codec_callback_queue, Q_CODEC_REQUEST_FAILED, 0);
|
return Q_CODEC_REQUEST_FAILED;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_fd >= 0)
|
if (current_fd >= 0)
|
||||||
|
@ -3188,8 +3191,8 @@ static void audio_rebuffer_and_seek(size_t newpos)
|
||||||
|
|
||||||
buf_ridx = RINGBUF_ADD(buf_ridx, real_preseek);
|
buf_ridx = RINGBUF_ADD(buf_ridx, real_preseek);
|
||||||
|
|
||||||
LOGFQUEUE("audio > codec Q_CODEC_REQUEST_COMPLETE");
|
LOGFQUEUE("audio >|= codec Q_CODEC_REQUEST_COMPLETE");
|
||||||
queue_post(&codec_callback_queue, Q_CODEC_REQUEST_COMPLETE, 0);
|
return Q_CODEC_REQUEST_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio_set_track_buffer_event(void (*handler)(struct mp3entry *id3,
|
void audio_set_track_buffer_event(void (*handler)(struct mp3entry *id3,
|
||||||
|
@ -3424,6 +3427,10 @@ static void audio_reset_buffer(size_t pcmbufsize)
|
||||||
filebuflen -= offset;
|
filebuflen -= offset;
|
||||||
filebuflen &= ~3;
|
filebuflen &= ~3;
|
||||||
|
|
||||||
|
#if MEM > 8
|
||||||
|
high_watermark = (3*filebuflen)/4;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Clear any references to the file buffer */
|
/* Clear any references to the file buffer */
|
||||||
buffer_state = BUFFER_STATE_NORMAL;
|
buffer_state = BUFFER_STATE_NORMAL;
|
||||||
}
|
}
|
||||||
|
@ -3539,17 +3546,13 @@ bool ata_fillbuffer_callback(void)
|
||||||
static void audio_thread(void)
|
static void audio_thread(void)
|
||||||
{
|
{
|
||||||
struct event ev;
|
struct event ev;
|
||||||
#if MEM > 8
|
|
||||||
size_t high_watermark;
|
|
||||||
#endif
|
|
||||||
/* At first initialize audio system in background. */
|
/* At first initialize audio system in background. */
|
||||||
audio_playback_init();
|
audio_playback_init();
|
||||||
#if MEM > 8
|
|
||||||
high_watermark = (3*filebuflen)/4;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
void *result = NULL;
|
||||||
|
|
||||||
if (filling)
|
if (filling)
|
||||||
{
|
{
|
||||||
queue_wait_w_tmo(&audio_queue, &ev, 0);
|
queue_wait_w_tmo(&audio_queue, &ev, 0);
|
||||||
|
@ -3622,12 +3625,12 @@ static void audio_thread(void)
|
||||||
|
|
||||||
case Q_AUDIO_REBUFFER_SEEK:
|
case Q_AUDIO_REBUFFER_SEEK:
|
||||||
LOGFQUEUE("audio < Q_AUDIO_REBUFFER_SEEK");
|
LOGFQUEUE("audio < Q_AUDIO_REBUFFER_SEEK");
|
||||||
audio_rebuffer_and_seek((size_t)ev.data);
|
result = (void *)audio_rebuffer_and_seek((size_t)ev.data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Q_AUDIO_CHECK_NEW_TRACK:
|
case Q_AUDIO_CHECK_NEW_TRACK:
|
||||||
LOGFQUEUE("audio < Q_AUDIO_CHECK_NEW_TRACK");
|
LOGFQUEUE("audio < Q_AUDIO_CHECK_NEW_TRACK");
|
||||||
audio_check_new_track();
|
result = (void *)audio_check_new_track();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Q_AUDIO_DIR_SKIP:
|
case Q_AUDIO_DIR_SKIP:
|
||||||
|
@ -3677,7 +3680,9 @@ static void audio_thread(void)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOGFQUEUE("audio < default");
|
LOGFQUEUE("audio < default");
|
||||||
}
|
} /* end switch */
|
||||||
}
|
|
||||||
|
queue_reply(&audio_queue, result);
|
||||||
|
} /* end while */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -222,50 +222,30 @@ static int enc_wr_index_last; /* previsou encoder read position */
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static struct event_queue pcmrec_queue;
|
static struct event_queue pcmrec_queue;
|
||||||
|
static struct queue_sender_list pcmrec_queue_send;
|
||||||
static long pcmrec_stack[3*DEFAULT_STACK_SIZE/sizeof(long)];
|
static long pcmrec_stack[3*DEFAULT_STACK_SIZE/sizeof(long)];
|
||||||
static const char pcmrec_thread_name[] = "pcmrec";
|
static const char pcmrec_thread_name[] = "pcmrec";
|
||||||
|
|
||||||
static void pcmrec_thread(void);
|
static void pcmrec_thread(void);
|
||||||
|
|
||||||
/* Event values which are also single-bit flags */
|
enum
|
||||||
#define PCMREC_INIT 0x00000001 /* enable recording */
|
|
||||||
#define PCMREC_CLOSE 0x00000002 /* close recording */
|
|
||||||
#define PCMREC_OPTIONS 0x00000004 /* set recording options */
|
|
||||||
#define PCMREC_START 0x00000008 /* start recording */
|
|
||||||
#define PCMREC_STOP 0x00000010 /* stop the current recording */
|
|
||||||
#define PCMREC_PAUSE 0x00000020 /* pause the current recording */
|
|
||||||
#define PCMREC_RESUME 0x00000040 /* resume the current recording */
|
|
||||||
#define PCMREC_NEW_FILE 0x00000080 /* start new file */
|
|
||||||
#define PCMREC_FLUSH_NUM 0x00000100 /* flush a number of files out */
|
|
||||||
#define PCMREC_FINISH_STOP 0x00000200 /* finish the stopping recording */
|
|
||||||
|
|
||||||
/* mask for signaling events */
|
|
||||||
static volatile long pcm_thread_event_mask = PCMREC_CLOSE;
|
|
||||||
|
|
||||||
static void pcm_thread_sync_post(long event, void *data)
|
|
||||||
{
|
{
|
||||||
pcm_thread_event_mask &= ~event;
|
PCMREC_NULL = 0,
|
||||||
queue_post(&pcmrec_queue, event, data);
|
PCMREC_INIT, /* enable recording */
|
||||||
while(!(event & pcm_thread_event_mask))
|
PCMREC_CLOSE, /* close recording */
|
||||||
yield();
|
PCMREC_OPTIONS, /* set recording options */
|
||||||
} /* pcm_thread_sync_post */
|
PCMREC_START, /* start recording */
|
||||||
|
PCMREC_STOP, /* stop the current recording */
|
||||||
|
PCMREC_FINISH_STOP, /* finish the stopping recording */
|
||||||
|
PCMREC_PAUSE, /* pause the current recording */
|
||||||
|
PCMREC_RESUME, /* resume the current recording */
|
||||||
|
PCMREC_NEW_FILE, /* start new file */
|
||||||
|
#if 0
|
||||||
|
PCMREC_FLUSH_NUM, /* flush a number of files out */
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
static inline void pcm_thread_signal_event(long event)
|
|
||||||
{
|
|
||||||
pcm_thread_event_mask |= event;
|
|
||||||
} /* pcm_thread_signal_event */
|
|
||||||
|
|
||||||
static inline void pcm_thread_unsignal_event(long event)
|
|
||||||
{
|
|
||||||
pcm_thread_event_mask &= ~event;
|
|
||||||
} /* pcm_thread_unsignal_event */
|
|
||||||
|
|
||||||
static inline bool pcm_thread_event_state(long signaled, long unsignaled)
|
|
||||||
{
|
|
||||||
return ((signaled | unsignaled) & pcm_thread_event_mask) == signaled;
|
|
||||||
} /* pcm_thread_event_state */
|
|
||||||
|
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
/* Functions that are not executing in the pcmrec_thread first */
|
/* Functions that are not executing in the pcmrec_thread first */
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
|
@ -401,6 +381,7 @@ unsigned long pcm_rec_sample_rate(void)
|
||||||
void pcm_rec_init(void)
|
void pcm_rec_init(void)
|
||||||
{
|
{
|
||||||
queue_init(&pcmrec_queue, true);
|
queue_init(&pcmrec_queue, true);
|
||||||
|
queue_enable_queue_send(&pcmrec_queue, &pcmrec_queue_send);
|
||||||
create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack),
|
create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack),
|
||||||
pcmrec_thread_name, PRIORITY_RECORDING);
|
pcmrec_thread_name, PRIORITY_RECORDING);
|
||||||
} /* pcm_rec_init */
|
} /* pcm_rec_init */
|
||||||
|
@ -417,7 +398,7 @@ void pcm_rec_init(void)
|
||||||
void audio_init_recording(unsigned int buffer_offset)
|
void audio_init_recording(unsigned int buffer_offset)
|
||||||
{
|
{
|
||||||
logf("audio_init_recording");
|
logf("audio_init_recording");
|
||||||
pcm_thread_sync_post(PCMREC_INIT, NULL);
|
queue_send(&pcmrec_queue, PCMREC_INIT, NULL);
|
||||||
logf("audio_init_recording done");
|
logf("audio_init_recording done");
|
||||||
(void)buffer_offset;
|
(void)buffer_offset;
|
||||||
} /* audio_init_recording */
|
} /* audio_init_recording */
|
||||||
|
@ -428,7 +409,7 @@ void audio_init_recording(unsigned int buffer_offset)
|
||||||
void audio_close_recording(void)
|
void audio_close_recording(void)
|
||||||
{
|
{
|
||||||
logf("audio_close_recording");
|
logf("audio_close_recording");
|
||||||
pcm_thread_sync_post(PCMREC_CLOSE, NULL);
|
queue_send(&pcmrec_queue, PCMREC_CLOSE, NULL);
|
||||||
logf("audio_close_recording done");
|
logf("audio_close_recording done");
|
||||||
} /* audio_close_recording */
|
} /* audio_close_recording */
|
||||||
|
|
||||||
|
@ -438,7 +419,7 @@ void audio_close_recording(void)
|
||||||
void audio_set_recording_options(struct audio_recording_options *options)
|
void audio_set_recording_options(struct audio_recording_options *options)
|
||||||
{
|
{
|
||||||
logf("audio_set_recording_options");
|
logf("audio_set_recording_options");
|
||||||
pcm_thread_sync_post(PCMREC_OPTIONS, (void *)options);
|
queue_send(&pcmrec_queue, PCMREC_OPTIONS, (void *)options);
|
||||||
logf("audio_set_recording_options done");
|
logf("audio_set_recording_options done");
|
||||||
} /* audio_set_recording_options */
|
} /* audio_set_recording_options */
|
||||||
|
|
||||||
|
@ -448,7 +429,7 @@ void audio_set_recording_options(struct audio_recording_options *options)
|
||||||
void audio_record(const char *filename)
|
void audio_record(const char *filename)
|
||||||
{
|
{
|
||||||
logf("audio_record: %s", filename);
|
logf("audio_record: %s", filename);
|
||||||
pcm_thread_sync_post(PCMREC_START, (void *)filename);
|
queue_send(&pcmrec_queue, PCMREC_START, (void *)filename);
|
||||||
logf("audio_record_done");
|
logf("audio_record_done");
|
||||||
} /* audio_record */
|
} /* audio_record */
|
||||||
|
|
||||||
|
@ -458,7 +439,7 @@ void audio_record(const char *filename)
|
||||||
void audio_new_file(const char *filename)
|
void audio_new_file(const char *filename)
|
||||||
{
|
{
|
||||||
logf("audio_new_file: %s", filename);
|
logf("audio_new_file: %s", filename);
|
||||||
pcm_thread_sync_post(PCMREC_NEW_FILE, (void *)filename);
|
queue_send(&pcmrec_queue, PCMREC_NEW_FILE, (void *)filename);
|
||||||
logf("audio_new_file done");
|
logf("audio_new_file done");
|
||||||
} /* audio_new_file */
|
} /* audio_new_file */
|
||||||
|
|
||||||
|
@ -468,7 +449,7 @@ void audio_new_file(const char *filename)
|
||||||
void audio_stop_recording(void)
|
void audio_stop_recording(void)
|
||||||
{
|
{
|
||||||
logf("audio_stop_recording");
|
logf("audio_stop_recording");
|
||||||
pcm_thread_sync_post(PCMREC_STOP, NULL);
|
queue_send(&pcmrec_queue, PCMREC_STOP, NULL);
|
||||||
logf("audio_stop_recording done");
|
logf("audio_stop_recording done");
|
||||||
} /* audio_stop_recording */
|
} /* audio_stop_recording */
|
||||||
|
|
||||||
|
@ -478,7 +459,7 @@ void audio_stop_recording(void)
|
||||||
void audio_pause_recording(void)
|
void audio_pause_recording(void)
|
||||||
{
|
{
|
||||||
logf("audio_pause_recording");
|
logf("audio_pause_recording");
|
||||||
pcm_thread_sync_post(PCMREC_PAUSE, NULL);
|
queue_send(&pcmrec_queue, PCMREC_PAUSE, NULL);
|
||||||
logf("audio_pause_recording done");
|
logf("audio_pause_recording done");
|
||||||
} /* audio_pause_recording */
|
} /* audio_pause_recording */
|
||||||
|
|
||||||
|
@ -488,7 +469,7 @@ void audio_pause_recording(void)
|
||||||
void audio_resume_recording(void)
|
void audio_resume_recording(void)
|
||||||
{
|
{
|
||||||
logf("audio_resume_recording");
|
logf("audio_resume_recording");
|
||||||
pcm_thread_sync_post(PCMREC_RESUME, NULL);
|
queue_send(&pcmrec_queue, PCMREC_RESUME, NULL);
|
||||||
logf("audio_resume_recording done");
|
logf("audio_resume_recording done");
|
||||||
} /* audio_resume_recording */
|
} /* audio_resume_recording */
|
||||||
|
|
||||||
|
@ -1137,6 +1118,7 @@ static void pcmrec_init(void)
|
||||||
is_stopping = false;
|
is_stopping = false;
|
||||||
|
|
||||||
buffer = audio_get_recording_buffer(&rec_buffer_size);
|
buffer = audio_get_recording_buffer(&rec_buffer_size);
|
||||||
|
|
||||||
/* Line align pcm_buffer 2^4=16 bytes */
|
/* Line align pcm_buffer 2^4=16 bytes */
|
||||||
pcm_buffer = (unsigned char *)ALIGN_UP_P2((unsigned long)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 +
|
enc_buffer = pcm_buffer + ALIGN_UP_P2(PCM_NUM_CHUNKS*PCM_CHUNK_SIZE +
|
||||||
|
@ -1145,8 +1127,6 @@ static void pcmrec_init(void)
|
||||||
rec_buffer_size -= pcm_buffer - buffer;
|
rec_buffer_size -= pcm_buffer - buffer;
|
||||||
|
|
||||||
pcm_init_recording();
|
pcm_init_recording();
|
||||||
pcm_thread_unsignal_event(PCMREC_CLOSE);
|
|
||||||
pcm_thread_signal_event(PCMREC_INIT);
|
|
||||||
} /* pcmrec_init */
|
} /* pcmrec_init */
|
||||||
|
|
||||||
/* PCMREC_CLOSE */
|
/* PCMREC_CLOSE */
|
||||||
|
@ -1158,8 +1138,6 @@ static void pcmrec_close(void)
|
||||||
pcm_close_recording();
|
pcm_close_recording();
|
||||||
reset_hardware();
|
reset_hardware();
|
||||||
audio_remove_encoder();
|
audio_remove_encoder();
|
||||||
pcm_thread_unsignal_event(PCMREC_INIT);
|
|
||||||
pcm_thread_signal_event(PCMREC_CLOSE);
|
|
||||||
} /* pcmrec_close */
|
} /* pcmrec_close */
|
||||||
|
|
||||||
/* PCMREC_OPTIONS */
|
/* PCMREC_OPTIONS */
|
||||||
|
@ -1218,12 +1196,11 @@ static void pcmrec_set_recording_options(struct audio_recording_options *options
|
||||||
errors |= PCMREC_E_LOAD_ENCODER;
|
errors |= PCMREC_E_LOAD_ENCODER;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcm_thread_signal_event(PCMREC_OPTIONS);
|
|
||||||
} /* pcmrec_set_recording_options */
|
} /* pcmrec_set_recording_options */
|
||||||
|
|
||||||
/* PCMREC_START/PCMREC_NEW_FILE - start recording (not gapless)
|
/* PCMREC_START/PCMREC_NEW_FILE - start recording (not gapless)
|
||||||
or split stream (gapless) */
|
or split stream (gapless) */
|
||||||
static void pcmrec_start(int event, const char *filename)
|
static void pcmrec_start(const char *filename)
|
||||||
{
|
{
|
||||||
unsigned long pre_sample_ticks;
|
unsigned long pre_sample_ticks;
|
||||||
int rd_start;
|
int rd_start;
|
||||||
|
@ -1318,7 +1295,6 @@ static void pcmrec_start(int event, const char *filename)
|
||||||
enc_rd_index);
|
enc_rd_index);
|
||||||
|
|
||||||
start_done:
|
start_done:
|
||||||
pcm_thread_signal_event(event);
|
|
||||||
logf("pcmrec_start done");
|
logf("pcmrec_start done");
|
||||||
} /* pcmrec_start */
|
} /* pcmrec_start */
|
||||||
|
|
||||||
|
@ -1343,7 +1319,6 @@ static void pcmrec_stop(void)
|
||||||
queue_post(&pcmrec_queue, PCMREC_FINISH_STOP, NULL);
|
queue_post(&pcmrec_queue, PCMREC_FINISH_STOP, NULL);
|
||||||
|
|
||||||
not_recording_or_stopping:
|
not_recording_or_stopping:
|
||||||
pcm_thread_signal_event(PCMREC_STOP);
|
|
||||||
logf("pcmrec_stop done");
|
logf("pcmrec_stop done");
|
||||||
} /* pcmrec_stop */
|
} /* pcmrec_stop */
|
||||||
|
|
||||||
|
@ -1419,7 +1394,6 @@ static void pcmrec_pause(void)
|
||||||
is_paused = true;
|
is_paused = true;
|
||||||
|
|
||||||
not_recording_or_paused:
|
not_recording_or_paused:
|
||||||
pcm_thread_signal_event(PCMREC_PAUSE);
|
|
||||||
logf("pcmrec_pause done");
|
logf("pcmrec_pause done");
|
||||||
} /* pcmrec_pause */
|
} /* pcmrec_pause */
|
||||||
|
|
||||||
|
@ -1444,7 +1418,6 @@ static void pcmrec_resume(void)
|
||||||
dma_lock = false;
|
dma_lock = false;
|
||||||
|
|
||||||
not_recording_or_not_paused:
|
not_recording_or_not_paused:
|
||||||
pcm_thread_signal_event(PCMREC_RESUME);
|
|
||||||
logf("pcmrec_resume done");
|
logf("pcmrec_resume done");
|
||||||
} /* pcmrec_resume */
|
} /* pcmrec_resume */
|
||||||
|
|
||||||
|
@ -1491,7 +1464,7 @@ static void pcmrec_thread(void)
|
||||||
|
|
||||||
case PCMREC_START:
|
case PCMREC_START:
|
||||||
case PCMREC_NEW_FILE:
|
case PCMREC_NEW_FILE:
|
||||||
pcmrec_start(ev.id, (const char *)ev.data);
|
pcmrec_start((const char *)ev.data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCMREC_STOP:
|
case PCMREC_STOP:
|
||||||
|
@ -1509,11 +1482,11 @@ static void pcmrec_thread(void)
|
||||||
case PCMREC_RESUME:
|
case PCMREC_RESUME:
|
||||||
pcmrec_resume();
|
pcmrec_resume();
|
||||||
break;
|
break;
|
||||||
|
#if 0
|
||||||
case PCMREC_FLUSH_NUM:
|
case PCMREC_FLUSH_NUM:
|
||||||
pcmrec_flush((unsigned)ev.data);
|
pcmrec_flush((unsigned)ev.data);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case SYS_USB_CONNECTED:
|
case SYS_USB_CONNECTED:
|
||||||
if (is_recording)
|
if (is_recording)
|
||||||
break;
|
break;
|
||||||
|
@ -1523,6 +1496,8 @@ static void pcmrec_thread(void)
|
||||||
usb_wait_for_disconnect(&pcmrec_queue);
|
usb_wait_for_disconnect(&pcmrec_queue);
|
||||||
break;
|
break;
|
||||||
} /* end switch */
|
} /* end switch */
|
||||||
|
|
||||||
|
queue_reply(&pcmrec_queue, NULL);
|
||||||
} /* end while */
|
} /* end while */
|
||||||
} /* pcmrec_thread */
|
} /* pcmrec_thread */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue