More work on swcodec. No significant pcmbuf functions are called from the audio thread now. Do not be surprised if seek or skip behavior gets weird after this, but it Works for Me (TM), and is a significant step in the right direction.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9510 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
4ff8744e55
commit
33a62e8a8e
5 changed files with 29 additions and 45 deletions
|
@ -111,13 +111,13 @@ reasonable amount of time for the typical user to react */
|
|||
|
||||
void ab_jump_to_A_marker(void)
|
||||
{
|
||||
#if (CONFIG_CODEC == SWCODEC)
|
||||
audio_seamless_seek(ab_A_marker);
|
||||
#else
|
||||
#if (CONFIG_CODEC != SWCODEC)
|
||||
bool paused = (audio_status() & AUDIO_STATUS_PAUSE) != 0;
|
||||
if ( ! paused )
|
||||
audio_pause();
|
||||
#endif
|
||||
audio_ff_rewind(ab_A_marker);
|
||||
#if (CONFIG_CODEC != SWCODEC)
|
||||
if ( ! paused )
|
||||
audio_resume();
|
||||
#endif
|
||||
|
|
|
@ -61,8 +61,6 @@ static bool crossfade_init IDATA_ATTR;
|
|||
static size_t crossfade_pos IDATA_ATTR;
|
||||
static size_t crossfade_rem IDATA_ATTR;
|
||||
|
||||
static struct mutex pcmbuf_mutex IDATA_ATTR;
|
||||
|
||||
/* Crossfade modes. If CFM_CROSSFADE is selected, normal
|
||||
* crossfader will activate. Selecting CFM_FLUSH is a special
|
||||
* operation that only overwrites the pcm buffer without crossfading.
|
||||
|
@ -297,7 +295,6 @@ bool pcmbuf_crossfade_init(bool manual_skip)
|
|||
|
||||
void pcmbuf_play_stop(void)
|
||||
{
|
||||
mutex_lock(&pcmbuf_mutex);
|
||||
/** Prevent a very tiny pop from happening by muting audio
|
||||
* until dma has been initialized. */
|
||||
pcm_mute(true);
|
||||
|
@ -320,7 +317,6 @@ void pcmbuf_play_stop(void)
|
|||
pcmbuf_set_boost_mode(false);
|
||||
pcmbuf_boost(false);
|
||||
|
||||
mutex_unlock(&pcmbuf_mutex);
|
||||
}
|
||||
|
||||
int pcmbuf_used_descs(void) {
|
||||
|
@ -356,7 +352,6 @@ static void pcmbuf_init_pcmbuffers(void) {
|
|||
* ...CODECBUFFER|---------PCMBUF---------|GUARDBUF|DESCS| */
|
||||
void pcmbuf_init(size_t bufsize)
|
||||
{
|
||||
mutex_init(&pcmbuf_mutex);
|
||||
pcmbuf_size = bufsize;
|
||||
pcmbuf_descsize = pcmbuf_descs()*sizeof(struct pcmbufdesc);
|
||||
audiobuffer = (char *)&audiobuf[(audiobufend - audiobuf) -
|
||||
|
@ -401,8 +396,6 @@ void pcmbuf_pause(bool pause) {
|
|||
/* Force playback. */
|
||||
void pcmbuf_play_start(void)
|
||||
{
|
||||
mutex_lock(&pcmbuf_mutex);
|
||||
|
||||
if (!pcm_is_playing() && pcmbuf_unplayed_bytes)
|
||||
{
|
||||
/** Prevent a very tiny pop from happening by muting audio
|
||||
|
@ -417,8 +410,6 @@ void pcmbuf_play_start(void)
|
|||
/* Now unmute the audio. */
|
||||
pcm_mute(false);
|
||||
}
|
||||
|
||||
mutex_unlock(&pcmbuf_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -426,8 +417,6 @@ void pcmbuf_play_start(void)
|
|||
*/
|
||||
static void pcmbuf_flush_fillpos(void)
|
||||
{
|
||||
mutex_lock(&pcmbuf_mutex);
|
||||
|
||||
if (audiobuffer_fillpos) {
|
||||
/* Never use the last buffer descriptor */
|
||||
while (pcmbuf_write == pcmbuf_write_end) {
|
||||
|
@ -444,8 +433,6 @@ static void pcmbuf_flush_fillpos(void)
|
|||
}
|
||||
pcmbuf_add_chunk();
|
||||
}
|
||||
|
||||
mutex_unlock(&pcmbuf_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
static volatile bool audio_codec_loaded;
|
||||
static volatile bool voice_codec_loaded;
|
||||
static volatile bool playing;
|
||||
static volatile bool seeking;
|
||||
|
||||
#define CODEC_VORBIS "/.rockbox/codecs/vorbis.codec"
|
||||
#define CODEC_MPA_L3 "/.rockbox/codecs/mpa.codec"
|
||||
|
@ -102,7 +103,6 @@ enum {
|
|||
Q_AUDIO_TRACK_CHANGED,
|
||||
Q_AUDIO_DIR_NEXT,
|
||||
Q_AUDIO_DIR_PREV,
|
||||
Q_AUDIO_SEAMLESS_SEEK,
|
||||
Q_AUDIO_POSTINIT,
|
||||
|
||||
Q_CODEC_LOAD,
|
||||
|
@ -679,7 +679,12 @@ off_t codec_mp3_get_filepos_callback(int newtime)
|
|||
void codec_seek_complete_callback(void)
|
||||
{
|
||||
/* assume we're called from non-voice codec, as they shouldn't seek */
|
||||
if (pcm_is_paused()) {
|
||||
/* If this is not a seamless seek, clear the buffer */
|
||||
pcmbuf_play_stop();
|
||||
}
|
||||
ci.seek_time = 0;
|
||||
seeking = false;
|
||||
}
|
||||
|
||||
bool codec_seek_buffer_callback(size_t newpos)
|
||||
|
@ -1329,10 +1334,10 @@ static void audio_clear_track_entries(bool buffered_only)
|
|||
static void stop_codec_flush(void)
|
||||
{
|
||||
ci.stop_codec = true;
|
||||
pcmbuf_play_stop();
|
||||
pcmbuf_pause(true);
|
||||
while (audio_codec_loaded)
|
||||
yield();
|
||||
pcmbuf_play_stop();
|
||||
pcmbuf_pause(false);
|
||||
}
|
||||
|
||||
static void audio_stop_playback(bool resume)
|
||||
|
@ -1343,7 +1348,6 @@ static void audio_stop_playback(bool resume)
|
|||
playing = false;
|
||||
filling = false;
|
||||
stop_codec_flush();
|
||||
pcmbuf_pause(false);
|
||||
if (current_fd >= 0) {
|
||||
close(current_fd);
|
||||
current_fd = -1;
|
||||
|
@ -1768,11 +1772,11 @@ static void initiate_track_change(int peek_index)
|
|||
{
|
||||
/* Detect if disk is spinning or already loading. */
|
||||
if (filling || ci.reload_codec || !audio_codec_loaded) {
|
||||
if (pcmbuf_is_crossfade_enabled())
|
||||
if (pcmbuf_is_crossfade_enabled()) {
|
||||
pcmbuf_crossfade_init(true);
|
||||
else
|
||||
pcmbuf_play_stop();
|
||||
ci.stop_codec = true;
|
||||
ci.stop_codec = true;
|
||||
} else
|
||||
stop_codec_flush();
|
||||
queue_post(&audio_queue, Q_AUDIO_PLAY, 0);
|
||||
} else {
|
||||
new_track = peek_index;
|
||||
|
@ -1836,10 +1840,6 @@ void audio_thread(void)
|
|||
play_pending = false;
|
||||
last_tick = current_tick;
|
||||
|
||||
/* Do not start crossfading if audio is paused. */
|
||||
if (pcm_is_paused())
|
||||
pcmbuf_play_stop();
|
||||
|
||||
#ifdef CONFIG_TUNER
|
||||
/* check if radio is playing */
|
||||
if (get_radio_status() != FMRADIO_OFF) {
|
||||
|
@ -1848,6 +1848,7 @@ void audio_thread(void)
|
|||
#endif
|
||||
|
||||
logf("starting...");
|
||||
|
||||
playing = true;
|
||||
ci.stop_codec = true;
|
||||
ci.reload_codec = false;
|
||||
|
@ -1896,13 +1897,6 @@ void audio_thread(void)
|
|||
break;
|
||||
|
||||
case Q_AUDIO_FF_REWIND:
|
||||
if (!playing)
|
||||
break ;
|
||||
pcmbuf_play_stop();
|
||||
ci.seek_time = (long)ev.data+1;
|
||||
break ;
|
||||
|
||||
case Q_AUDIO_SEAMLESS_SEEK:
|
||||
if (!playing)
|
||||
break ;
|
||||
ci.seek_time = (long)ev.data+1;
|
||||
|
@ -1911,6 +1905,7 @@ void audio_thread(void)
|
|||
case Q_AUDIO_DIR_NEXT:
|
||||
logf("audio_dir_next");
|
||||
playlist_end = false;
|
||||
/* pcmbuf_beep may or may not be safe on audio thread */
|
||||
if (global_settings.beep)
|
||||
pcmbuf_beep(5000, 100, 2500*global_settings.beep);
|
||||
initiate_dir_change(1);
|
||||
|
@ -1919,6 +1914,7 @@ void audio_thread(void)
|
|||
case Q_AUDIO_DIR_PREV:
|
||||
logf("audio_dir_prev");
|
||||
playlist_end = false;
|
||||
/* pcmbuf_beep may or may not be safe on audio thread */
|
||||
if (global_settings.beep)
|
||||
pcmbuf_beep(5000, 100, 2500*global_settings.beep);
|
||||
initiate_dir_change(-1);
|
||||
|
@ -2010,6 +2006,9 @@ void codec_thread(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
if (ci.stop_codec && pcm_is_paused())
|
||||
pcmbuf_play_stop();
|
||||
|
||||
audio_codec_loaded = false;
|
||||
|
||||
switch (ev.id) {
|
||||
|
@ -2191,7 +2190,6 @@ void audio_play(long offset)
|
|||
else
|
||||
{
|
||||
stop_codec_flush();
|
||||
pcmbuf_play_stop();
|
||||
}
|
||||
|
||||
queue_post(&audio_queue, Q_AUDIO_PLAY, (void *)offset);
|
||||
|
@ -2268,14 +2266,14 @@ void audio_prev_dir(void)
|
|||
|
||||
void audio_ff_rewind(long newpos)
|
||||
{
|
||||
logf("rewind: %d", newpos);
|
||||
logf("ff/rewind: %d", newpos);
|
||||
seeking = true;
|
||||
queue_post(&audio_queue, Q_AUDIO_FF_REWIND, (int *)newpos);
|
||||
}
|
||||
|
||||
void audio_seamless_seek(long newpos)
|
||||
{
|
||||
logf("seamless_seek: %d", newpos);
|
||||
queue_post(&audio_queue, Q_AUDIO_SEAMLESS_SEEK, (int *)newpos);
|
||||
/* This is a hack, the correct solution is to report back to
|
||||
* the caller when the seek is complete. */
|
||||
while (seeking) {
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
||||
void audio_flush_and_reload_tracks(void)
|
||||
|
|
|
@ -71,7 +71,6 @@ void audio_next(void);
|
|||
void audio_prev(void);
|
||||
int audio_status(void);
|
||||
void audio_ff_rewind(long newtime);
|
||||
void audio_seamless_seek(long newtime);
|
||||
void audio_flush_and_reload_tracks(void);
|
||||
struct mp3entry* audio_current_track(void);
|
||||
struct mp3entry* audio_next_track(void);
|
||||
|
|
|
@ -638,7 +638,7 @@ void pcm_play_pause(bool play)
|
|||
/* nothing yet */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} /* pcm_playing && needs_change */
|
||||
}
|
||||
|
||||
bool pcm_is_playing(void) {
|
||||
|
|
Loading…
Reference in a new issue