mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
pcmbuf: bug fix with pcmbuf flush, code cleanup, added comments
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23608 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
db4cab0e66
commit
0db3308cb5
4 changed files with 64 additions and 68 deletions
|
@ -168,7 +168,7 @@ static void* codec_get_buffer(size_t *size)
|
||||||
return &codecbuf[codec_size];
|
return &codecbuf[codec_size];
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool codec_pcmbuf_insert_callback(
|
static void codec_pcmbuf_insert_callback(
|
||||||
const void *ch1, const void *ch2, int count)
|
const void *ch1, const void *ch2, int count)
|
||||||
{
|
{
|
||||||
const char *src[2] = { ch1, ch2 };
|
const char *src[2] = { ch1, ch2 };
|
||||||
|
@ -181,14 +181,14 @@ static bool codec_pcmbuf_insert_callback(
|
||||||
|
|
||||||
/* Prevent audio from a previous track from playing */
|
/* Prevent audio from a previous track from playing */
|
||||||
if (ci.new_track || ci.stop_codec)
|
if (ci.new_track || ci.stop_codec)
|
||||||
return true;
|
return;
|
||||||
|
|
||||||
while ((dest = pcmbuf_request_buffer(&out_count)) == NULL)
|
while ((dest = pcmbuf_request_buffer(&out_count)) == NULL)
|
||||||
{
|
{
|
||||||
cancel_cpu_boost();
|
cancel_cpu_boost();
|
||||||
sleep(1);
|
sleep(1);
|
||||||
if (ci.seek_time || ci.new_track || ci.stop_codec)
|
if (ci.seek_time || ci.new_track || ci.stop_codec)
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the real input_size for output_size bytes, guarding
|
/* Get the real input_size for output_size bytes, guarding
|
||||||
|
@ -196,7 +196,7 @@ static bool codec_pcmbuf_insert_callback(
|
||||||
inp_count = dsp_input_count(ci.dsp, out_count);
|
inp_count = dsp_input_count(ci.dsp, out_count);
|
||||||
|
|
||||||
if (inp_count <= 0)
|
if (inp_count <= 0)
|
||||||
return true;
|
return;
|
||||||
|
|
||||||
/* Input size has grown, no error, just don't write more than length */
|
/* Input size has grown, no error, just don't write more than length */
|
||||||
if (inp_count > count)
|
if (inp_count > count)
|
||||||
|
@ -205,14 +205,12 @@ static bool codec_pcmbuf_insert_callback(
|
||||||
out_count = dsp_process(ci.dsp, dest, src, inp_count);
|
out_count = dsp_process(ci.dsp, dest, src, inp_count);
|
||||||
|
|
||||||
if (out_count <= 0)
|
if (out_count <= 0)
|
||||||
return true;
|
return;
|
||||||
|
|
||||||
pcmbuf_write_complete(out_count);
|
pcmbuf_write_complete(out_count);
|
||||||
|
|
||||||
count -= inp_count;
|
count -= inp_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
} /* codec_pcmbuf_insert_callback */
|
} /* codec_pcmbuf_insert_callback */
|
||||||
|
|
||||||
static void codec_set_elapsed_callback(unsigned long value)
|
static void codec_set_elapsed_callback(unsigned long value)
|
||||||
|
|
|
@ -121,7 +121,7 @@ struct codec_api {
|
||||||
void* (*codec_get_buffer)(size_t *size);
|
void* (*codec_get_buffer)(size_t *size);
|
||||||
/* Insert PCM data into audio buffer for playback. Playback will start
|
/* Insert PCM data into audio buffer for playback. Playback will start
|
||||||
automatically. */
|
automatically. */
|
||||||
bool (*pcmbuf_insert)(const void *ch1, const void *ch2, int count);
|
void (*pcmbuf_insert)(const void *ch1, const void *ch2, int count);
|
||||||
/* Set song position in WPS (value in ms). */
|
/* Set song position in WPS (value in ms). */
|
||||||
void (*set_elapsed)(unsigned long value);
|
void (*set_elapsed)(unsigned long value);
|
||||||
|
|
||||||
|
|
110
apps/pcmbuf.c
110
apps/pcmbuf.c
|
@ -119,7 +119,7 @@ static struct chunkdesc *mix_chunk IDATA_ATTR;
|
||||||
static size_t pcmbuf_mix_sample IDATA_ATTR;
|
static size_t pcmbuf_mix_sample IDATA_ATTR;
|
||||||
|
|
||||||
static bool low_latency_mode = false;
|
static bool low_latency_mode = false;
|
||||||
static bool flush_pcmbuf;
|
static bool flush_pcmbuf = false;
|
||||||
|
|
||||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||||
static int codec_thread_priority = PRIORITY_PLAYBACK;
|
static int codec_thread_priority = PRIORITY_PLAYBACK;
|
||||||
|
@ -129,14 +129,14 @@ extern unsigned int codec_thread_id;
|
||||||
|
|
||||||
/* Helpful macros for use in conditionals this assumes some of the above
|
/* Helpful macros for use in conditionals this assumes some of the above
|
||||||
* static variable names */
|
* static variable names */
|
||||||
#define NEED_FLUSH(position) \
|
#define COMMIT_IF_NEEDED if(pcmbuffer_fillpos > PCMBUF_TARGET_CHUNK || \
|
||||||
(pcmbuffer_fillpos > PCMBUF_TARGET_CHUNK || position >= pcmbuf_size)
|
(pcmbuffer_pos + pcmbuffer_fillpos) >= pcmbuf_size) commit_chunk(false)
|
||||||
#define LOW_DATA(quarter_secs) \
|
#define LOW_DATA(quarter_secs) \
|
||||||
(pcmbuf_unplayed_bytes < NATIVE_FREQUENCY * quarter_secs)
|
(pcmbuf_unplayed_bytes < NATIVE_FREQUENCY * quarter_secs)
|
||||||
|
|
||||||
#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 write_to_crossfade(char *buf, size_t length);
|
||||||
static void pcmbuf_finish_crossfade_enable(void);
|
static void pcmbuf_finish_crossfade_enable(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -181,12 +181,10 @@ static bool show_desc(char *caller)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Commit PCM data */
|
/** Accept new PCM data */
|
||||||
|
|
||||||
/**
|
/* Commit PCM buffer samples as a new chunk for playback */
|
||||||
* Commit samples waiting to the pcm buffer.
|
static void commit_chunk(bool flush_next_time)
|
||||||
*/
|
|
||||||
static void commit_chunk(void)
|
|
||||||
{
|
{
|
||||||
if (!pcmbuffer_fillpos)
|
if (!pcmbuffer_fillpos)
|
||||||
return;
|
return;
|
||||||
|
@ -219,7 +217,7 @@ static void commit_chunk(void)
|
||||||
{
|
{
|
||||||
if (flush_pcmbuf)
|
if (flush_pcmbuf)
|
||||||
{
|
{
|
||||||
/* flush! discard all data after the currently playing chunk,
|
/* Flush! Discard all data after the currently playing chunk,
|
||||||
and make the current chunk play next */
|
and make the current chunk play next */
|
||||||
write_end_chunk->link = read_chunk->link;
|
write_end_chunk->link = read_chunk->link;
|
||||||
read_chunk->link = pcmbuf_current;
|
read_chunk->link = pcmbuf_current;
|
||||||
|
@ -228,7 +226,6 @@ static void commit_chunk(void)
|
||||||
write_end_chunk = write_end_chunk->link;
|
write_end_chunk = write_end_chunk->link;
|
||||||
pcmbuf_unplayed_bytes -= write_end_chunk->size;
|
pcmbuf_unplayed_bytes -= write_end_chunk->size;
|
||||||
}
|
}
|
||||||
flush_pcmbuf = false;
|
|
||||||
}
|
}
|
||||||
/* If there is already a read buffer setup, add to it */
|
/* If there is already a read buffer setup, add to it */
|
||||||
else
|
else
|
||||||
|
@ -240,6 +237,11 @@ static void commit_chunk(void)
|
||||||
read_chunk = pcmbuf_current;
|
read_chunk = pcmbuf_current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If flush_next_time is true, then the current chunk will be thrown out
|
||||||
|
* and the next chunk to be committed will be the next to be played.
|
||||||
|
* This is used to empty the PCM buffer for a track change. */
|
||||||
|
flush_pcmbuf = flush_next_time;
|
||||||
|
|
||||||
/* This is now the last buffer to read */
|
/* This is now the last buffer to read */
|
||||||
read_end_chunk = pcmbuf_current;
|
read_end_chunk = pcmbuf_current;
|
||||||
|
|
||||||
|
@ -254,6 +256,7 @@ static void commit_chunk(void)
|
||||||
DISPLAY_DESC("commit_chunk");
|
DISPLAY_DESC("commit_chunk");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set priority of the codec thread */
|
||||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||||
static void boost_codec_thread(bool boost)
|
static void boost_codec_thread(bool boost)
|
||||||
{
|
{
|
||||||
|
@ -282,6 +285,8 @@ static void boost_codec_thread(bool boost)
|
||||||
#define boost_codec_thread(boost) do{}while(0)
|
#define boost_codec_thread(boost) do{}while(0)
|
||||||
#endif /* HAVE_PRIORITY_SCHEDULING */
|
#endif /* HAVE_PRIORITY_SCHEDULING */
|
||||||
|
|
||||||
|
/* Return true if the PCM buffer is able to receive new data.
|
||||||
|
* Also maintain buffer level above the watermark. */
|
||||||
static bool prepare_insert(size_t length)
|
static bool prepare_insert(size_t length)
|
||||||
{
|
{
|
||||||
if (low_latency_mode)
|
if (low_latency_mode)
|
||||||
|
@ -295,7 +300,7 @@ static bool prepare_insert(size_t length)
|
||||||
if (pcmbuf_free() < length + PCMBUF_MIN_CHUNK)
|
if (pcmbuf_free() < length + PCMBUF_MIN_CHUNK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* boost CPU if needed to either fill to watermark or for pre-buffer */
|
/* Maintain the buffer level above the watermark */
|
||||||
if (pcm_is_playing())
|
if (pcm_is_playing())
|
||||||
{
|
{
|
||||||
/* Only codec thread initiates boost - voice boosts the cpu when playing
|
/* Only codec thread initiates boost - voice boosts the cpu when playing
|
||||||
|
@ -328,9 +333,10 @@ static bool prepare_insert(size_t length)
|
||||||
}
|
}
|
||||||
else /* pcm_is_playing */
|
else /* pcm_is_playing */
|
||||||
{
|
{
|
||||||
|
/* Boost CPU for pre-buffer */
|
||||||
trigger_cpu_boost();
|
trigger_cpu_boost();
|
||||||
|
|
||||||
/* Pre-buffer up to watermark */
|
/* If pre-buffered to the watermark, start playback */
|
||||||
#if MEMORYSIZE > 2
|
#if MEMORYSIZE > 2
|
||||||
if (!LOW_DATA(4))
|
if (!LOW_DATA(4))
|
||||||
#else
|
#else
|
||||||
|
@ -346,18 +352,23 @@ static bool prepare_insert(size_t length)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Request space in the buffer for writing output samples */
|
||||||
void *pcmbuf_request_buffer(int *count)
|
void *pcmbuf_request_buffer(int *count)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_CROSSFADE
|
#ifdef HAVE_CROSSFADE
|
||||||
|
/* we're going to crossfade to a new track, which is now on its way */
|
||||||
if (crossfade_track_change_started)
|
if (crossfade_track_change_started)
|
||||||
crossfade_start();
|
crossfade_start();
|
||||||
|
|
||||||
if (crossfade_active) {
|
/* crossfade has begun, put the new track samples in fadebuf */
|
||||||
|
if (crossfade_active)
|
||||||
|
{
|
||||||
*count = MIN(*count, PCMBUF_MIX_CHUNK/4);
|
*count = MIN(*count, PCMBUF_MIX_CHUNK/4);
|
||||||
return fadebuf;
|
return fadebuf;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
/* if possible, reserve room in the PCM buffer for new samples */
|
||||||
{
|
{
|
||||||
if(prepare_insert(*count << 2))
|
if(prepare_insert(*count << 2))
|
||||||
{
|
{
|
||||||
|
@ -369,38 +380,34 @@ void *pcmbuf_request_buffer(int *count)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Flush and wrap the buffer */
|
/* Wrap the buffer, the new samples go at the beginning */
|
||||||
commit_chunk();
|
commit_chunk(false);
|
||||||
pcmbuffer_pos = 0;
|
pcmbuffer_pos = 0;
|
||||||
return &pcmbuffer[0];
|
return &pcmbuffer[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* PCM buffer not ready to receive new data yet */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle new samples to the buffer */
|
||||||
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;
|
||||||
#ifdef HAVE_CROSSFADE
|
#ifdef HAVE_CROSSFADE
|
||||||
if (crossfade_active)
|
if (crossfade_active)
|
||||||
{
|
write_to_crossfade(fadebuf, length);
|
||||||
flush_crossfade(fadebuf, length);
|
|
||||||
if (!(crossfade_fade_in_rem || crossfade_chunk))
|
|
||||||
crossfade_active = false;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
pcmbuffer_fillpos += length;
|
pcmbuffer_fillpos += length;
|
||||||
|
COMMIT_IF_NEEDED;
|
||||||
if (NEED_FLUSH(pcmbuffer_pos + pcmbuffer_fillpos))
|
|
||||||
commit_chunk();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Init */
|
/** Init */
|
||||||
|
|
||||||
static inline void init_pcmbuffers(void)
|
static inline void init_pcmbuffers(void)
|
||||||
{
|
{
|
||||||
|
@ -466,14 +473,13 @@ size_t pcmbuf_init(unsigned char *bufend)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Track change */
|
/** Track change */
|
||||||
|
|
||||||
void pcmbuf_start_track_change(bool auto_skip)
|
void pcmbuf_start_track_change(bool auto_skip)
|
||||||
{
|
{
|
||||||
bool crossfade = false;
|
bool crossfade = false;
|
||||||
#ifdef HAVE_CROSSFADE
|
#ifdef HAVE_CROSSFADE
|
||||||
/* Determine whether this track change needs to crossfade */
|
/* Determine whether this track change needs to crossfade */
|
||||||
|
|
||||||
if(crossfade_enabled && !pcmbuf_is_crossfade_active())
|
if(crossfade_enabled && !pcmbuf_is_crossfade_active())
|
||||||
{
|
{
|
||||||
switch(global_settings.crossfade)
|
switch(global_settings.crossfade)
|
||||||
|
@ -524,8 +530,7 @@ void pcmbuf_start_track_change(bool auto_skip)
|
||||||
/* Not enough data, or not crossfading, flush the old data instead */
|
/* Not enough data, or not crossfading, flush the old data instead */
|
||||||
if (LOW_DATA(2) || !crossfade || low_latency_mode)
|
if (LOW_DATA(2) || !crossfade || low_latency_mode)
|
||||||
{
|
{
|
||||||
flush_pcmbuf = true;
|
commit_chunk(true);
|
||||||
commit_chunk();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,7 +541,7 @@ void pcmbuf_start_track_change(bool auto_skip)
|
||||||
crossfade_track_change_started = crossfade;
|
crossfade_track_change_started = crossfade;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else /* automatic and not crossfading, so gapless track change */
|
else /* automatic and not crossfading, so do gapless track change */
|
||||||
{
|
{
|
||||||
/* The codec is moving on to the next track, but the current track will
|
/* The codec is moving on to the next track, but the current track will
|
||||||
* continue to play. Set a flag to make sure the elapsed time of the
|
* continue to play. Set a flag to make sure the elapsed time of the
|
||||||
|
@ -549,9 +554,9 @@ void pcmbuf_start_track_change(bool auto_skip)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Playback */
|
/** Playback */
|
||||||
|
|
||||||
/** PCM driver callback
|
/* PCM driver callback
|
||||||
* This function has 3 major logical parts (separated by brackets both for
|
* This function has 3 major logical parts (separated by brackets both for
|
||||||
* readability and variable scoping). The first part performs the
|
* readability and variable scoping). The first part performs the
|
||||||
* operations related to finishing off the last chunk we fed to the DMA.
|
* operations related to finishing off the last chunk we fed to the DMA.
|
||||||
|
@ -598,7 +603,7 @@ static void pcmbuf_pcm_callback(unsigned char** start, size_t* size)
|
||||||
if (pcmbuffer_fillpos && !read_chunk)
|
if (pcmbuffer_fillpos && !read_chunk)
|
||||||
{
|
{
|
||||||
logf("pcmbuf_pcm_callback: commit last samples");
|
logf("pcmbuf_pcm_callback: commit last samples");
|
||||||
commit_chunk();
|
commit_chunk(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,7 +630,7 @@ static void pcmbuf_pcm_callback(unsigned char** start, size_t* size)
|
||||||
DISPLAY_DESC("callback");
|
DISPLAY_DESC("callback");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Force playback. */
|
/* Force playback */
|
||||||
void pcmbuf_play_start(void)
|
void pcmbuf_play_start(void)
|
||||||
{
|
{
|
||||||
if (!pcm_is_playing() && pcmbuf_unplayed_bytes && read_chunk != NULL)
|
if (!pcm_is_playing() && pcmbuf_unplayed_bytes && read_chunk != NULL)
|
||||||
|
@ -658,7 +663,6 @@ void pcmbuf_play_stop(void)
|
||||||
#endif
|
#endif
|
||||||
end_of_track = false;
|
end_of_track = false;
|
||||||
track_transition = false;
|
track_transition = false;
|
||||||
flush_pcmbuf = false;
|
|
||||||
DISPLAY_DESC("play_stop");
|
DISPLAY_DESC("play_stop");
|
||||||
|
|
||||||
/* Can unboost the codec thread here no matter who's calling */
|
/* Can unboost the codec thread here no matter who's calling */
|
||||||
|
@ -675,7 +679,7 @@ void pcmbuf_pause(bool pause)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Crossfade */
|
/** Crossfade */
|
||||||
|
|
||||||
/* Clip sample to signed 16 bit range */
|
/* Clip sample to signed 16 bit range */
|
||||||
static inline int32_t clip_sample_16(int32_t sample)
|
static inline int32_t clip_sample_16(int32_t sample)
|
||||||
|
@ -686,9 +690,7 @@ static inline int32_t clip_sample_16(int32_t sample)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_CROSSFADE
|
#ifdef HAVE_CROSSFADE
|
||||||
/**
|
/* Completely process the crossfade fade-out effect with current PCM buffer */
|
||||||
* Completely process the crossfade fade out effect with current pcm buffer.
|
|
||||||
*/
|
|
||||||
static void crossfade_process_buffer(size_t fade_in_delay,
|
static void crossfade_process_buffer(size_t fade_in_delay,
|
||||||
size_t fade_out_delay, size_t fade_out_rem)
|
size_t fade_out_delay, size_t fade_out_rem)
|
||||||
{
|
{
|
||||||
|
@ -747,8 +749,8 @@ static void crossfade_process_buffer(size_t fade_in_delay,
|
||||||
logf("process done!");
|
logf("process done!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initializes crossfader, calculates all necessary parameters and
|
/* Initializes crossfader, calculates all necessary parameters and performs
|
||||||
* performs fade-out with the pcm buffer. */
|
* fade-out with the PCM buffer. */
|
||||||
static void crossfade_start(void)
|
static void crossfade_start(void)
|
||||||
{
|
{
|
||||||
size_t crossfade_rem;
|
size_t crossfade_rem;
|
||||||
|
@ -766,7 +768,7 @@ static void crossfade_start(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
logf("crossfade_start");
|
logf("crossfade_start");
|
||||||
commit_chunk();
|
commit_chunk(false);
|
||||||
crossfade_active = true;
|
crossfade_active = true;
|
||||||
|
|
||||||
/* Initialize the crossfade buffer size to all of the buffered data that
|
/* Initialize the crossfade buffer size to all of the buffered data that
|
||||||
|
@ -854,7 +856,8 @@ static size_t crossfade_mix(int factor, const char *buf, size_t length)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flush_crossfade(char *buf, size_t length)
|
/* Perform fade-in of new track */
|
||||||
|
static void write_to_crossfade(char *buf, size_t length)
|
||||||
{
|
{
|
||||||
if (length)
|
if (length)
|
||||||
{
|
{
|
||||||
|
@ -904,17 +907,13 @@ static void flush_crossfade(char *buf, size_t length)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush samples to the buffer */
|
/* Commit samples to the buffer */
|
||||||
while (!prepare_insert(length))
|
while (!prepare_insert(length))
|
||||||
sleep(1);
|
sleep(1);
|
||||||
while (length > 0)
|
while (length > 0)
|
||||||
{
|
{
|
||||||
|
COMMIT_IF_NEEDED;
|
||||||
size_t pcmbuffer_index = pcmbuffer_pos + pcmbuffer_fillpos;
|
size_t pcmbuffer_index = pcmbuffer_pos + pcmbuffer_fillpos;
|
||||||
if (NEED_FLUSH(pcmbuffer_index))
|
|
||||||
{
|
|
||||||
commit_chunk();
|
|
||||||
pcmbuffer_index = pcmbuffer_pos + pcmbuffer_fillpos;
|
|
||||||
}
|
|
||||||
size_t copy_n = MIN(length, pcmbuf_size - pcmbuffer_index);
|
size_t copy_n = MIN(length, pcmbuf_size - pcmbuffer_index);
|
||||||
memcpy(&pcmbuffer[pcmbuffer_index], buf, copy_n);
|
memcpy(&pcmbuffer[pcmbuffer_index], buf, copy_n);
|
||||||
buf += copy_n;
|
buf += copy_n;
|
||||||
|
@ -922,6 +921,9 @@ static void flush_crossfade(char *buf, size_t length)
|
||||||
length -= copy_n;
|
length -= copy_n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* if no more fading-in to do, stop the crossfade */
|
||||||
|
if (!(crossfade_fade_in_rem || crossfade_chunk))
|
||||||
|
crossfade_active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcmbuf_finish_crossfade_enable(void)
|
static void pcmbuf_finish_crossfade_enable(void)
|
||||||
|
@ -962,7 +964,7 @@ bool pcmbuf_is_same_size(void)
|
||||||
#endif /* HAVE_CROSSFADE */
|
#endif /* HAVE_CROSSFADE */
|
||||||
|
|
||||||
|
|
||||||
/* Voice */
|
/** Voice */
|
||||||
|
|
||||||
/* Returns pcm buffer usage in percents (0 to 100). */
|
/* Returns pcm buffer usage in percents (0 to 100). */
|
||||||
static int pcmbuf_usage(void)
|
static int pcmbuf_usage(void)
|
||||||
|
@ -1058,7 +1060,7 @@ void pcmbuf_write_voice_complete(int count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Debug menu, other metrics */
|
/** Debug menu, other metrics */
|
||||||
|
|
||||||
/* Amount of bytes left in the buffer. */
|
/* Amount of bytes left in the buffer. */
|
||||||
size_t pcmbuf_free(void)
|
size_t pcmbuf_free(void)
|
||||||
|
@ -1072,7 +1074,7 @@ size_t pcmbuf_free(void)
|
||||||
else
|
else
|
||||||
return (size_t) (read - write);
|
return (size_t) (read - write);
|
||||||
}
|
}
|
||||||
return pcmbuf_size;
|
return pcmbuf_size - pcmbuffer_fillpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pcmbuf_get_bufsize(void)
|
size_t pcmbuf_get_bufsize(void)
|
||||||
|
@ -1097,7 +1099,7 @@ int pcmbuf_descs(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ROCKBOX_HAS_LOGF
|
#ifdef ROCKBOX_HAS_LOGF
|
||||||
unsigned char * pcmbuf_get_meminfo(size_t *length)
|
unsigned char *pcmbuf_get_meminfo(size_t *length)
|
||||||
{
|
{
|
||||||
*length = pcmbuf_bufend - pcmbuffer;
|
*length = pcmbuf_bufend - pcmbuffer;
|
||||||
return pcmbuffer;
|
return pcmbuffer;
|
||||||
|
@ -1105,7 +1107,7 @@ unsigned char * pcmbuf_get_meminfo(size_t *length)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Misc */
|
/** Misc */
|
||||||
|
|
||||||
bool pcmbuf_is_lowdata(void)
|
bool pcmbuf_is_lowdata(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -239,14 +239,12 @@ static int process_dsp(const void *ch1, const void *ch2, int count)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Null output */
|
/* Null output */
|
||||||
static bool pcmbuf_insert_null(const void *ch1, const void *ch2, int count)
|
static void pcmbuf_insert_null(const void *ch1, const void *ch2, int count)
|
||||||
{
|
{
|
||||||
if (use_dsp) process_dsp(ch1, ch2, count);
|
if (use_dsp) process_dsp(ch1, ch2, count);
|
||||||
|
|
||||||
/* Prevent idle poweroff */
|
/* Prevent idle poweroff */
|
||||||
rb->reset_poweroff_timer();
|
rb->reset_poweroff_timer();
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int32_t clip_sample(int32_t sample)
|
static inline int32_t clip_sample(int32_t sample)
|
||||||
|
@ -259,7 +257,7 @@ static inline int32_t clip_sample(int32_t sample)
|
||||||
|
|
||||||
|
|
||||||
/* WAV output */
|
/* WAV output */
|
||||||
static bool pcmbuf_insert_wav(const void *ch1, const void *ch2, int count)
|
static void pcmbuf_insert_wav(const void *ch1, const void *ch2, int count)
|
||||||
{
|
{
|
||||||
const int16_t* data1_16;
|
const int16_t* data1_16;
|
||||||
const int16_t* data2_16;
|
const int16_t* data2_16;
|
||||||
|
@ -360,8 +358,6 @@ static bool pcmbuf_insert_wav(const void *ch1, const void *ch2, int count)
|
||||||
wavinfo.totalsamples += count;
|
wavinfo.totalsamples += count;
|
||||||
rb->write(wavinfo.fd, wavbuffer, p - wavbuffer);
|
rb->write(wavinfo.fd, wavbuffer, p - wavbuffer);
|
||||||
} /* else */
|
} /* else */
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set song position in WPS (value in ms). */
|
/* Set song position in WPS (value in ms). */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue