mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-13 18:17:39 -04:00
pcmbuf: more refactoring
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23588 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
91d982a1b6
commit
5c69a42d51
2 changed files with 53 additions and 71 deletions
|
@ -448,7 +448,7 @@ static bool codec_load_next_track(void)
|
||||||
{
|
{
|
||||||
case Q_CODEC_REQUEST_COMPLETE:
|
case Q_CODEC_REQUEST_COMPLETE:
|
||||||
LOGFQUEUE("codec |< Q_CODEC_REQUEST_COMPLETE");
|
LOGFQUEUE("codec |< Q_CODEC_REQUEST_COMPLETE");
|
||||||
pcmbuf_start_track_change(!automatic_skip);
|
pcmbuf_start_track_change(automatic_skip);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Q_CODEC_REQUEST_FAILED:
|
case Q_CODEC_REQUEST_FAILED:
|
||||||
|
|
122
apps/pcmbuf.c
122
apps/pcmbuf.c
|
@ -92,7 +92,7 @@ static bool crossfade_enabled;
|
||||||
static bool crossfade_enable_request;
|
static bool crossfade_enable_request;
|
||||||
static bool crossfade_mixmode;
|
static bool crossfade_mixmode;
|
||||||
static bool crossfade_active IDATA_ATTR;
|
static bool crossfade_active IDATA_ATTR;
|
||||||
static bool crossfade_init IDATA_ATTR;
|
static bool crossfade_track_change_started IDATA_ATTR;
|
||||||
|
|
||||||
/* Track the current location for processing crossfade */
|
/* Track the current location for processing crossfade */
|
||||||
static struct chunkdesc *crossfade_chunk IDATA_ATTR;
|
static struct chunkdesc *crossfade_chunk IDATA_ATTR;
|
||||||
|
@ -132,12 +132,11 @@ extern unsigned int codec_thread_id;
|
||||||
#define LOW_DATA(quarter_secs) \
|
#define LOW_DATA(quarter_secs) \
|
||||||
(pcmbuf_unplayed_bytes < NATIVE_FREQUENCY * quarter_secs)
|
(pcmbuf_unplayed_bytes < NATIVE_FREQUENCY * quarter_secs)
|
||||||
|
|
||||||
static void pcmbuf_finish_track_change(void);
|
static void finish_gapless_track_change(void);
|
||||||
#ifdef HAVE_CROSSFADE
|
#ifdef HAVE_CROSSFADE
|
||||||
static void crossfade_start(void);
|
static void crossfade_start(void);
|
||||||
static void flush_crossfade(char *buf, size_t length);
|
static void flush_crossfade(char *buf, size_t length);
|
||||||
#endif
|
#endif
|
||||||
static bool pcmbuf_crossfade_init(bool manual_skip);
|
|
||||||
static void pcmbuf_finish_crossfade_enable(void);
|
static void pcmbuf_finish_crossfade_enable(void);
|
||||||
static bool pcmbuf_is_crossfade_enabled(void);
|
static bool pcmbuf_is_crossfade_enabled(void);
|
||||||
|
|
||||||
|
@ -348,7 +347,7 @@ static bool prepare_insert(size_t length)
|
||||||
void *pcmbuf_request_buffer(int *count)
|
void *pcmbuf_request_buffer(int *count)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_CROSSFADE
|
#ifdef HAVE_CROSSFADE
|
||||||
if (crossfade_init)
|
if (crossfade_track_change_started)
|
||||||
crossfade_start();
|
crossfade_start();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -401,7 +400,7 @@ void pcmbuf_write_complete(int count)
|
||||||
|
|
||||||
/* Init */
|
/* Init */
|
||||||
|
|
||||||
static void pcmbuf_init_pcmbuffers(void)
|
static inline void init_pcmbuffers(void)
|
||||||
{
|
{
|
||||||
#ifdef DESC_DEBUG
|
#ifdef DESC_DEBUG
|
||||||
first_desc = write_chunk;
|
first_desc = write_chunk;
|
||||||
|
@ -417,7 +416,7 @@ static void pcmbuf_init_pcmbuffers(void)
|
||||||
DISPLAY_DESC("init");
|
DISPLAY_DESC("init");
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t pcmbuf_get_next_required_pcmbuf_size(void)
|
static size_t get_next_required_pcmbuf_size(void)
|
||||||
{
|
{
|
||||||
size_t seconds = 1;
|
size_t seconds = 1;
|
||||||
|
|
||||||
|
@ -444,13 +443,13 @@ static char *pcmbuf_calc_pcmbuffer_ptr(size_t bufsize)
|
||||||
size_t pcmbuf_init(unsigned char *bufend)
|
size_t pcmbuf_init(unsigned char *bufend)
|
||||||
{
|
{
|
||||||
pcmbuf_bufend = bufend;
|
pcmbuf_bufend = bufend;
|
||||||
pcmbuf_size = pcmbuf_get_next_required_pcmbuf_size();
|
pcmbuf_size = get_next_required_pcmbuf_size();
|
||||||
pcmbuffer = pcmbuf_calc_pcmbuffer_ptr(pcmbuf_size);
|
pcmbuffer = pcmbuf_calc_pcmbuffer_ptr(pcmbuf_size);
|
||||||
fadebuf = &pcmbuffer[pcmbuf_size];
|
fadebuf = &pcmbuffer[pcmbuf_size];
|
||||||
voicebuf = &fadebuf[PCMBUF_MIX_CHUNK];
|
voicebuf = &fadebuf[PCMBUF_MIX_CHUNK];
|
||||||
write_chunk = (struct chunkdesc *)&voicebuf[PCMBUF_MIX_CHUNK];
|
write_chunk = (struct chunkdesc *)&voicebuf[PCMBUF_MIX_CHUNK];
|
||||||
|
|
||||||
pcmbuf_init_pcmbuffers();
|
init_pcmbuffers();
|
||||||
|
|
||||||
if(track_transition){logf("pcmbuf: (init) track transition false");}
|
if(track_transition){logf("pcmbuf: (init) track transition false");}
|
||||||
end_of_track = false;
|
end_of_track = false;
|
||||||
|
@ -488,7 +487,7 @@ static void pcmbuf_pcm_callback(unsigned char** start, size_t* size)
|
||||||
|
|
||||||
/* if last buffer in the track, let the audio thread know */
|
/* if last buffer in the track, let the audio thread know */
|
||||||
if (pcmbuf_current->end_of_track)
|
if (pcmbuf_current->end_of_track)
|
||||||
pcmbuf_finish_track_change();
|
finish_gapless_track_change();
|
||||||
|
|
||||||
/* Put the finished buffer back into circulation */
|
/* Put the finished buffer back into circulation */
|
||||||
write_end_chunk->link = pcmbuf_current;
|
write_end_chunk->link = pcmbuf_current;
|
||||||
|
@ -532,7 +531,7 @@ static void pcmbuf_pcm_callback(unsigned char** start, size_t* size)
|
||||||
*realsize = 0;
|
*realsize = 0;
|
||||||
*realstart = NULL;
|
*realstart = NULL;
|
||||||
if (end_of_track)
|
if (end_of_track)
|
||||||
pcmbuf_finish_track_change();
|
finish_gapless_track_change();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DISPLAY_DESC("callback");
|
DISPLAY_DESC("callback");
|
||||||
|
@ -563,7 +562,7 @@ void pcmbuf_play_stop(void)
|
||||||
}
|
}
|
||||||
pcmbuffer_pos = 0;
|
pcmbuffer_pos = 0;
|
||||||
pcmbuffer_fillpos = 0;
|
pcmbuffer_fillpos = 0;
|
||||||
crossfade_init = false;
|
crossfade_track_change_started = false;
|
||||||
crossfade_active = false;
|
crossfade_active = false;
|
||||||
flush_pcmbuf = false;
|
flush_pcmbuf = false;
|
||||||
DISPLAY_DESC("play_stop");
|
DISPLAY_DESC("play_stop");
|
||||||
|
@ -587,7 +586,7 @@ void pcmbuf_pause(bool pause)
|
||||||
* still playing. Set flags to make sure the elapsed time of the current
|
* still playing. Set flags to make sure the elapsed time of the current
|
||||||
* track is updated properly, and mark the currently written chunk as the
|
* track is updated properly, and mark the currently written chunk as the
|
||||||
* last one in the track. */
|
* last one in the track. */
|
||||||
static void pcmbuf_gapless_track_change(void)
|
static void start_gapless_track_change(void)
|
||||||
{
|
{
|
||||||
/* we're starting a track transition */
|
/* we're starting a track transition */
|
||||||
track_transition = true;
|
track_transition = true;
|
||||||
|
@ -596,22 +595,42 @@ static void pcmbuf_gapless_track_change(void)
|
||||||
end_of_track = true;
|
end_of_track = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcmbuf_crossfade_track_change(void)
|
static void start_crossfade_track_change(bool auto_skip)
|
||||||
{
|
{
|
||||||
/* Initiate automatic crossfade mode */
|
|
||||||
pcmbuf_crossfade_init(false);
|
|
||||||
/* Notify the wps that the track change starts now */
|
/* Notify the wps that the track change starts now */
|
||||||
audio_post_track_change(false);
|
audio_post_track_change(false);
|
||||||
|
|
||||||
|
/* Can't do two crossfades at once and, no fade if pcm is off now */
|
||||||
|
if (pcmbuf_is_crossfade_active() || !pcm_is_playing())
|
||||||
|
{
|
||||||
|
pcmbuf_play_stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
trigger_cpu_boost();
|
||||||
|
|
||||||
|
/* Not enough data, or crossfade disabled, flush the old data instead */
|
||||||
|
if (LOW_DATA(2) || !pcmbuf_is_crossfade_enabled() || low_latency_mode)
|
||||||
|
{
|
||||||
|
/* commit everything to this point and keep going, but... */
|
||||||
|
commit_chunk();
|
||||||
|
/* ... when the next chunk commits, throw away everything but itself */
|
||||||
|
flush_pcmbuf = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't enable mix mode when skipping tracks manually. */
|
||||||
|
crossfade_mixmode = auto_skip && global_settings.crossfade_fade_out_mixmode;
|
||||||
|
|
||||||
|
crossfade_track_change_started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcmbuf_start_track_change(bool manual_skip)
|
void pcmbuf_start_track_change(bool auto_skip)
|
||||||
{
|
{
|
||||||
/* Manual track change (always crossfade or flush audio). */
|
/* Manual track change (always crossfade or flush audio). */
|
||||||
if (manual_skip)
|
if (!auto_skip)
|
||||||
{
|
start_crossfade_track_change(false);
|
||||||
pcmbuf_crossfade_init(true);
|
|
||||||
audio_post_track_change(false);
|
|
||||||
}
|
|
||||||
/* Automatic track change w/crossfade, if not in "Track Skip Only" mode. */
|
/* Automatic track change w/crossfade, if not in "Track Skip Only" mode. */
|
||||||
else if (pcmbuf_is_crossfade_enabled() && !pcmbuf_is_crossfade_active()
|
else if (pcmbuf_is_crossfade_enabled() && !pcmbuf_is_crossfade_active()
|
||||||
&& global_settings.crossfade != CROSSFADE_ENABLE_TRACKSKIP)
|
&& global_settings.crossfade != CROSSFADE_ENABLE_TRACKSKIP)
|
||||||
|
@ -620,22 +639,22 @@ void pcmbuf_start_track_change(bool manual_skip)
|
||||||
{
|
{
|
||||||
if (global_settings.playlist_shuffle)
|
if (global_settings.playlist_shuffle)
|
||||||
/* shuffle mode is on, so crossfade: */
|
/* shuffle mode is on, so crossfade: */
|
||||||
pcmbuf_crossfade_track_change();
|
start_crossfade_track_change(true);
|
||||||
else
|
else
|
||||||
/* shuffle mode is off, so normal gapless playback */
|
/* shuffle mode is off, so normal gapless playback */
|
||||||
pcmbuf_gapless_track_change();
|
start_gapless_track_change();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* normal crossfade: */
|
/* normal crossfade: */
|
||||||
pcmbuf_crossfade_track_change();
|
start_crossfade_track_change(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* normal gapless playback. */
|
/* normal gapless playback. */
|
||||||
pcmbuf_gapless_track_change();
|
start_gapless_track_change();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when the last chunk in the track has been played */
|
/* Called when the last chunk in the track has been played */
|
||||||
static void pcmbuf_finish_track_change(void)
|
static void finish_gapless_track_change(void)
|
||||||
{
|
{
|
||||||
/* not in a track transition anymore */
|
/* not in a track transition anymore */
|
||||||
if(track_transition){logf("pcmbuf: (finish change) track transition false");}
|
if(track_transition){logf("pcmbuf: (finish change) track transition false");}
|
||||||
|
@ -732,7 +751,7 @@ static void crossfade_start(void)
|
||||||
size_t fade_out_delay;
|
size_t fade_out_delay;
|
||||||
size_t fade_in_delay;
|
size_t fade_in_delay;
|
||||||
|
|
||||||
crossfade_init = false;
|
crossfade_track_change_started = false;
|
||||||
/* Reject crossfade if less than .5s of data */
|
/* Reject crossfade if less than .5s of data */
|
||||||
if (LOW_DATA(2)) {
|
if (LOW_DATA(2)) {
|
||||||
logf("crossfade rejected");
|
logf("crossfade rejected");
|
||||||
|
@ -900,37 +919,6 @@ static void flush_crossfade(char *buf, size_t length)
|
||||||
}
|
}
|
||||||
#endif /* HAVE_CROSSFADE */
|
#endif /* HAVE_CROSSFADE */
|
||||||
|
|
||||||
static bool pcmbuf_crossfade_init(bool manual_skip)
|
|
||||||
{
|
|
||||||
/* Can't do two crossfades at once and, no fade if pcm is off now */
|
|
||||||
if (crossfade_init || crossfade_active || !pcm_is_playing())
|
|
||||||
{
|
|
||||||
pcmbuf_play_stop();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
trigger_cpu_boost();
|
|
||||||
|
|
||||||
/* Not enough data, or crossfade disabled, flush the old data instead */
|
|
||||||
if (LOW_DATA(2) || !pcmbuf_is_crossfade_enabled() || low_latency_mode)
|
|
||||||
{
|
|
||||||
commit_chunk();
|
|
||||||
flush_pcmbuf = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Don't enable mix mode when skipping tracks manually. */
|
|
||||||
if (manual_skip)
|
|
||||||
crossfade_mixmode = false;
|
|
||||||
else
|
|
||||||
crossfade_mixmode = global_settings.crossfade_fade_out_mixmode;
|
|
||||||
|
|
||||||
crossfade_init = true;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pcmbuf_finish_crossfade_enable(void)
|
static void pcmbuf_finish_crossfade_enable(void)
|
||||||
{
|
{
|
||||||
/* Copy the pending setting over now */
|
/* Copy the pending setting over now */
|
||||||
|
@ -953,7 +941,7 @@ static bool pcmbuf_is_crossfade_enabled(void)
|
||||||
|
|
||||||
bool pcmbuf_is_crossfade_active(void)
|
bool pcmbuf_is_crossfade_active(void)
|
||||||
{
|
{
|
||||||
return crossfade_active || crossfade_init;
|
return crossfade_active || crossfade_track_change_started;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcmbuf_request_crossfade_enable(bool on_off)
|
void pcmbuf_request_crossfade_enable(bool on_off)
|
||||||
|
@ -964,16 +952,11 @@ void pcmbuf_request_crossfade_enable(bool on_off)
|
||||||
|
|
||||||
bool pcmbuf_is_same_size(void)
|
bool pcmbuf_is_same_size(void)
|
||||||
{
|
{
|
||||||
bool same_size;
|
/* if pcmbuffer is NULL, then not set up yet even once so always */
|
||||||
|
bool same_size = pcmbuffer ?
|
||||||
if (pcmbuffer == NULL)
|
(get_next_required_pcmbuf_size() == pcmbuf_size) : true;
|
||||||
same_size = true; /* Not set up yet even once so always */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t bufsize = pcmbuf_get_next_required_pcmbuf_size();
|
|
||||||
same_size = pcmbuf_calc_pcmbuffer_ptr(bufsize) == pcmbuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* no buffer change needed, so finish crossfade setup now */
|
||||||
if (same_size)
|
if (same_size)
|
||||||
pcmbuf_finish_crossfade_enable();
|
pcmbuf_finish_crossfade_enable();
|
||||||
|
|
||||||
|
@ -1128,8 +1111,7 @@ unsigned char * pcmbuf_get_meminfo(size_t *length)
|
||||||
|
|
||||||
bool pcmbuf_is_lowdata(void)
|
bool pcmbuf_is_lowdata(void)
|
||||||
{
|
{
|
||||||
if (!pcm_is_playing() || pcm_is_paused() ||
|
if (!pcm_is_playing() || pcm_is_paused() || pcmbuf_is_crossfade_active())
|
||||||
crossfade_init || crossfade_active)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#if MEMORYSIZE > 2
|
#if MEMORYSIZE > 2
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue