summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/codecs.c1
-rw-r--r--apps/codecs.h7
-rw-r--r--apps/codecs/a52.c7
-rw-r--r--apps/codecs/aac.c8
-rw-r--r--apps/codecs/adx.c7
-rw-r--r--apps/codecs/aiff.c17
-rw-r--r--apps/codecs/alac.c5
-rw-r--r--apps/codecs/flac.c7
-rw-r--r--apps/codecs/mpa.c10
-rw-r--r--apps/codecs/mpc.c7
-rw-r--r--apps/codecs/nsf.c4
-rw-r--r--apps/codecs/shorten.c7
-rw-r--r--apps/codecs/sid.c3
-rw-r--r--apps/codecs/vorbis.c5
-rw-r--r--apps/codecs/wav.c25
-rw-r--r--apps/codecs/wavpack.c3
-rw-r--r--apps/dsp.c130
-rw-r--r--apps/dsp.h6
-rw-r--r--apps/pcmbuf.c30
-rw-r--r--apps/pcmbuf.h8
-rw-r--r--apps/playback.c129
21 files changed, 170 insertions, 256 deletions
diff --git a/apps/codecs.c b/apps/codecs.c
index 3af5158fbb..09fd6e522e 100644
--- a/apps/codecs.c
+++ b/apps/codecs.c
@@ -78,7 +78,6 @@ struct codec_api ci = {
0, /* seek_time */
NULL, /* get_codec_memory */
NULL, /* pcmbuf_insert */
- NULL, /* pcmbuf_insert_split */
NULL, /* set_elapsed */
NULL, /* read_filebuf */
NULL, /* request_buffer */
diff --git a/apps/codecs.h b/apps/codecs.h
index e474c7a6bb..993ef3fecb 100644
--- a/apps/codecs.h
+++ b/apps/codecs.h
@@ -90,12 +90,12 @@
#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */
/* increase this every time the api struct changes */
-#define CODEC_API_VERSION 12
+#define CODEC_API_VERSION 13
/* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any
new function which are "waiting" at the end of the function table) */
-#define CODEC_MIN_API_VERSION 12
+#define CODEC_MIN_API_VERSION 13
/* codec return codes */
enum codec_status {
@@ -133,8 +133,7 @@ struct codec_api {
void* (*get_codec_memory)(size_t *size);
/* Insert PCM data into audio buffer for playback. Playback will start
automatically. */
- bool (*pcmbuf_insert)(const char *data, size_t length);
- bool (*pcmbuf_insert_split)(const void *ch1, const void *ch2, size_t length);
+ bool (*pcmbuf_insert)(const void *ch1, const void *ch2, int count);
/* Set song position in WPS (value in ms). */
void (*set_elapsed)(unsigned int value);
diff --git a/apps/codecs/a52.c b/apps/codecs/a52.c
index 4f41bfeaf5..028dff6db5 100644
--- a/apps/codecs/a52.c
+++ b/apps/codecs/a52.c
@@ -35,12 +35,9 @@ unsigned long frequency;
/* used outside liba52 */
static uint8_t buf[3840] IBSS_ATTR;
-void output_audio(sample_t *samples)
+static inline void output_audio(sample_t *samples)
{
- do {
- ci->yield();
- } while (!ci->pcmbuf_insert_split(&samples[0], &samples[256],
- 256*sizeof(sample_t)));
+ ci->pcmbuf_insert(&samples[0], &samples[256], 256);
}
void a52_decode_data(uint8_t *start, uint8_t *end)
diff --git a/apps/codecs/aac.c b/apps/codecs/aac.c
index 4695caab4a..7656c416fe 100644
--- a/apps/codecs/aac.c
+++ b/apps/codecs/aac.c
@@ -183,12 +183,8 @@ next_track:
/* Output the audio */
ci->yield();
- while (!ci->pcmbuf_insert_split(decoder->time_out[0],
- decoder->time_out[1],
- frame_info.samples * 2))
- {
- ci->sleep(1);
- }
+ ci->pcmbuf_insert(decoder->time_out[0], decoder->time_out[1],
+ frame_info.samples >> 1);
/* Update the elapsed-time indicator */
sound_samples_done += sample_duration;
diff --git a/apps/codecs/adx.c b/apps/codecs/adx.c
index 608d9f0a3f..85e55a4c38 100644
--- a/apps/codecs/adx.c
+++ b/apps/codecs/adx.c
@@ -320,9 +320,10 @@ next_track:
}
}
- /* 2 bytes per sample */
- while (!ci->pcmbuf_insert((char *)samples, sampleswritten*2))
- ci->yield();
+ if (channels == 2)
+ sampleswritten >>= 1; /* make samples/channel */
+
+ ci->pcmbuf_insert(samples, NULL, sampleswritten);
ci->set_elapsed(
((end_adr-start_adr)*loop_count + bufoff-chanstart)*
diff --git a/apps/codecs/aiff.c b/apps/codecs/aiff.c
index d1bb14aa64..628f9948ea 100644
--- a/apps/codecs/aiff.c
+++ b/apps/codecs/aiff.c
@@ -51,7 +51,8 @@ enum codec_status codec_main(void)
uint16_t sample_size = 0;
uint32_t sample_rate = 0;
uint32_t i;
- size_t n, bufsize;
+ size_t n;
+ int bufcount;
int endofstream;
unsigned char *buf;
uint8_t *aifbuf;
@@ -229,25 +230,27 @@ next_track:
samples[i/4] = (SE(aifbuf[i])<<21)|(aifbuf[i + 1]<<13)
|(aifbuf[i + 2]<<5)|(aifbuf[i + 3]>>3);
}
- bufsize = n;
+ bufcount = n >> 2;
} else if (sample_size > 16) {
for (i = 0; i < n; i += 3) {
samples[i/3] = (SE(aifbuf[i])<<21)|(aifbuf[i + 1]<<13)
|(aifbuf[i + 2]<<5);
}
- bufsize = n*4/3;
+ bufcount = n/3;
} else if (sample_size > 8) {
for (i = 0; i < n; i += 2)
samples[i/2] = (SE(aifbuf[i])<<21)|(aifbuf[i + 1]<<13);
- bufsize = n*2;
+ bufcount = n >> 1;
} else {
for (i = 0; i < n; i++)
samples[i] = SE(aifbuf[i]) << 21;
- bufsize = n*4;
+ bufcount = n;
}
- while (!ci->pcmbuf_insert((char *)samples, bufsize))
- ci->yield();
+ if (num_channels == 2)
+ bufcount >>= 1;
+
+ ci->pcmbuf_insert(samples, NULL, bufcount);
ci->advance_buffer(n);
bytesdone += n;
diff --git a/apps/codecs/alac.c b/apps/codecs/alac.c
index 1c1b14a0da..cfa713a29a 100644
--- a/apps/codecs/alac.c
+++ b/apps/codecs/alac.c
@@ -121,10 +121,7 @@ enum codec_status codec_main(void)
/* Output the audio */
ci->yield();
- while(!ci->pcmbuf_insert_split(outputbuffer[0],
- outputbuffer[1],
- samplesdecoded*sizeof(int32_t)))
- ci->yield();
+ ci->pcmbuf_insert(outputbuffer[0], outputbuffer[1], samplesdecoded);
/* Update the elapsed-time indicator */
samplesdone+=sample_duration;
diff --git a/apps/codecs/flac.c b/apps/codecs/flac.c
index 649c26a6bb..738e4bb391 100644
--- a/apps/codecs/flac.c
+++ b/apps/codecs/flac.c
@@ -489,11 +489,8 @@ enum codec_status codec_main(void)
frame++;
ci->yield();
- while(!ci->pcmbuf_insert_split((char*)&decoded0[fc.sample_skip],
- (char*)&decoded1[fc.sample_skip],
- (fc.blocksize-fc.sample_skip)*4)) {
- ci->yield();
- }
+ ci->pcmbuf_insert(&decoded0[fc.sample_skip], &decoded1[fc.sample_skip],
+ fc.blocksize - fc.sample_skip);
fc.sample_skip = 0;
diff --git a/apps/codecs/mpa.c b/apps/codecs/mpa.c
index 6e474c1abb..4c99778071 100644
--- a/apps/codecs/mpa.c
+++ b/apps/codecs/mpa.c
@@ -199,9 +199,9 @@ next_track:
loop we will need to process the final frame that was decoded. */
if (framelength > 0) {
/* In case of a mono file, the second array will be ignored. */
- ci->pcmbuf_insert_split(&synth.pcm.samples[0][samples_to_skip],
- &synth.pcm.samples[1][samples_to_skip],
- framelength * 4);
+ ci->pcmbuf_insert(&synth.pcm.samples[0][samples_to_skip],
+ &synth.pcm.samples[1][samples_to_skip],
+ framelength);
/* Only skip samples for the first frame added. */
samples_to_skip = 0;
@@ -244,8 +244,8 @@ next_track:
/* Finish the remaining decoded frame.
Cut the required samples from the end. */
if (framelength > stop_skip)
- ci->pcmbuf_insert_split(synth.pcm.samples[0], synth.pcm.samples[1],
- (framelength - stop_skip) * 4);
+ ci->pcmbuf_insert(synth.pcm.samples[0], synth.pcm.samples[1],
+ framelength - stop_skip);
stream.error = 0;
diff --git a/apps/codecs/mpc.c b/apps/codecs/mpc.c
index 1075d88aa1..8aba8e50c2 100644
--- a/apps/codecs/mpc.c
+++ b/apps/codecs/mpc.c
@@ -168,10 +168,9 @@ next_track:
retval = CODEC_ERROR;
goto done;
} else {
- while (!ci->pcmbuf_insert_split(sample_buffer,
- sample_buffer + MPC_FRAME_LENGTH,
- status*sizeof(MPC_SAMPLE_FORMAT)))
- ci->yield();
+ ci->pcmbuf_insert(sample_buffer,
+ sample_buffer + MPC_FRAME_LENGTH,
+ status);
samplesdone += status;
ci->set_elapsed(samplesdone/frequency);
}
diff --git a/apps/codecs/nsf.c b/apps/codecs/nsf.c
index 77043b60ce..f138fa1e01 100644
--- a/apps/codecs/nsf.c
+++ b/apps/codecs/nsf.c
@@ -4445,9 +4445,7 @@ init_nsf:
goto init_nsf;
}
- while (!ci->pcmbuf_insert((char *)samples, written))
- ci->yield();
-
+ ci->pcmbuf_insert(samples, NULL, written >> 1);
}
print_timers(last_path,track);
diff --git a/apps/codecs/shorten.c b/apps/codecs/shorten.c
index 1b9563a676..3c099bc031 100644
--- a/apps/codecs/shorten.c
+++ b/apps/codecs/shorten.c
@@ -134,11 +134,8 @@ seek_start:
/* Insert decoded samples in pcmbuf */
if (nsamples) {
ci->yield();
- while (!ci->pcmbuf_insert_split((char*)(decoded0 + sc.nwrap),
- (char*)(decoded1 + sc.nwrap),
- 4*nsamples)) {
- ci->yield();
- }
+ ci->pcmbuf_insert(decoded0 + sc.nwrap, decoded1 + sc.nwrap,
+ nsamples);
/* Update the elapsed-time indicator */
samplesdone += nsamples;
diff --git a/apps/codecs/sid.c b/apps/codecs/sid.c
index 58eb725057..59683e9b6a 100644
--- a/apps/codecs/sid.c
+++ b/apps/codecs/sid.c
@@ -1309,8 +1309,7 @@ next_track:
}
}
- while (!ci->pcmbuf_insert((char *)samples, CHUNK_SIZE*4))
- ci->yield();
+ ci->pcmbuf_insert(samples, NULL, CHUNK_SIZE);
}
if (ci->request_next_track())
diff --git a/apps/codecs/vorbis.c b/apps/codecs/vorbis.c
index a6a90654b5..8ab4a95faa 100644
--- a/apps/codecs/vorbis.c
+++ b/apps/codecs/vorbis.c
@@ -217,10 +217,7 @@ next_track:
} else if (n < 0) {
DEBUGF("Error decoding frame\n");
} else {
- while (!ci->pcmbuf_insert_split(pcm[0], pcm[1],
- n*sizeof(ogg_int32_t))) {
- ci->sleep(1);
- }
+ ci->pcmbuf_insert(pcm[0], pcm[1], n);
ci->set_offset(ov_raw_tell(&vf));
ci->set_elapsed(ov_time_tell(&vf));
}
diff --git a/apps/codecs/wav.c b/apps/codecs/wav.c
index 26cbf7f6a1..ec268a3a2b 100644
--- a/apps/codecs/wav.c
+++ b/apps/codecs/wav.c
@@ -212,7 +212,8 @@ enum codec_status codec_main(void)
int bytespersample = 0;
uint16_t bitspersample;
uint32_t i;
- size_t n, bufsize;
+ size_t n;
+ int bufcount;
int endofstream;
unsigned char *buf;
uint8_t *wavbuf;
@@ -466,34 +467,39 @@ next_track:
(wavbuf[i + 1]<<5)|(wavbuf[i + 2]<<13)|
(SE(wavbuf[i + 3])<<21);
}
- bufsize = n;
+ bufcount = n >> 2;
} else if (bitspersample > 16) {
for (i = 0; i < n; i += 3) {
samples[i/3] = (wavbuf[i]<<5)|
(wavbuf[i + 1]<<13)|(SE(wavbuf[i + 2])<<21);
}
- bufsize = n*4/3;
+ bufcount = n/3;
} else if (bitspersample > 8) {
for (i = 0; i < n; i += 2) {
samples[i/2] = (wavbuf[i]<<13)|(SE(wavbuf[i + 1])<<21);
}
- bufsize = n*2;
+ bufcount = n >> 1;
} else {
for (i = 0; i < n; i++) {
samples[i] = (wavbuf[i] - 0x80)<<21;
}
- bufsize = n*4;
+ bufcount = n;
}
+
+ if (channels == 2)
+ bufcount >>= 1;
} else if (formattag == WAVE_FORMAT_ALAW
|| formattag == IBM_FORMAT_ALAW) {
for (i = 0; i < n; i++)
samples[i] = alaw2linear16[wavbuf[i]] << 13;
- bufsize = n*4;
+
+ bufcount = (channels == 2) ? (n >> 1) : n;
} else if (formattag == WAVE_FORMAT_MULAW
|| formattag == IBM_FORMAT_MULAW) {
for (i = 0; i < n; i++)
samples[i] = ulaw2linear16[wavbuf[i]] << 13;
- bufsize = n*4;
+
+ bufcount = (channels == 2) ? (n >> 1) : n;
}
else if (formattag == WAVE_FORMAT_DVI_ADPCM) {
unsigned int nblocks = chunksize/blockalign;
@@ -508,15 +514,14 @@ next_track:
goto done;
}
}
- bufsize = nblocks*samplesperblock*channels*4;
+ bufcount = nblocks*samplesperblock;
} else {
DEBUGF("CODEC_ERROR: unsupported format %x\n", formattag);
i = CODEC_ERROR;
goto done;
}
- while (!ci->pcmbuf_insert((char *)samples, bufsize))
- ci->yield();
+ ci->pcmbuf_insert(samples, NULL, bufcount);
ci->advance_buffer(n);
bytesdone += n;
diff --git a/apps/codecs/wavpack.c b/apps/codecs/wavpack.c
index e2c19c82e4..34616d75e9 100644
--- a/apps/codecs/wavpack.c
+++ b/apps/codecs/wavpack.c
@@ -118,8 +118,7 @@ enum codec_status codec_main(void)
if (ci->stop_codec || ci->new_track)
break;
- while (!ci->pcmbuf_insert ((char *) temp_buffer, nsamples * nchans * 4))
- ci->sleep (1);
+ ci->pcmbuf_insert (temp_buffer, NULL, nsamples);
ci->set_elapsed (WavpackGetSampleIndex (wpc) / sr_100 * 10);
ci->yield ();
diff --git a/apps/dsp.c b/apps/dsp.c
index c4630ada77..f7eb48ed03 100644
--- a/apps/dsp.c
+++ b/apps/dsp.c
@@ -40,8 +40,8 @@
#define WORD_FRACBITS 27
#define NATIVE_DEPTH 16
-#define SAMPLE_BUF_SIZE 256
-#define RESAMPLE_BUF_SIZE (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/
+#define SAMPLE_BUF_COUNT 256
+#define RESAMPLE_BUF_COUNT (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/
#define DEFAULT_GAIN 0x01000000
struct dsp_config
@@ -116,8 +116,8 @@ static struct dsp_config *dsp;
* of copying needed is minimized for that case.
*/
-static int32_t sample_buf[SAMPLE_BUF_SIZE] IBSS_ATTR;
-static int32_t resample_buf[RESAMPLE_BUF_SIZE] IBSS_ATTR;
+static int32_t sample_buf[SAMPLE_BUF_COUNT] IBSS_ATTR;
+static int32_t resample_buf[RESAMPLE_BUF_COUNT] IBSS_ATTR;
int sound_get_pitch(void)
{
@@ -139,14 +139,14 @@ void sound_set_pitch(int permille)
*/
static int convert_to_internal(const char* src[], int count, int32_t* dst[])
{
- count = MIN(SAMPLE_BUF_SIZE / 2, count);
+ count = MIN(SAMPLE_BUF_COUNT / 2, count);
if ((dsp->sample_depth <= NATIVE_DEPTH)
|| (dsp->stereo_mode == STEREO_INTERLEAVED))
{
dst[0] = &sample_buf[0];
dst[1] = (dsp->stereo_mode == STEREO_MONO)
- ? dst[0] : &sample_buf[SAMPLE_BUF_SIZE / 2];
+ ? dst[0] : &sample_buf[SAMPLE_BUF_COUNT / 2];
}
else
{
@@ -231,7 +231,7 @@ static void resampler_set_delta(int frequency)
/* TODO: we really should have a separate set of resample functions for both
mono and stereo to avoid all this internal branching and looping. */
-static long downsample(int32_t **dst, int32_t **src, int count,
+static int downsample(int32_t **dst, int32_t **src, int count,
struct resample_data *r)
{
long phase = r->phase;
@@ -246,11 +246,14 @@ static long downsample(int32_t **dst, int32_t **src, int count,
last_sample = r->last_sample[j];
/* Do we need last sample of previous frame for interpolation? */
if (pos > 0)
- {
last_sample = src[j][pos - 1];
- }
- *d[j]++ = last_sample + FRACMUL((phase & 0xffff) << 15,
- src[j][pos] - last_sample);
+
+ /* Be sure starting position isn't passed the available data */
+ if (pos < count)
+ *d[j]++ = last_sample + FRACMUL((phase & 0xffff) << 15,
+ src[j][pos] - last_sample);
+ else /* This is kinda nasty but works somewhat well for now */
+ *d[j]++ = src[j][count - 1];
}
phase += delta;
@@ -316,7 +319,7 @@ static inline int resample(int32_t* src[], int count)
if (dsp->frequency != NATIVE_FREQUENCY)
{
- int32_t* dst[2] = {&resample_buf[0], &resample_buf[RESAMPLE_BUF_SIZE / 2]};
+ int32_t* dst[2] = {&resample_buf[0], &resample_buf[RESAMPLE_BUF_COUNT / 2]};
if (dsp->frequency < NATIVE_FREQUENCY)
{
@@ -619,7 +622,7 @@ static void apply_gain(int32_t* _src[], int _count)
if (s0 != s1)
{
- d = &sample_buf[SAMPLE_BUF_SIZE / 2];
+ d = &sample_buf[SAMPLE_BUF_COUNT / 2];
src[1] = d;
s = *s1++;
@@ -736,18 +739,17 @@ static void write_samples(short* dst, int32_t* src[], int count)
}
/* Process and convert src audio to dst based on the DSP configuration,
- * reading size bytes of audio data. dst is assumed to be large enough; use
- * dst_get_dest_size() to get the required size. src is an array of
- * pointers; for mono and interleaved stereo, it contains one pointer to the
- * start of the audio data; for non-interleaved stereo, it contains two
- * pointers, one for each audio channel. Returns number of bytes written to
- * dest.
+ * reading count number of audio samples. dst is assumed to be large
+ * enough; use dsp_output_count() to get the required number. src is an
+ * array of pointers; for mono and interleaved stereo, it contains one
+ * pointer to the start of the audio data and the other is ignored; for
+ * non-interleaved stereo, it contains two pointers, one for each audio
+ * channel. Returns number of bytes written to dst.
*/
-long dsp_process(char* dst, const char* src[], long size)
+int dsp_process(char *dst, const char *src[], int count)
{
int32_t* tmp[2];
- long written = 0;
- long factor;
+ int written = 0;
int samples;
#if defined(CPU_COLDFIRE) && !defined(SIMULATOR)
@@ -759,14 +761,12 @@ long dsp_process(char* dst, const char* src[], long size)
dsp = &dsp_conf[current_codec];
- factor = (dsp->stereo_mode != STEREO_MONO) ? 2 : 1;
- size /= dsp->sample_bytes * factor;
dsp_set_replaygain(false);
- while (size > 0)
+ while (count > 0)
{
- samples = convert_to_internal(src, size, tmp);
- size -= samples;
+ samples = convert_to_internal(src, count, tmp);
+ count -= samples;
apply_gain(tmp, samples);
samples = resample(tmp, samples);
if (dsp->crossfeed_enabled && dsp->stereo_mode != STEREO_MONO)
@@ -780,85 +780,61 @@ long dsp_process(char* dst, const char* src[], long size)
dst += samples * sizeof(short) * 2;
yield();
}
+
#if defined(CPU_COLDFIRE) && !defined(SIMULATOR)
/* set old macsr again */
coldfire_set_macsr(old_macsr);
#endif
- return written * sizeof(short) * 2;
+ return written;
}
-/* Given size bytes of input data, calculate the maximum number of bytes of
- * output data that would be generated (the calculation is not entirely
- * exact and rounds upwards to be on the safe side; during resampling,
- * the number of samples generated depends on the current state of the
- * resampler).
+/* Given count number of input samples, calculate the maximum number of
+ * samples of output data that would be generated (the calculation is not
+ * entirely exact and rounds upwards to be on the safe side; during
+ * resampling, the number of samples generated depends on the current state
+ * of the resampler).
*/
/* dsp_input_size MUST be called afterwards */
-long dsp_output_size(long size)
+int dsp_output_count(int count)
{
dsp = &dsp_conf[current_codec];
- if (dsp->sample_depth > NATIVE_DEPTH)
- {
- size /= 2;
- }
-
if (dsp->frequency != NATIVE_FREQUENCY)
{
- size = (long) ((((unsigned long) size * NATIVE_FREQUENCY)
- + (dsp->frequency - 1)) / dsp->frequency);
- }
-
- /* round to the next multiple of 2 (these are shorts) */
- size = (size + 1) & ~1;
-
- if (dsp->stereo_mode == STEREO_MONO)
- {
- size *= 2;
+ count = (int)(((unsigned long)count * NATIVE_FREQUENCY
+ + (dsp->frequency - 1)) / dsp->frequency);
}
- /* now we have the size in bytes for two resampled channels,
- * and the size in (short) must not exceed RESAMPLE_BUF_SIZE to
- * avoid resample buffer overflow. One must call dsp_input_size()
- * to get the correct input buffer size. */
- if (size > RESAMPLE_BUF_SIZE*2)
- size = RESAMPLE_BUF_SIZE*2;
+ /* Now we have the resampled sample count which must not exceed
+ * RESAMPLE_BUF_COUNT/2 to avoid resample buffer overflow. One
+ * must call dsp_input_count() to get the correct input sample
+ * count.
+ */
+ if (count > RESAMPLE_BUF_COUNT/2)
+ count = RESAMPLE_BUF_COUNT/2;
- return size;
+ return count;
}
-/* Given size bytes of output buffer, calculate number of bytes of input
- * data that would be consumed in order to fill the output buffer.
+/* Given count output samples, calculate number of input samples
+ * that would be consumed in order to fill the output buffer.
*/
-long dsp_input_size(long size)
+int dsp_input_count(int count)
{
dsp = &dsp_conf[current_codec];
-
- /* convert to number of output stereo samples. */
- size /= 2;
- /* Mono means we need half input samples to fill the output buffer */
- if (dsp->stereo_mode == STEREO_MONO)
- size /= 2;
-
- /* size is now the number of resampled input samples. Convert to
+ /* count is now the number of resampled input samples. Convert to
original input samples. */
if (dsp->frequency != NATIVE_FREQUENCY)
{
/* Use the real resampling delta =
- * (unsigned long) dsp->frequency * 65536 / NATIVE_FREQUENCY, and
+ * dsp->frequency * 65536 / NATIVE_FREQUENCY, and
* round towards zero to avoid buffer overflows. */
- size = ((unsigned long)size *
- resample_data[current_codec].delta) >> 16;
+ count = (int)(((unsigned long)count *
+ resample_data[current_codec].delta) >> 16);
}
- /* Convert back to bytes. */
- if (dsp->sample_depth > NATIVE_DEPTH)
- size *= 4;
- else
- size *= 2;
-
- return size;
+ return count;
}
int dsp_stereo_mode(void)
diff --git a/apps/dsp.h b/apps/dsp.h
index ccea8cba34..5217224797 100644
--- a/apps/dsp.h
+++ b/apps/dsp.h
@@ -206,9 +206,9 @@ enum {
#define DIV64(x, y, z) (long)(((long long)(x) << (z))/(y))
-long dsp_process(char *dest, const char *src[], long size);
-long dsp_input_size(long size);
-long dsp_output_size(long size);
+int dsp_process(char *dest, const char *src[], int count);
+int dsp_input_count(int count);
+int dsp_output_count(int count);
int dsp_stereo_mode(void);
bool dsp_configure(int setting, void *value);
void dsp_set_replaygain(bool always);
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index f9d60e9b58..e2b1d7f87b 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -791,21 +791,20 @@ static bool prepare_insert(size_t length)
return true;
}
-void* pcmbuf_request_buffer(size_t length, size_t *realsize)
+void* pcmbuf_request_buffer(int *count)
{
if (crossfade_init)
crossfade_start();
if (crossfade_active) {
- *realsize = MIN(length, PCMBUF_MIX_CHUNK);
+ *count = MIN(*count, PCMBUF_MIX_CHUNK/4);
return fadebuf;
}
else
{
- if(prepare_insert(length))
+ if(prepare_insert(*count << 2))
{
size_t audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos;
- *realsize = length;
if (pcmbuf_size - audiobuffer_index >= PCMBUF_MIN_CHUNK)
{
/* Usual case, there's space here */
@@ -821,34 +820,31 @@ void* pcmbuf_request_buffer(size_t length, size_t *realsize)
}
else
{
- *realsize = 0;
return NULL;
}
}
}
-void* pcmbuf_request_voice_buffer(size_t length, size_t *realsize, bool mix)
+void* pcmbuf_request_voice_buffer(int *count, bool mix)
{
if (mix)
{
if (pcmbuf_read == NULL)
{
- *realsize = 0;
return NULL;
}
else if (pcmbuf_mix_chunk || pcmbuf_read->link)
{
- *realsize = MIN(length, PCMBUF_MIX_CHUNK);
+ *count = MIN(*count, PCMBUF_MIX_CHUNK/4);
return voicebuf;
}
else
{
- *realsize = 0;
return NULL;
}
}
else
- return pcmbuf_request_buffer(length, realsize);
+ return pcmbuf_request_buffer(count);
}
bool pcmbuf_is_crossfade_active(void)
@@ -856,8 +852,10 @@ bool pcmbuf_is_crossfade_active(void)
return crossfade_active || crossfade_init;
}
-void pcmbuf_write_complete(size_t length)
+void pcmbuf_write_complete(int count)
{
+ size_t length = (size_t)(unsigned int)count << 2;
+
if (crossfade_active)
{
flush_crossfade(fadebuf, length);
@@ -874,8 +872,10 @@ void pcmbuf_write_complete(size_t length)
}
#if 0
-bool pcmbuf_insert_buffer(char *buf, size_t length)
+bool pcmbuf_insert_buffer(char *buf, int count)
{
+ size_t length = (size_t)(unsigned int)count << 2;
+
if (crossfade_active)
{
flush_crossfade(buf, length);
@@ -980,7 +980,7 @@ int pcmbuf_mix_free(void)
return 100;
}
-void pcmbuf_mix_voice(size_t length)
+void pcmbuf_mix_voice(int count)
{
short *ibuf = (short *)voicebuf;
short *obuf;
@@ -998,9 +998,9 @@ void pcmbuf_mix_voice(size_t length)
obuf = (short *)pcmbuf_mix_chunk->addr;
chunk_samples = pcmbuf_mix_chunk->size / 2;
- length /= 2;
+ count <<= 1;
- while (length-- > 0) {
+ while (count-- > 0) {
int sample = *ibuf++;
if (pcmbuf_mix_sample >= chunk_samples)
{
diff --git a/apps/pcmbuf.h b/apps/pcmbuf.h
index a408cdae42..5c35ecc291 100644
--- a/apps/pcmbuf.h
+++ b/apps/pcmbuf.h
@@ -63,16 +63,16 @@ void pcmbuf_set_position_callback(void (*callback)(size_t size));
size_t pcmbuf_free(void);
unsigned int pcmbuf_get_latency(void);
void pcmbuf_set_low_latency(bool state);
-void pcmbuf_write_complete(size_t length);
-void* pcmbuf_request_buffer(size_t length, size_t *realsize);
-void* pcmbuf_request_voice_buffer(size_t length, size_t *realsize, bool mix);
+void pcmbuf_write_complete(int count);
+void* pcmbuf_request_buffer(int *count);
+void* pcmbuf_request_voice_buffer(int *count, bool mix);
bool pcmbuf_is_crossfade_enabled(void);
void pcmbuf_crossfade_enable(bool on_off);
int pcmbuf_usage(void);
int pcmbuf_mix_free(void);
void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude);
-void pcmbuf_mix_voice(size_t length);
+void pcmbuf_mix_voice(int count);
int pcmbuf_used_descs(void);
int pcmbuf_descs(void);
diff --git a/apps/playback.c b/apps/playback.c
index ff681bb85c..939643890e 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -1022,81 +1022,60 @@ static const char * get_codec_filename(int cod_spec)
#ifdef PLAYBACK_VOICE
-static bool voice_pcmbuf_insert_split_callback(
- const void *ch1, const void *ch2, size_t length)
+static bool voice_pcmbuf_insert_callback(
+ const void *ch1, const void *ch2, int count)
{
- const char* src[2];
- char *dest;
- long input_size;
- size_t output_size;
+ const char *src[2] = { ch1, ch2 };
- src[0] = ch1;
- src[1] = ch2;
-
- if (dsp_stereo_mode() == STEREO_NONINTERLEAVED)
- length *= 2; /* Length is per channel */
-
- while (length)
+ while (count > 0)
{
- long est_output_size = dsp_output_size(length);
-
- while ((dest = pcmbuf_request_voice_buffer(est_output_size,
- &output_size, playing)) == NULL)
+ int out_count = dsp_output_count(count);
+ int inp_count;
+ char *dest;
+
+ while ((dest = pcmbuf_request_voice_buffer(
+ &out_count, playing)) == NULL)
{
if (playing && audio_codec_loaded)
swap_codec();
else
yield();
}
-
+
/* Get the real input_size for output_size bytes, guarding
* against resampling buffer overflows. */
- input_size = dsp_input_size(output_size);
+ inp_count = dsp_input_count(out_count);
- if (input_size <= 0)
+ if (inp_count <= 0)
{
- DEBUGF("Error: dsp_input_size(%ld=dsp_output_size(%ld))=%ld<=0\n",
- output_size, length, input_size);
+ DEBUGF("Error: dsp_input_count(%ld=dsp_output_count(%ld))=%ld<=0\n",
+ out_count, count, inp_count);
/* If this happens, there are samples of codec data that don't
* become a number of pcm samples, and something is broken */
return false;
}
/* Input size has grown, no error, just don't write more than length */
- if ((size_t)input_size > length)
- input_size = length;
+ if (inp_count > count)
+ inp_count = count;
- output_size = dsp_process(dest, src, input_size);
+ out_count = dsp_process(dest, src, inp_count);
if (playing)
{
- pcmbuf_mix_voice(output_size);
+ pcmbuf_mix_voice(out_count);
if ((pcmbuf_usage() < 10 || pcmbuf_mix_free() < 30) &&
audio_codec_loaded)
swap_codec();
}
else
- pcmbuf_write_complete(output_size);
+ pcmbuf_write_complete(out_count);
- length -= input_size;
+ count -= inp_count;
}
return true;
-} /* voice_pcmbuf_insert_split_callback */
-
-static bool voice_pcmbuf_insert_callback(const char *buf, size_t length)
-{
- /* TODO: The audiobuffer API should probably be updated, and be based on
- * pcmbuf_insert_split(). */
- long real_length = length;
-
- if (dsp_stereo_mode() == STEREO_NONINTERLEAVED)
- length /= 2; /* Length is per channel */
-
- /* Second channel is only used for non-interleaved stereo. */
- return voice_pcmbuf_insert_split_callback(buf, buf + (real_length / 2),
- length);
-}
+} /* voice_pcmbuf_insert_callback */
static void* voice_get_memory_callback(size_t *size)
{
@@ -1321,30 +1300,22 @@ static void voice_thread(void)
#endif /* PLAYBACK_VOICE */
/* --- Codec thread --- */
-
-static bool codec_pcmbuf_insert_split_callback(
- const void *ch1, const void *ch2, size_t length)
+static bool codec_pcmbuf_insert_callback(
+ const void *ch1, const void *ch2, int count)
{
- const char* src[2];
- char *dest;
- long input_size;
- size_t output_size;
-
- src[0] = ch1;
- src[1] = ch2;
-
- if (dsp_stereo_mode() == STEREO_NONINTERLEAVED)
- length *= 2; /* Length is per channel */
+ const char *src[2] = { ch1, ch2 };
- while (length)
+ while (count > 0)
{
- long est_output_size = dsp_output_size(length);
+ int out_count = dsp_output_count(count);
+ int inp_count;
+ char *dest;
+
/* Prevent audio from a previous track from playing */
if (ci.new_track || ci.stop_codec)
return true;
- while ((dest = pcmbuf_request_buffer(est_output_size,
- &output_size)) == NULL)
+ while ((dest = pcmbuf_request_buffer(&out_count)) == NULL)
{
sleep(1);
if (ci.seek_time || ci.new_track || ci.stop_codec)
@@ -1353,24 +1324,24 @@ static bool codec_pcmbuf_insert_split_callback(
/* Get the real input_size for output_size bytes, guarding
* against resampling buffer overflows. */
- input_size = dsp_input_size(output_size);
+ inp_count = dsp_input_count(out_count);
- if (input_size <= 0)
+ if (inp_count <= 0)
{
- DEBUGF("Error: dsp_input_size(%ld=dsp_output_size(%ld))=%ld<=0\n",
- output_size, length, input_size);
+ DEBUGF("Error: dsp_input_count(%ld=dsp_output_count(%ld))=%ld<=0\n",
+ out_count, count, inp_count);
/* If this happens, there are samples of codec data that don't
* become a number of pcm samples, and something is broken */
return false;
}
/* Input size has grown, no error, just don't write more than length */
- if ((size_t)input_size > length)
- input_size = length;
+ if (inp_count > count)
+ inp_count = count;
- output_size = dsp_process(dest, src, input_size);
+ out_count = dsp_process(dest, src, inp_count);
- pcmbuf_write_complete(output_size);
+ pcmbuf_write_complete(out_count);
#ifdef PLAYBACK_VOICE
if ((voice_is_playing || voice_thread_start)
@@ -1381,26 +1352,12 @@ static bool codec_pcmbuf_insert_split_callback(
swap_codec();
}
#endif
-
- length -= input_size;
+
+ count -= inp_count;
}
return true;
-} /* codec_pcmbuf_insert_split_callback */
-
-static bool codec_pcmbuf_insert_callback(const char *buf, size_t length)
-{
- /* TODO: The audiobuffer API should probably be updated, and be based on
- * pcmbuf_insert_split(). */
- long real_length = length;
-
- if (dsp_stereo_mode() == STEREO_NONINTERLEAVED)
- length /= 2; /* Length is per channel */
-
- /* Second channel is only used for non-interleaved stereo. */
- return codec_pcmbuf_insert_split_callback(buf, buf + (real_length / 2),
- length);
-}
+} /* codec_pcmbuf_insert_callback */
static void* codec_get_memory_callback(size_t *size)
{
@@ -3523,7 +3480,6 @@ static void audio_playback_init(void)
/* Initialize codec api. */
ci.read_filebuf = codec_filebuf_callback;
ci.pcmbuf_insert = codec_pcmbuf_insert_callback;
- ci.pcmbuf_insert_split = codec_pcmbuf_insert_split_callback;
ci.get_codec_memory = codec_get_memory_callback;
ci.request_buffer = codec_request_buffer_callback;
ci.advance_buffer = codec_advance_buffer_callback;
@@ -3543,7 +3499,6 @@ static void audio_playback_init(void)
memset(&id3_voice, 0, sizeof(struct mp3entry));
ci_voice.read_filebuf = voice_filebuf_callback;
ci_voice.pcmbuf_insert = voice_pcmbuf_insert_callback;
- ci_voice.pcmbuf_insert_split = voice_pcmbuf_insert_split_callback;
ci_voice.get_codec_memory = voice_get_memory_callback;
ci_voice.request_buffer = voice_request_buffer_callback;
ci_voice.advance_buffer = voice_advance_buffer_callback;