pcmbuf: clarify and simplify crossfade code, etc.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23538 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
013fe35992
commit
04b01e1831
5 changed files with 180 additions and 181 deletions
|
@ -416,47 +416,7 @@ void codec_init_codec_api(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** track change functions */
|
/* track change */
|
||||||
|
|
||||||
static inline void codec_crossfade_track_change(void)
|
|
||||||
{
|
|
||||||
/* Initiate automatic crossfade mode */
|
|
||||||
pcmbuf_crossfade_init(false);
|
|
||||||
/* Notify the wps that the track change starts now */
|
|
||||||
LOGFQUEUE("codec > audio Q_AUDIO_TRACK_CHANGED");
|
|
||||||
queue_post(&audio_queue, Q_AUDIO_TRACK_CHANGED, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void codec_track_skip_done(bool was_manual)
|
|
||||||
{
|
|
||||||
/* Manual track change (always crossfade or flush audio). */
|
|
||||||
if (was_manual)
|
|
||||||
{
|
|
||||||
pcmbuf_crossfade_init(true);
|
|
||||||
LOGFQUEUE("codec > audio Q_AUDIO_TRACK_CHANGED");
|
|
||||||
queue_post(&audio_queue, Q_AUDIO_TRACK_CHANGED, 0);
|
|
||||||
}
|
|
||||||
/* Automatic track change w/crossfade, if not in "Track Skip Only" mode. */
|
|
||||||
else if (pcmbuf_is_crossfade_enabled() && !pcmbuf_is_crossfade_active()
|
|
||||||
&& global_settings.crossfade != CROSSFADE_ENABLE_TRACKSKIP)
|
|
||||||
{
|
|
||||||
if (global_settings.crossfade == CROSSFADE_ENABLE_SHUFFLE_AND_TRACKSKIP)
|
|
||||||
{
|
|
||||||
if (global_settings.playlist_shuffle)
|
|
||||||
/* shuffle mode is on, so crossfade: */
|
|
||||||
codec_crossfade_track_change();
|
|
||||||
else
|
|
||||||
/* shuffle mode is off, so normal gapless playback */
|
|
||||||
pcmbuf_start_track_change();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/* normal crossfade: */
|
|
||||||
codec_crossfade_track_change();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/* normal gapless playback. */
|
|
||||||
pcmbuf_start_track_change();
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool codec_load_next_track(void)
|
static bool codec_load_next_track(void)
|
||||||
{
|
{
|
||||||
|
@ -487,7 +447,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");
|
||||||
codec_track_skip_done(!automatic_skip);
|
pcmbuf_start_track_change(!automatic_skip);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Q_CODEC_REQUEST_FAILED:
|
case Q_CODEC_REQUEST_FAILED:
|
||||||
|
|
210
apps/pcmbuf.c
210
apps/pcmbuf.c
|
@ -49,6 +49,17 @@ static inline int32_t clip_sample_16(int32_t sample)
|
||||||
return sample;
|
return sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PCMBUF_TARGET_CHUNK 32768 /* This is the target fill size of chunks
|
||||||
|
on the pcm buffer */
|
||||||
|
#define PCMBUF_MINAVG_CHUNK 24576 /* This is the minimum average size of
|
||||||
|
chunks on the pcm buffer (or we run out
|
||||||
|
of buffer descriptors, which is
|
||||||
|
non-fatal) */
|
||||||
|
#define PCMBUF_MIN_CHUNK 4096 /* We try to never feed a chunk smaller than
|
||||||
|
this to the DMA */
|
||||||
|
#define PCMBUF_MIX_CHUNK 8192 /* This is the maximum size of one packet
|
||||||
|
for mixing (crossfade or voice) */
|
||||||
|
|
||||||
#if MEMORYSIZE > 2
|
#if MEMORYSIZE > 2
|
||||||
/* Keep watermark high for iPods at least (2s) */
|
/* Keep watermark high for iPods at least (2s) */
|
||||||
#define PCMBUF_WATERMARK (NATIVE_FREQUENCY * 4 * 2)
|
#define PCMBUF_WATERMARK (NATIVE_FREQUENCY * 4 * 2)
|
||||||
|
@ -135,6 +146,10 @@ static bool prepare_insert(size_t length);
|
||||||
static void pcmbuf_under_watermark(bool under);
|
static void pcmbuf_under_watermark(bool under);
|
||||||
static bool pcmbuf_flush_fillpos(void);
|
static bool pcmbuf_flush_fillpos(void);
|
||||||
|
|
||||||
|
static bool pcmbuf_crossfade_init(bool manual_skip);
|
||||||
|
static bool pcmbuf_is_crossfade_enabled(void);
|
||||||
|
static void pcmbuf_finish_crossfade_enable(void);
|
||||||
|
|
||||||
|
|
||||||
/**************************************/
|
/**************************************/
|
||||||
|
|
||||||
|
@ -181,7 +196,7 @@ static bool show_desc(char *caller)
|
||||||
* 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. */
|
||||||
void pcmbuf_start_track_change(void)
|
static void pcmbuf_gapless_track_change(void)
|
||||||
{
|
{
|
||||||
/* we're starting a track transition */
|
/* we're starting a track transition */
|
||||||
track_transition = true;
|
track_transition = true;
|
||||||
|
@ -190,6 +205,44 @@ void pcmbuf_start_track_change(void)
|
||||||
end_of_track = true;
|
end_of_track = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pcmbuf_crossfade_track_change(void)
|
||||||
|
{
|
||||||
|
/* Initiate automatic crossfade mode */
|
||||||
|
pcmbuf_crossfade_init(false);
|
||||||
|
/* Notify the wps that the track change starts now */
|
||||||
|
audio_post_track_change(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pcmbuf_start_track_change(bool manual_skip)
|
||||||
|
{
|
||||||
|
/* Manual track change (always crossfade or flush audio). */
|
||||||
|
if (manual_skip)
|
||||||
|
{
|
||||||
|
pcmbuf_crossfade_init(true);
|
||||||
|
audio_post_track_change(false);
|
||||||
|
}
|
||||||
|
/* Automatic track change w/crossfade, if not in "Track Skip Only" mode. */
|
||||||
|
else if (pcmbuf_is_crossfade_enabled() && !pcmbuf_is_crossfade_active()
|
||||||
|
&& global_settings.crossfade != CROSSFADE_ENABLE_TRACKSKIP)
|
||||||
|
{
|
||||||
|
if (global_settings.crossfade == CROSSFADE_ENABLE_SHUFFLE_AND_TRACKSKIP)
|
||||||
|
{
|
||||||
|
if (global_settings.playlist_shuffle)
|
||||||
|
/* shuffle mode is on, so crossfade: */
|
||||||
|
pcmbuf_crossfade_track_change();
|
||||||
|
else
|
||||||
|
/* shuffle mode is off, so normal gapless playback */
|
||||||
|
pcmbuf_gapless_track_change();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* normal crossfade: */
|
||||||
|
pcmbuf_crossfade_track_change();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* normal gapless playback. */
|
||||||
|
pcmbuf_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 pcmbuf_finish_track_change(void)
|
||||||
{
|
{
|
||||||
|
@ -198,7 +251,7 @@ static void pcmbuf_finish_track_change(void)
|
||||||
track_transition = false;
|
track_transition = false;
|
||||||
|
|
||||||
/* notify playback that the track has just finished */
|
/* notify playback that the track has just finished */
|
||||||
audio_post_track_change();
|
audio_post_track_change(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -274,15 +327,6 @@ static void pcmbuf_pcm_callback(unsigned char** start, size_t* size)
|
||||||
DISPLAY_DESC("callback");
|
DISPLAY_DESC("callback");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcmbuf_set_watermark_bytes(void)
|
|
||||||
{
|
|
||||||
pcmbuf_watermark = (crossfade_enabled && pcmbuf_size) ?
|
|
||||||
/* If crossfading, try to keep the buffer full other than 1 second */
|
|
||||||
(pcmbuf_size - (NATIVE_FREQUENCY * 4 * 1)) :
|
|
||||||
/* Otherwise, just use the default */
|
|
||||||
PCMBUF_WATERMARK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is really just part of pcmbuf_flush_fillpos, but is easier to keep
|
/* This is really just part of pcmbuf_flush_fillpos, but is easier to keep
|
||||||
* in a separate function for the moment */
|
* in a separate function for the moment */
|
||||||
static inline void pcmbuf_add_chunk(void)
|
static inline void pcmbuf_add_chunk(void)
|
||||||
|
@ -330,6 +374,28 @@ static inline void pcmbuf_add_chunk(void)
|
||||||
DISPLAY_DESC("add_chunk");
|
DISPLAY_DESC("add_chunk");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commit samples waiting to the pcm buffer.
|
||||||
|
*/
|
||||||
|
static bool pcmbuf_flush_fillpos(void)
|
||||||
|
{
|
||||||
|
if (audiobuffer_fillpos) {
|
||||||
|
/* Never use the last buffer descriptor */
|
||||||
|
while (pcmbuf_write == pcmbuf_write_end) {
|
||||||
|
/* If this happens, something is being stupid */
|
||||||
|
if (!pcm_is_playing()) {
|
||||||
|
logf("pcmbuf_flush_fillpos error");
|
||||||
|
pcmbuf_play_start();
|
||||||
|
}
|
||||||
|
/* Let approximately one chunk of data playback */
|
||||||
|
sleep(HZ*PCMBUF_TARGET_CHUNK/(NATIVE_FREQUENCY*4));
|
||||||
|
}
|
||||||
|
pcmbuf_add_chunk();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||||
static void boost_codec_thread(bool boost)
|
static void boost_codec_thread(bool boost)
|
||||||
{
|
{
|
||||||
|
@ -431,7 +497,7 @@ inline size_t pcmbuf_free(void)
|
||||||
return pcmbuf_size;
|
return pcmbuf_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pcmbuf_crossfade_init(bool manual_skip)
|
static bool pcmbuf_crossfade_init(bool manual_skip)
|
||||||
{
|
{
|
||||||
/* Can't do two crossfades at once and, no fade if pcm is off now */
|
/* Can't do two crossfades at once and, no fade if pcm is off now */
|
||||||
if (crossfade_init || crossfade_active || !pcm_is_playing())
|
if (crossfade_init || crossfade_active || !pcm_is_playing())
|
||||||
|
@ -542,11 +608,20 @@ static char *pcmbuf_calc_audiobuffer_ptr(size_t bufsize)
|
||||||
|
|
||||||
bool pcmbuf_is_same_size(void)
|
bool pcmbuf_is_same_size(void)
|
||||||
{
|
{
|
||||||
if (audiobuffer == NULL)
|
bool same_size;
|
||||||
return true; /* Not set up yet even once so always */
|
|
||||||
|
|
||||||
|
if (audiobuffer == NULL)
|
||||||
|
same_size = true; /* Not set up yet even once so always */
|
||||||
|
else
|
||||||
|
{
|
||||||
size_t bufsize = pcmbuf_get_next_required_pcmbuf_size();
|
size_t bufsize = pcmbuf_get_next_required_pcmbuf_size();
|
||||||
return pcmbuf_calc_audiobuffer_ptr(bufsize) == audiobuffer;
|
same_size = pcmbuf_calc_audiobuffer_ptr(bufsize) == audiobuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (same_size)
|
||||||
|
pcmbuf_finish_crossfade_enable();
|
||||||
|
|
||||||
|
return same_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the pcmbuffer the structure looks like this:
|
/* Initialize the pcmbuffer the structure looks like this:
|
||||||
|
@ -566,7 +641,7 @@ size_t pcmbuf_init(unsigned char *bufend)
|
||||||
end_of_track = false;
|
end_of_track = false;
|
||||||
track_transition = false;
|
track_transition = false;
|
||||||
|
|
||||||
pcmbuf_crossfade_enable_finished();
|
pcmbuf_finish_crossfade_enable();
|
||||||
|
|
||||||
pcmbuf_play_stop();
|
pcmbuf_play_stop();
|
||||||
|
|
||||||
|
@ -606,28 +681,6 @@ void pcmbuf_play_start(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Commit samples waiting to the pcm buffer.
|
|
||||||
*/
|
|
||||||
static bool pcmbuf_flush_fillpos(void)
|
|
||||||
{
|
|
||||||
if (audiobuffer_fillpos) {
|
|
||||||
/* Never use the last buffer descriptor */
|
|
||||||
while (pcmbuf_write == pcmbuf_write_end) {
|
|
||||||
/* If this happens, something is being stupid */
|
|
||||||
if (!pcm_is_playing()) {
|
|
||||||
logf("pcmbuf_flush_fillpos error");
|
|
||||||
pcmbuf_play_start();
|
|
||||||
}
|
|
||||||
/* Let approximately one chunk of data playback */
|
|
||||||
sleep(HZ*PCMBUF_TARGET_CHUNK/(NATIVE_FREQUENCY*4));
|
|
||||||
}
|
|
||||||
pcmbuf_add_chunk();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Low memory targets don't have crossfade, so don't compile crossfade
|
* Low memory targets don't have crossfade, so don't compile crossfade
|
||||||
* specific code in order to save some memory. */
|
* specific code in order to save some memory. */
|
||||||
|
@ -943,38 +996,6 @@ void* pcmbuf_request_buffer(int *count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void * pcmbuf_request_voice_buffer(int *count)
|
|
||||||
{
|
|
||||||
/* A get-it-to-work-for-now hack (audio status could change by
|
|
||||||
completion) */
|
|
||||||
if (audio_status() & AUDIO_STATUS_PLAY)
|
|
||||||
{
|
|
||||||
if (pcmbuf_read == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else if (pcmbuf_usage() >= 10 && pcmbuf_mix_free() >= 30 &&
|
|
||||||
(pcmbuf_mix_chunk || pcmbuf_read->link))
|
|
||||||
{
|
|
||||||
*count = MIN(*count, PCMBUF_MIX_CHUNK/4);
|
|
||||||
return voicebuf;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return pcmbuf_request_buffer(count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool pcmbuf_is_crossfade_active(void)
|
|
||||||
{
|
|
||||||
return crossfade_active || crossfade_init;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pcmbuf_write_complete(int count)
|
void pcmbuf_write_complete(int count)
|
||||||
{
|
{
|
||||||
size_t length = (size_t)(unsigned int)count << 2;
|
size_t length = (size_t)(unsigned int)count << 2;
|
||||||
|
@ -1098,12 +1119,12 @@ void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
|
||||||
#endif /* HAVE_HARDWARE_BEEP */
|
#endif /* HAVE_HARDWARE_BEEP */
|
||||||
|
|
||||||
/* Returns pcm buffer usage in percents (0 to 100). */
|
/* Returns pcm buffer usage in percents (0 to 100). */
|
||||||
int pcmbuf_usage(void)
|
static int pcmbuf_usage(void)
|
||||||
{
|
{
|
||||||
return pcmbuf_unplayed_bytes * 100 / pcmbuf_size;
|
return pcmbuf_unplayed_bytes * 100 / pcmbuf_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcmbuf_mix_free(void)
|
static int pcmbuf_mix_free(void)
|
||||||
{
|
{
|
||||||
if (pcmbuf_mix_chunk)
|
if (pcmbuf_mix_chunk)
|
||||||
{
|
{
|
||||||
|
@ -1117,6 +1138,33 @@ int pcmbuf_mix_free(void)
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *pcmbuf_request_voice_buffer(int *count)
|
||||||
|
{
|
||||||
|
/* A get-it-to-work-for-now hack (audio status could change by
|
||||||
|
completion) */
|
||||||
|
if (audio_status() & AUDIO_STATUS_PLAY)
|
||||||
|
{
|
||||||
|
if (pcmbuf_read == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (pcmbuf_usage() >= 10 && pcmbuf_mix_free() >= 30 &&
|
||||||
|
(pcmbuf_mix_chunk || pcmbuf_read->link))
|
||||||
|
{
|
||||||
|
*count = MIN(*count, PCMBUF_MIX_CHUNK/4);
|
||||||
|
return voicebuf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return pcmbuf_request_buffer(count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pcmbuf_write_voice_complete(int count)
|
void pcmbuf_write_voice_complete(int count)
|
||||||
{
|
{
|
||||||
/* A get-it-to-work-for-now hack (audio status could have changed) */
|
/* A get-it-to-work-for-now hack (audio status could have changed) */
|
||||||
|
@ -1163,23 +1211,33 @@ void pcmbuf_write_voice_complete(int count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcmbuf_crossfade_enable(bool on_off)
|
void pcmbuf_request_crossfade_enable(bool on_off)
|
||||||
{
|
{
|
||||||
/* Next setting to be used, not applied now */
|
/* Next setting to be used, not applied now */
|
||||||
crossfade_enabled_pending = on_off;
|
crossfade_enabled_pending = on_off;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcmbuf_crossfade_enable_finished(void)
|
static void pcmbuf_finish_crossfade_enable(void)
|
||||||
{
|
{
|
||||||
/* Copy the pending setting over now */
|
/* Copy the pending setting over now */
|
||||||
crossfade_enabled = crossfade_enabled_pending;
|
crossfade_enabled = crossfade_enabled_pending;
|
||||||
pcmbuf_set_watermark_bytes();
|
|
||||||
|
pcmbuf_watermark = (crossfade_enabled && pcmbuf_size) ?
|
||||||
|
/* If crossfading, try to keep the buffer full other than 1 second */
|
||||||
|
(pcmbuf_size - (NATIVE_FREQUENCY * 4 * 1)) :
|
||||||
|
/* Otherwise, just use the default */
|
||||||
|
PCMBUF_WATERMARK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pcmbuf_is_crossfade_enabled(void)
|
static bool pcmbuf_is_crossfade_enabled(void)
|
||||||
{
|
{
|
||||||
if (global_settings.crossfade == CROSSFADE_ENABLE_SHUFFLE)
|
if (global_settings.crossfade == CROSSFADE_ENABLE_SHUFFLE)
|
||||||
return global_settings.playlist_shuffle;
|
return global_settings.playlist_shuffle;
|
||||||
|
|
||||||
return crossfade_enabled;
|
return crossfade_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool pcmbuf_is_crossfade_active(void)
|
||||||
|
{
|
||||||
|
return crossfade_active || crossfade_init;
|
||||||
|
}
|
||||||
|
|
|
@ -21,58 +21,37 @@
|
||||||
#ifndef PCMBUF_H
|
#ifndef PCMBUF_H
|
||||||
#define PCMBUF_H
|
#define PCMBUF_H
|
||||||
|
|
||||||
#define PCMBUF_TARGET_CHUNK 32768 /* This is the target fill size of chunks
|
/* playback */
|
||||||
on the pcm buffer */
|
|
||||||
#define PCMBUF_MINAVG_CHUNK 24576 /* This is the minimum average size of
|
|
||||||
chunks on the pcm buffer (or we run out
|
|
||||||
of buffer descriptors, which is
|
|
||||||
non-fatal) */
|
|
||||||
#define PCMBUF_MIN_CHUNK 4096 /* We try to never feed a chunk smaller than
|
|
||||||
this to the DMA */
|
|
||||||
#define PCMBUF_MIX_CHUNK 8192 /* This is the maximum size of one packet
|
|
||||||
for mixing (crossfade or voice) */
|
|
||||||
|
|
||||||
/* Returns true if the buffer needs to change size */
|
|
||||||
bool pcmbuf_is_same_size(void);
|
|
||||||
size_t pcmbuf_init(unsigned char *bufend);
|
size_t pcmbuf_init(unsigned char *bufend);
|
||||||
/* Size in bytes used by the pcmbuffer */
|
void pcmbuf_play_start(void);
|
||||||
|
void pcmbuf_play_stop(void);
|
||||||
|
void pcmbuf_pause(bool pause);
|
||||||
|
void pcmbuf_start_track_change(bool manual_skip);
|
||||||
|
void *pcmbuf_request_buffer(int *count);
|
||||||
|
void pcmbuf_write_complete(int count);
|
||||||
|
|
||||||
|
/* crossfade */
|
||||||
|
bool pcmbuf_is_crossfade_active(void);
|
||||||
|
void pcmbuf_request_crossfade_enable(bool on_off);
|
||||||
|
bool pcmbuf_is_same_size(void);
|
||||||
|
|
||||||
|
/* voice */
|
||||||
|
void *pcmbuf_request_voice_buffer(int *count);
|
||||||
|
void pcmbuf_write_voice_complete(int count);
|
||||||
|
|
||||||
|
/* debug menu, other metrics */
|
||||||
|
size_t pcmbuf_free(void);
|
||||||
size_t pcmbuf_get_bufsize(void);
|
size_t pcmbuf_get_bufsize(void);
|
||||||
|
int pcmbuf_descs(void);
|
||||||
|
int pcmbuf_used_descs(void);
|
||||||
#ifdef ROCKBOX_HAS_LOGF
|
#ifdef ROCKBOX_HAS_LOGF
|
||||||
/* just used for logging for now */
|
|
||||||
unsigned char *pcmbuf_get_meminfo(size_t *length);
|
unsigned char *pcmbuf_get_meminfo(size_t *length);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void pcmbuf_pause(bool pause);
|
/* misc */
|
||||||
void pcmbuf_play_stop(void);
|
|
||||||
bool pcmbuf_is_crossfade_active(void);
|
|
||||||
|
|
||||||
/* These functions are for playing chained buffers of PCM data */
|
|
||||||
#if defined(HAVE_ADJUSTABLE_CPU_FREQ)
|
|
||||||
void pcmbuf_boost(bool state);
|
|
||||||
void pcmbuf_set_boost_mode(bool state);
|
|
||||||
#else
|
|
||||||
#define pcmbuf_boost(state) do { } while(0)
|
|
||||||
#define pcmbuf_set_boost_mode(state) do { } while(0)
|
|
||||||
#endif
|
|
||||||
bool pcmbuf_is_lowdata(void);
|
|
||||||
void pcmbuf_play_start(void);
|
|
||||||
bool pcmbuf_crossfade_init(bool manual_skip);
|
|
||||||
void pcmbuf_start_track_change(void);
|
|
||||||
size_t pcmbuf_free(void);
|
|
||||||
unsigned long pcmbuf_get_latency(void);
|
|
||||||
void pcmbuf_set_low_latency(bool state);
|
|
||||||
void * pcmbuf_request_buffer(int *count);
|
|
||||||
void pcmbuf_write_complete(int count);
|
|
||||||
void * pcmbuf_request_voice_buffer(int *count);
|
|
||||||
void pcmbuf_write_voice_complete(int count);
|
|
||||||
bool pcmbuf_is_crossfade_enabled(void);
|
|
||||||
void pcmbuf_crossfade_enable(bool on_off);
|
|
||||||
void pcmbuf_crossfade_enable_finished(void);
|
|
||||||
int pcmbuf_usage(void);
|
|
||||||
int pcmbuf_mix_free(void);
|
|
||||||
void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude);
|
void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude);
|
||||||
|
bool pcmbuf_is_lowdata(void);
|
||||||
int pcmbuf_used_descs(void);
|
void pcmbuf_set_low_latency(bool state);
|
||||||
int pcmbuf_descs(void);
|
unsigned long pcmbuf_get_latency(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -246,11 +246,19 @@ void audio_pcmbuf_position_callback(size_t size)
|
||||||
|
|
||||||
/* Post message from pcmbuf that the end of the previous track
|
/* Post message from pcmbuf that the end of the previous track
|
||||||
* has just been played. */
|
* has just been played. */
|
||||||
void audio_post_track_change(void)
|
void audio_post_track_change(bool pcmbuf)
|
||||||
|
{
|
||||||
|
if (pcmbuf)
|
||||||
{
|
{
|
||||||
LOGFQUEUE("pcmbuf > pcmbuf Q_AUDIO_TRACK_CHANGED");
|
LOGFQUEUE("pcmbuf > pcmbuf Q_AUDIO_TRACK_CHANGED");
|
||||||
queue_post(&pcmbuf_queue, Q_AUDIO_TRACK_CHANGED, 0);
|
queue_post(&pcmbuf_queue, Q_AUDIO_TRACK_CHANGED, 0);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOGFQUEUE("pcmbuf > audio Q_AUDIO_TRACK_CHANGED");
|
||||||
|
queue_post(&audio_queue, Q_AUDIO_TRACK_CHANGED, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Scan the pcmbuf queue and return true if a message pulled.
|
/* Scan the pcmbuf queue and return true if a message pulled.
|
||||||
* Permissible Context(s): Thread
|
* Permissible Context(s): Thread
|
||||||
|
@ -814,18 +822,12 @@ void audio_set_crossfade(int enable)
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
/* Tell it the next setting to use */
|
/* Tell it the next setting to use */
|
||||||
pcmbuf_crossfade_enable(enable);
|
pcmbuf_request_crossfade_enable(enable);
|
||||||
|
|
||||||
/* Return if size hasn't changed or this is too early to determine
|
/* Return if size hasn't changed or this is too early to determine
|
||||||
which in the second case there's no way we could be playing
|
which in the second case there's no way we could be playing
|
||||||
anything at all */
|
anything at all */
|
||||||
if (pcmbuf_is_same_size())
|
if (pcmbuf_is_same_size()) return;
|
||||||
{
|
|
||||||
/* This function is a copout and just syncs some variables -
|
|
||||||
to be removed at a later date */
|
|
||||||
pcmbuf_crossfade_enable_finished();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = 0;
|
offset = 0;
|
||||||
was_playing = playing;
|
was_playing = playing;
|
||||||
|
@ -2058,7 +2060,7 @@ void audio_init(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set crossfade setting for next buffer init which should be about... */
|
/* Set crossfade setting for next buffer init which should be about... */
|
||||||
pcmbuf_crossfade_enable(global_settings.crossfade);
|
pcmbuf_request_crossfade_enable(global_settings.crossfade);
|
||||||
|
|
||||||
/* initialize the buffering system */
|
/* initialize the buffering system */
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ enum
|
||||||
bool audio_restore_playback(int type); /* Restores the audio buffer to handle the requested playback */
|
bool audio_restore_playback(int type); /* Restores the audio buffer to handle the requested playback */
|
||||||
size_t audio_get_filebuflen(void);
|
size_t audio_get_filebuflen(void);
|
||||||
void audio_pcmbuf_position_callback(size_t size) ICODE_ATTR;
|
void audio_pcmbuf_position_callback(size_t size) ICODE_ATTR;
|
||||||
void audio_post_track_change(void);
|
void audio_post_track_change(bool pcmbuf);
|
||||||
int get_audio_hid(void);
|
int get_audio_hid(void);
|
||||||
int *get_codec_hid(void);
|
int *get_codec_hid(void);
|
||||||
void audio_set_prev_elapsed(unsigned long setting);
|
void audio_set_prev_elapsed(unsigned long setting);
|
||||||
|
|
Loading…
Reference in a new issue