diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs.c | 1 | ||||
-rw-r--r-- | apps/codecs.h | 7 | ||||
-rw-r--r-- | apps/codecs/a52.c | 7 | ||||
-rw-r--r-- | apps/codecs/aac.c | 8 | ||||
-rw-r--r-- | apps/codecs/adx.c | 7 | ||||
-rw-r--r-- | apps/codecs/aiff.c | 17 | ||||
-rw-r--r-- | apps/codecs/alac.c | 5 | ||||
-rw-r--r-- | apps/codecs/flac.c | 7 | ||||
-rw-r--r-- | apps/codecs/mpa.c | 10 | ||||
-rw-r--r-- | apps/codecs/mpc.c | 7 | ||||
-rw-r--r-- | apps/codecs/nsf.c | 4 | ||||
-rw-r--r-- | apps/codecs/shorten.c | 7 | ||||
-rw-r--r-- | apps/codecs/sid.c | 3 | ||||
-rw-r--r-- | apps/codecs/vorbis.c | 5 | ||||
-rw-r--r-- | apps/codecs/wav.c | 25 | ||||
-rw-r--r-- | apps/codecs/wavpack.c | 3 | ||||
-rw-r--r-- | apps/dsp.c | 130 | ||||
-rw-r--r-- | apps/dsp.h | 6 | ||||
-rw-r--r-- | apps/pcmbuf.c | 30 | ||||
-rw-r--r-- | apps/pcmbuf.h | 8 | ||||
-rw-r--r-- | apps/playback.c | 129 |
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 = { | |||
78 | 0, /* seek_time */ | 78 | 0, /* seek_time */ |
79 | NULL, /* get_codec_memory */ | 79 | NULL, /* get_codec_memory */ |
80 | NULL, /* pcmbuf_insert */ | 80 | NULL, /* pcmbuf_insert */ |
81 | NULL, /* pcmbuf_insert_split */ | ||
82 | NULL, /* set_elapsed */ | 81 | NULL, /* set_elapsed */ |
83 | NULL, /* read_filebuf */ | 82 | NULL, /* read_filebuf */ |
84 | NULL, /* request_buffer */ | 83 | 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 @@ | |||
90 | #define CODEC_ENC_MAGIC 0x52454E43 /* RENC */ | 90 | #define CODEC_ENC_MAGIC 0x52454E43 /* RENC */ |
91 | 91 | ||
92 | /* increase this every time the api struct changes */ | 92 | /* increase this every time the api struct changes */ |
93 | #define CODEC_API_VERSION 12 | 93 | #define CODEC_API_VERSION 13 |
94 | 94 | ||
95 | /* update this to latest version if a change to the api struct breaks | 95 | /* update this to latest version if a change to the api struct breaks |
96 | backwards compatibility (and please take the opportunity to sort in any | 96 | backwards compatibility (and please take the opportunity to sort in any |
97 | new function which are "waiting" at the end of the function table) */ | 97 | new function which are "waiting" at the end of the function table) */ |
98 | #define CODEC_MIN_API_VERSION 12 | 98 | #define CODEC_MIN_API_VERSION 13 |
99 | 99 | ||
100 | /* codec return codes */ | 100 | /* codec return codes */ |
101 | enum codec_status { | 101 | enum codec_status { |
@@ -133,8 +133,7 @@ struct codec_api { | |||
133 | void* (*get_codec_memory)(size_t *size); | 133 | void* (*get_codec_memory)(size_t *size); |
134 | /* Insert PCM data into audio buffer for playback. Playback will start | 134 | /* Insert PCM data into audio buffer for playback. Playback will start |
135 | automatically. */ | 135 | automatically. */ |
136 | bool (*pcmbuf_insert)(const char *data, size_t length); | 136 | bool (*pcmbuf_insert)(const void *ch1, const void *ch2, int count); |
137 | bool (*pcmbuf_insert_split)(const void *ch1, const void *ch2, size_t length); | ||
138 | /* Set song position in WPS (value in ms). */ | 137 | /* Set song position in WPS (value in ms). */ |
139 | void (*set_elapsed)(unsigned int value); | 138 | void (*set_elapsed)(unsigned int value); |
140 | 139 | ||
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; | |||
35 | /* used outside liba52 */ | 35 | /* used outside liba52 */ |
36 | static uint8_t buf[3840] IBSS_ATTR; | 36 | static uint8_t buf[3840] IBSS_ATTR; |
37 | 37 | ||
38 | void output_audio(sample_t *samples) | 38 | static inline void output_audio(sample_t *samples) |
39 | { | 39 | { |
40 | do { | 40 | ci->pcmbuf_insert(&samples[0], &samples[256], 256); |
41 | ci->yield(); | ||
42 | } while (!ci->pcmbuf_insert_split(&samples[0], &samples[256], | ||
43 | 256*sizeof(sample_t))); | ||
44 | } | 41 | } |
45 | 42 | ||
46 | void a52_decode_data(uint8_t *start, uint8_t *end) | 43 | 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: | |||
183 | 183 | ||
184 | /* Output the audio */ | 184 | /* Output the audio */ |
185 | ci->yield(); | 185 | ci->yield(); |
186 | while (!ci->pcmbuf_insert_split(decoder->time_out[0], | 186 | ci->pcmbuf_insert(decoder->time_out[0], decoder->time_out[1], |
187 | decoder->time_out[1], | 187 | frame_info.samples >> 1); |
188 | frame_info.samples * 2)) | ||
189 | { | ||
190 | ci->sleep(1); | ||
191 | } | ||
192 | 188 | ||
193 | /* Update the elapsed-time indicator */ | 189 | /* Update the elapsed-time indicator */ |
194 | sound_samples_done += sample_duration; | 190 | 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: | |||
320 | } | 320 | } |
321 | } | 321 | } |
322 | 322 | ||
323 | /* 2 bytes per sample */ | 323 | if (channels == 2) |
324 | while (!ci->pcmbuf_insert((char *)samples, sampleswritten*2)) | 324 | sampleswritten >>= 1; /* make samples/channel */ |
325 | ci->yield(); | 325 | |
326 | ci->pcmbuf_insert(samples, NULL, sampleswritten); | ||
326 | 327 | ||
327 | ci->set_elapsed( | 328 | ci->set_elapsed( |
328 | ((end_adr-start_adr)*loop_count + bufoff-chanstart)* | 329 | ((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) | |||
51 | uint16_t sample_size = 0; | 51 | uint16_t sample_size = 0; |
52 | uint32_t sample_rate = 0; | 52 | uint32_t sample_rate = 0; |
53 | uint32_t i; | 53 | uint32_t i; |
54 | size_t n, bufsize; | 54 | size_t n; |
55 | int bufcount; | ||
55 | int endofstream; | 56 | int endofstream; |
56 | unsigned char *buf; | 57 | unsigned char *buf; |
57 | uint8_t *aifbuf; | 58 | uint8_t *aifbuf; |
@@ -229,25 +230,27 @@ next_track: | |||
229 | samples[i/4] = (SE(aifbuf[i])<<21)|(aifbuf[i + 1]<<13) | 230 | samples[i/4] = (SE(aifbuf[i])<<21)|(aifbuf[i + 1]<<13) |
230 | |(aifbuf[i + 2]<<5)|(aifbuf[i + 3]>>3); | 231 | |(aifbuf[i + 2]<<5)|(aifbuf[i + 3]>>3); |
231 | } | 232 | } |
232 | bufsize = n; | 233 | bufcount = n >> 2; |
233 | } else if (sample_size > 16) { | 234 | } else if (sample_size > 16) { |
234 | for (i = 0; i < n; i += 3) { | 235 | for (i = 0; i < n; i += 3) { |
235 | samples[i/3] = (SE(aifbuf[i])<<21)|(aifbuf[i + 1]<<13) | 236 | samples[i/3] = (SE(aifbuf[i])<<21)|(aifbuf[i + 1]<<13) |
236 | |(aifbuf[i + 2]<<5); | 237 | |(aifbuf[i + 2]<<5); |
237 | } | 238 | } |
238 | bufsize = n*4/3; | 239 | bufcount = n/3; |
239 | } else if (sample_size > 8) { | 240 | } else if (sample_size > 8) { |
240 | for (i = 0; i < n; i += 2) | 241 | for (i = 0; i < n; i += 2) |
241 | samples[i/2] = (SE(aifbuf[i])<<21)|(aifbuf[i + 1]<<13); | 242 | samples[i/2] = (SE(aifbuf[i])<<21)|(aifbuf[i + 1]<<13); |
242 | bufsize = n*2; | 243 | bufcount = n >> 1; |
243 | } else { | 244 | } else { |
244 | for (i = 0; i < n; i++) | 245 | for (i = 0; i < n; i++) |
245 | samples[i] = SE(aifbuf[i]) << 21; | 246 | samples[i] = SE(aifbuf[i]) << 21; |
246 | bufsize = n*4; | 247 | bufcount = n; |
247 | } | 248 | } |
248 | 249 | ||
249 | while (!ci->pcmbuf_insert((char *)samples, bufsize)) | 250 | if (num_channels == 2) |
250 | ci->yield(); | 251 | bufcount >>= 1; |
252 | |||
253 | ci->pcmbuf_insert(samples, NULL, bufcount); | ||
251 | 254 | ||
252 | ci->advance_buffer(n); | 255 | ci->advance_buffer(n); |
253 | bytesdone += n; | 256 | 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) | |||
121 | 121 | ||
122 | /* Output the audio */ | 122 | /* Output the audio */ |
123 | ci->yield(); | 123 | ci->yield(); |
124 | while(!ci->pcmbuf_insert_split(outputbuffer[0], | 124 | ci->pcmbuf_insert(outputbuffer[0], outputbuffer[1], samplesdecoded); |
125 | outputbuffer[1], | ||
126 | samplesdecoded*sizeof(int32_t))) | ||
127 | ci->yield(); | ||
128 | 125 | ||
129 | /* Update the elapsed-time indicator */ | 126 | /* Update the elapsed-time indicator */ |
130 | samplesdone+=sample_duration; | 127 | 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) | |||
489 | frame++; | 489 | frame++; |
490 | 490 | ||
491 | ci->yield(); | 491 | ci->yield(); |
492 | while(!ci->pcmbuf_insert_split((char*)&decoded0[fc.sample_skip], | 492 | ci->pcmbuf_insert(&decoded0[fc.sample_skip], &decoded1[fc.sample_skip], |
493 | (char*)&decoded1[fc.sample_skip], | 493 | fc.blocksize - fc.sample_skip); |
494 | (fc.blocksize-fc.sample_skip)*4)) { | ||
495 | ci->yield(); | ||
496 | } | ||
497 | 494 | ||
498 | fc.sample_skip = 0; | 495 | fc.sample_skip = 0; |
499 | 496 | ||
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: | |||
199 | loop we will need to process the final frame that was decoded. */ | 199 | loop we will need to process the final frame that was decoded. */ |
200 | if (framelength > 0) { | 200 | if (framelength > 0) { |
201 | /* In case of a mono file, the second array will be ignored. */ | 201 | /* In case of a mono file, the second array will be ignored. */ |
202 | ci->pcmbuf_insert_split(&synth.pcm.samples[0][samples_to_skip], | 202 | ci->pcmbuf_insert(&synth.pcm.samples[0][samples_to_skip], |
203 | &synth.pcm.samples[1][samples_to_skip], | 203 | &synth.pcm.samples[1][samples_to_skip], |
204 | framelength * 4); | 204 | framelength); |
205 | 205 | ||
206 | /* Only skip samples for the first frame added. */ | 206 | /* Only skip samples for the first frame added. */ |
207 | samples_to_skip = 0; | 207 | samples_to_skip = 0; |
@@ -244,8 +244,8 @@ next_track: | |||
244 | /* Finish the remaining decoded frame. | 244 | /* Finish the remaining decoded frame. |
245 | Cut the required samples from the end. */ | 245 | Cut the required samples from the end. */ |
246 | if (framelength > stop_skip) | 246 | if (framelength > stop_skip) |
247 | ci->pcmbuf_insert_split(synth.pcm.samples[0], synth.pcm.samples[1], | 247 | ci->pcmbuf_insert(synth.pcm.samples[0], synth.pcm.samples[1], |
248 | (framelength - stop_skip) * 4); | 248 | framelength - stop_skip); |
249 | 249 | ||
250 | stream.error = 0; | 250 | stream.error = 0; |
251 | 251 | ||
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: | |||
168 | retval = CODEC_ERROR; | 168 | retval = CODEC_ERROR; |
169 | goto done; | 169 | goto done; |
170 | } else { | 170 | } else { |
171 | while (!ci->pcmbuf_insert_split(sample_buffer, | 171 | ci->pcmbuf_insert(sample_buffer, |
172 | sample_buffer + MPC_FRAME_LENGTH, | 172 | sample_buffer + MPC_FRAME_LENGTH, |
173 | status*sizeof(MPC_SAMPLE_FORMAT))) | 173 | status); |
174 | ci->yield(); | ||
175 | samplesdone += status; | 174 | samplesdone += status; |
176 | ci->set_elapsed(samplesdone/frequency); | 175 | ci->set_elapsed(samplesdone/frequency); |
177 | } | 176 | } |
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: | |||
4445 | goto init_nsf; | 4445 | goto init_nsf; |
4446 | } | 4446 | } |
4447 | 4447 | ||
4448 | while (!ci->pcmbuf_insert((char *)samples, written)) | 4448 | ci->pcmbuf_insert(samples, NULL, written >> 1); |
4449 | ci->yield(); | ||
4450 | |||
4451 | } | 4449 | } |
4452 | 4450 | ||
4453 | print_timers(last_path,track); | 4451 | 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: | |||
134 | /* Insert decoded samples in pcmbuf */ | 134 | /* Insert decoded samples in pcmbuf */ |
135 | if (nsamples) { | 135 | if (nsamples) { |
136 | ci->yield(); | 136 | ci->yield(); |
137 | while (!ci->pcmbuf_insert_split((char*)(decoded0 + sc.nwrap), | 137 | ci->pcmbuf_insert(decoded0 + sc.nwrap, decoded1 + sc.nwrap, |
138 | (char*)(decoded1 + sc.nwrap), | 138 | nsamples); |
139 | 4*nsamples)) { | ||
140 | ci->yield(); | ||
141 | } | ||
142 | 139 | ||
143 | /* Update the elapsed-time indicator */ | 140 | /* Update the elapsed-time indicator */ |
144 | samplesdone += nsamples; | 141 | 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: | |||
1309 | } | 1309 | } |
1310 | } | 1310 | } |
1311 | 1311 | ||
1312 | while (!ci->pcmbuf_insert((char *)samples, CHUNK_SIZE*4)) | 1312 | ci->pcmbuf_insert(samples, NULL, CHUNK_SIZE); |
1313 | ci->yield(); | ||
1314 | } | 1313 | } |
1315 | 1314 | ||
1316 | if (ci->request_next_track()) | 1315 | 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: | |||
217 | } else if (n < 0) { | 217 | } else if (n < 0) { |
218 | DEBUGF("Error decoding frame\n"); | 218 | DEBUGF("Error decoding frame\n"); |
219 | } else { | 219 | } else { |
220 | while (!ci->pcmbuf_insert_split(pcm[0], pcm[1], | 220 | ci->pcmbuf_insert(pcm[0], pcm[1], n); |
221 | n*sizeof(ogg_int32_t))) { | ||
222 | ci->sleep(1); | ||
223 | } | ||
224 | ci->set_offset(ov_raw_tell(&vf)); | 221 | ci->set_offset(ov_raw_tell(&vf)); |
225 | ci->set_elapsed(ov_time_tell(&vf)); | 222 | ci->set_elapsed(ov_time_tell(&vf)); |
226 | } | 223 | } |
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) | |||
212 | int bytespersample = 0; | 212 | int bytespersample = 0; |
213 | uint16_t bitspersample; | 213 | uint16_t bitspersample; |
214 | uint32_t i; | 214 | uint32_t i; |
215 | size_t n, bufsize; | 215 | size_t n; |
216 | int bufcount; | ||
216 | int endofstream; | 217 | int endofstream; |
217 | unsigned char *buf; | 218 | unsigned char *buf; |
218 | uint8_t *wavbuf; | 219 | uint8_t *wavbuf; |
@@ -466,34 +467,39 @@ next_track: | |||
466 | (wavbuf[i + 1]<<5)|(wavbuf[i + 2]<<13)| | 467 | (wavbuf[i + 1]<<5)|(wavbuf[i + 2]<<13)| |
467 | (SE(wavbuf[i + 3])<<21); | 468 | (SE(wavbuf[i + 3])<<21); |
468 | } | 469 | } |
469 | bufsize = n; | 470 | bufcount = n >> 2; |
470 | } else if (bitspersample > 16) { | 471 | } else if (bitspersample > 16) { |
471 | for (i = 0; i < n; i += 3) { | 472 | for (i = 0; i < n; i += 3) { |
472 | samples[i/3] = (wavbuf[i]<<5)| | 473 | samples[i/3] = (wavbuf[i]<<5)| |
473 | (wavbuf[i + 1]<<13)|(SE(wavbuf[i + 2])<<21); | 474 | (wavbuf[i + 1]<<13)|(SE(wavbuf[i + 2])<<21); |
474 | } | 475 | } |
475 | bufsize = n*4/3; | 476 | bufcount = n/3; |
476 | } else if (bitspersample > 8) { | 477 | } else if (bitspersample > 8) { |
477 | for (i = 0; i < n; i += 2) { | 478 | for (i = 0; i < n; i += 2) { |
478 | samples[i/2] = (wavbuf[i]<<13)|(SE(wavbuf[i + 1])<<21); | 479 | samples[i/2] = (wavbuf[i]<<13)|(SE(wavbuf[i + 1])<<21); |
479 | } | 480 | } |
480 | bufsize = n*2; | 481 | bufcount = n >> 1; |
481 | } else { | 482 | } else { |
482 | for (i = 0; i < n; i++) { | 483 | for (i = 0; i < n; i++) { |
483 | samples[i] = (wavbuf[i] - 0x80)<<21; | 484 | samples[i] = (wavbuf[i] - 0x80)<<21; |
484 | } | 485 | } |
485 | bufsize = n*4; | 486 | bufcount = n; |
486 | } | 487 | } |
488 | |||
489 | if (channels == 2) | ||
490 | bufcount >>= 1; | ||
487 | } else if (formattag == WAVE_FORMAT_ALAW | 491 | } else if (formattag == WAVE_FORMAT_ALAW |
488 | || formattag == IBM_FORMAT_ALAW) { | 492 | || formattag == IBM_FORMAT_ALAW) { |
489 | for (i = 0; i < n; i++) | 493 | for (i = 0; i < n; i++) |
490 | samples[i] = alaw2linear16[wavbuf[i]] << 13; | 494 | samples[i] = alaw2linear16[wavbuf[i]] << 13; |
491 | bufsize = n*4; | 495 | |
496 | bufcount = (channels == 2) ? (n >> 1) : n; | ||
492 | } else if (formattag == WAVE_FORMAT_MULAW | 497 | } else if (formattag == WAVE_FORMAT_MULAW |
493 | || formattag == IBM_FORMAT_MULAW) { | 498 | || formattag == IBM_FORMAT_MULAW) { |
494 | for (i = 0; i < n; i++) | 499 | for (i = 0; i < n; i++) |
495 | samples[i] = ulaw2linear16[wavbuf[i]] << 13; | 500 | samples[i] = ulaw2linear16[wavbuf[i]] << 13; |
496 | bufsize = n*4; | 501 | |
502 | bufcount = (channels == 2) ? (n >> 1) : n; | ||
497 | } | 503 | } |
498 | else if (formattag == WAVE_FORMAT_DVI_ADPCM) { | 504 | else if (formattag == WAVE_FORMAT_DVI_ADPCM) { |
499 | unsigned int nblocks = chunksize/blockalign; | 505 | unsigned int nblocks = chunksize/blockalign; |
@@ -508,15 +514,14 @@ next_track: | |||
508 | goto done; | 514 | goto done; |
509 | } | 515 | } |
510 | } | 516 | } |
511 | bufsize = nblocks*samplesperblock*channels*4; | 517 | bufcount = nblocks*samplesperblock; |
512 | } else { | 518 | } else { |
513 | DEBUGF("CODEC_ERROR: unsupported format %x\n", formattag); | 519 | DEBUGF("CODEC_ERROR: unsupported format %x\n", formattag); |
514 | i = CODEC_ERROR; | 520 | i = CODEC_ERROR; |
515 | goto done; | 521 | goto done; |
516 | } | 522 | } |
517 | 523 | ||
518 | while (!ci->pcmbuf_insert((char *)samples, bufsize)) | 524 | ci->pcmbuf_insert(samples, NULL, bufcount); |
519 | ci->yield(); | ||
520 | 525 | ||
521 | ci->advance_buffer(n); | 526 | ci->advance_buffer(n); |
522 | bytesdone += n; | 527 | 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) | |||
118 | if (ci->stop_codec || ci->new_track) | 118 | if (ci->stop_codec || ci->new_track) |
119 | break; | 119 | break; |
120 | 120 | ||
121 | while (!ci->pcmbuf_insert ((char *) temp_buffer, nsamples * nchans * 4)) | 121 | ci->pcmbuf_insert (temp_buffer, NULL, nsamples); |
122 | ci->sleep (1); | ||
123 | 122 | ||
124 | ci->set_elapsed (WavpackGetSampleIndex (wpc) / sr_100 * 10); | 123 | ci->set_elapsed (WavpackGetSampleIndex (wpc) / sr_100 * 10); |
125 | ci->yield (); | 124 | 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 @@ | |||
40 | #define WORD_FRACBITS 27 | 40 | #define WORD_FRACBITS 27 |
41 | 41 | ||
42 | #define NATIVE_DEPTH 16 | 42 | #define NATIVE_DEPTH 16 |
43 | #define SAMPLE_BUF_SIZE 256 | 43 | #define SAMPLE_BUF_COUNT 256 |
44 | #define RESAMPLE_BUF_SIZE (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/ | 44 | #define RESAMPLE_BUF_COUNT (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/ |
45 | #define DEFAULT_GAIN 0x01000000 | 45 | #define DEFAULT_GAIN 0x01000000 |
46 | 46 | ||
47 | struct dsp_config | 47 | struct dsp_config |
@@ -116,8 +116,8 @@ static struct dsp_config *dsp; | |||
116 | * of copying needed is minimized for that case. | 116 | * of copying needed is minimized for that case. |
117 | */ | 117 | */ |
118 | 118 | ||
119 | static int32_t sample_buf[SAMPLE_BUF_SIZE] IBSS_ATTR; | 119 | static int32_t sample_buf[SAMPLE_BUF_COUNT] IBSS_ATTR; |
120 | static int32_t resample_buf[RESAMPLE_BUF_SIZE] IBSS_ATTR; | 120 | static int32_t resample_buf[RESAMPLE_BUF_COUNT] IBSS_ATTR; |
121 | 121 | ||
122 | int sound_get_pitch(void) | 122 | int sound_get_pitch(void) |
123 | { | 123 | { |
@@ -139,14 +139,14 @@ void sound_set_pitch(int permille) | |||
139 | */ | 139 | */ |
140 | static int convert_to_internal(const char* src[], int count, int32_t* dst[]) | 140 | static int convert_to_internal(const char* src[], int count, int32_t* dst[]) |
141 | { | 141 | { |
142 | count = MIN(SAMPLE_BUF_SIZE / 2, count); | 142 | count = MIN(SAMPLE_BUF_COUNT / 2, count); |
143 | 143 | ||
144 | if ((dsp->sample_depth <= NATIVE_DEPTH) | 144 | if ((dsp->sample_depth <= NATIVE_DEPTH) |
145 | || (dsp->stereo_mode == STEREO_INTERLEAVED)) | 145 | || (dsp->stereo_mode == STEREO_INTERLEAVED)) |
146 | { | 146 | { |
147 | dst[0] = &sample_buf[0]; | 147 | dst[0] = &sample_buf[0]; |
148 | dst[1] = (dsp->stereo_mode == STEREO_MONO) | 148 | dst[1] = (dsp->stereo_mode == STEREO_MONO) |
149 | ? dst[0] : &sample_buf[SAMPLE_BUF_SIZE / 2]; | 149 | ? dst[0] : &sample_buf[SAMPLE_BUF_COUNT / 2]; |
150 | } | 150 | } |
151 | else | 151 | else |
152 | { | 152 | { |
@@ -231,7 +231,7 @@ static void resampler_set_delta(int frequency) | |||
231 | 231 | ||
232 | /* TODO: we really should have a separate set of resample functions for both | 232 | /* TODO: we really should have a separate set of resample functions for both |
233 | mono and stereo to avoid all this internal branching and looping. */ | 233 | mono and stereo to avoid all this internal branching and looping. */ |
234 | static long downsample(int32_t **dst, int32_t **src, int count, | 234 | static int downsample(int32_t **dst, int32_t **src, int count, |
235 | struct resample_data *r) | 235 | struct resample_data *r) |
236 | { | 236 | { |
237 | long phase = r->phase; | 237 | long phase = r->phase; |
@@ -246,11 +246,14 @@ static long downsample(int32_t **dst, int32_t **src, int count, | |||
246 | last_sample = r->last_sample[j]; | 246 | last_sample = r->last_sample[j]; |
247 | /* Do we need last sample of previous frame for interpolation? */ | 247 | /* Do we need last sample of previous frame for interpolation? */ |
248 | if (pos > 0) | 248 | if (pos > 0) |
249 | { | ||
250 | last_sample = src[j][pos - 1]; | 249 | last_sample = src[j][pos - 1]; |
251 | } | 250 | |
252 | *d[j]++ = last_sample + FRACMUL((phase & 0xffff) << 15, | 251 | /* Be sure starting position isn't passed the available data */ |
253 | src[j][pos] - last_sample); | 252 | if (pos < count) |
253 | *d[j]++ = last_sample + FRACMUL((phase & 0xffff) << 15, | ||
254 | src[j][pos] - last_sample); | ||
255 | else /* This is kinda nasty but works somewhat well for now */ | ||
256 | *d[j]++ = src[j][count - 1]; | ||
254 | } | 257 | } |
255 | phase += delta; | 258 | phase += delta; |
256 | 259 | ||
@@ -316,7 +319,7 @@ static inline int resample(int32_t* src[], int count) | |||
316 | 319 | ||
317 | if (dsp->frequency != NATIVE_FREQUENCY) | 320 | if (dsp->frequency != NATIVE_FREQUENCY) |
318 | { | 321 | { |
319 | int32_t* dst[2] = {&resample_buf[0], &resample_buf[RESAMPLE_BUF_SIZE / 2]}; | 322 | int32_t* dst[2] = {&resample_buf[0], &resample_buf[RESAMPLE_BUF_COUNT / 2]}; |
320 | 323 | ||
321 | if (dsp->frequency < NATIVE_FREQUENCY) | 324 | if (dsp->frequency < NATIVE_FREQUENCY) |
322 | { | 325 | { |
@@ -619,7 +622,7 @@ static void apply_gain(int32_t* _src[], int _count) | |||
619 | 622 | ||
620 | if (s0 != s1) | 623 | if (s0 != s1) |
621 | { | 624 | { |
622 | d = &sample_buf[SAMPLE_BUF_SIZE / 2]; | 625 | d = &sample_buf[SAMPLE_BUF_COUNT / 2]; |
623 | src[1] = d; | 626 | src[1] = d; |
624 | s = *s1++; | 627 | s = *s1++; |
625 | 628 | ||
@@ -736,18 +739,17 @@ static void write_samples(short* dst, int32_t* src[], int count) | |||
736 | } | 739 | } |
737 | 740 | ||
738 | /* Process and convert src audio to dst based on the DSP configuration, | 741 | /* Process and convert src audio to dst based on the DSP configuration, |
739 | * reading size bytes of audio data. dst is assumed to be large enough; use | 742 | * reading count number of audio samples. dst is assumed to be large |
740 | * dst_get_dest_size() to get the required size. src is an array of | 743 | * enough; use dsp_output_count() to get the required number. src is an |
741 | * pointers; for mono and interleaved stereo, it contains one pointer to the | 744 | * array of pointers; for mono and interleaved stereo, it contains one |
742 | * start of the audio data; for non-interleaved stereo, it contains two | 745 | * pointer to the start of the audio data and the other is ignored; for |
743 | * pointers, one for each audio channel. Returns number of bytes written to | 746 | * non-interleaved stereo, it contains two pointers, one for each audio |
744 | * dest. | 747 | * channel. Returns number of bytes written to dst. |
745 | */ | 748 | */ |
746 | long dsp_process(char* dst, const char* src[], long size) | 749 | int dsp_process(char *dst, const char *src[], int count) |
747 | { | 750 | { |
748 | int32_t* tmp[2]; | 751 | int32_t* tmp[2]; |
749 | long written = 0; | 752 | int written = 0; |
750 | long factor; | ||
751 | int samples; | 753 | int samples; |
752 | 754 | ||
753 | #if defined(CPU_COLDFIRE) && !defined(SIMULATOR) | 755 | #if defined(CPU_COLDFIRE) && !defined(SIMULATOR) |
@@ -759,14 +761,12 @@ long dsp_process(char* dst, const char* src[], long size) | |||
759 | 761 | ||
760 | dsp = &dsp_conf[current_codec]; | 762 | dsp = &dsp_conf[current_codec]; |
761 | 763 | ||
762 | factor = (dsp->stereo_mode != STEREO_MONO) ? 2 : 1; | ||
763 | size /= dsp->sample_bytes * factor; | ||
764 | dsp_set_replaygain(false); | 764 | dsp_set_replaygain(false); |
765 | 765 | ||
766 | while (size > 0) | 766 | while (count > 0) |
767 | { | 767 | { |
768 | samples = convert_to_internal(src, size, tmp); | 768 | samples = convert_to_internal(src, count, tmp); |
769 | size -= samples; | 769 | count -= samples; |
770 | apply_gain(tmp, samples); | 770 | apply_gain(tmp, samples); |
771 | samples = resample(tmp, samples); | 771 | samples = resample(tmp, samples); |
772 | if (dsp->crossfeed_enabled && dsp->stereo_mode != STEREO_MONO) | 772 | if (dsp->crossfeed_enabled && dsp->stereo_mode != STEREO_MONO) |
@@ -780,85 +780,61 @@ long dsp_process(char* dst, const char* src[], long size) | |||
780 | dst += samples * sizeof(short) * 2; | 780 | dst += samples * sizeof(short) * 2; |
781 | yield(); | 781 | yield(); |
782 | } | 782 | } |
783 | |||
783 | #if defined(CPU_COLDFIRE) && !defined(SIMULATOR) | 784 | #if defined(CPU_COLDFIRE) && !defined(SIMULATOR) |
784 | /* set old macsr again */ | 785 | /* set old macsr again */ |
785 | coldfire_set_macsr(old_macsr); | 786 | coldfire_set_macsr(old_macsr); |
786 | #endif | 787 | #endif |
787 | return written * sizeof(short) * 2; | 788 | return written; |
788 | } | 789 | } |
789 | 790 | ||
790 | /* Given size bytes of input data, calculate the maximum number of bytes of | 791 | /* Given count number of input samples, calculate the maximum number of |
791 | * output data that would be generated (the calculation is not entirely | 792 | * samples of output data that would be generated (the calculation is not |
792 | * exact and rounds upwards to be on the safe side; during resampling, | 793 | * entirely exact and rounds upwards to be on the safe side; during |
793 | * the number of samples generated depends on the current state of the | 794 | * resampling, the number of samples generated depends on the current state |
794 | * resampler). | 795 | * of the resampler). |
795 | */ | 796 | */ |
796 | /* dsp_input_size MUST be called afterwards */ | 797 | /* dsp_input_size MUST be called afterwards */ |
797 | long dsp_output_size(long size) | 798 | int dsp_output_count(int count) |
798 | { | 799 | { |
799 | dsp = &dsp_conf[current_codec]; | 800 | dsp = &dsp_conf[current_codec]; |
800 | 801 | ||
801 | if (dsp->sample_depth > NATIVE_DEPTH) | ||
802 | { | ||
803 | size /= 2; | ||
804 | } | ||
805 | |||
806 | if (dsp->frequency != NATIVE_FREQUENCY) | 802 | if (dsp->frequency != NATIVE_FREQUENCY) |
807 | { | 803 | { |
808 | size = (long) ((((unsigned long) size * NATIVE_FREQUENCY) | 804 | count = (int)(((unsigned long)count * NATIVE_FREQUENCY |
809 | + (dsp->frequency - 1)) / dsp->frequency); | 805 | + (dsp->frequency - 1)) / dsp->frequency); |
810 | } | ||
811 | |||
812 | /* round to the next multiple of 2 (these are shorts) */ | ||
813 | size = (size + 1) & ~1; | ||
814 | |||
815 | if (dsp->stereo_mode == STEREO_MONO) | ||
816 | { | ||
817 | size *= 2; | ||
818 | } | 806 | } |
819 | 807 | ||
820 | /* now we have the size in bytes for two resampled channels, | 808 | /* Now we have the resampled sample count which must not exceed |
821 | * and the size in (short) must not exceed RESAMPLE_BUF_SIZE to | 809 | * RESAMPLE_BUF_COUNT/2 to avoid resample buffer overflow. One |
822 | * avoid resample buffer overflow. One must call dsp_input_size() | 810 | * must call dsp_input_count() to get the correct input sample |
823 | * to get the correct input buffer size. */ | 811 | * count. |
824 | if (size > RESAMPLE_BUF_SIZE*2) | 812 | */ |
825 | size = RESAMPLE_BUF_SIZE*2; | 813 | if (count > RESAMPLE_BUF_COUNT/2) |
814 | count = RESAMPLE_BUF_COUNT/2; | ||
826 | 815 | ||
827 | return size; | 816 | return count; |
828 | } | 817 | } |
829 | 818 | ||
830 | /* Given size bytes of output buffer, calculate number of bytes of input | 819 | /* Given count output samples, calculate number of input samples |
831 | * data that would be consumed in order to fill the output buffer. | 820 | * that would be consumed in order to fill the output buffer. |
832 | */ | 821 | */ |
833 | long dsp_input_size(long size) | 822 | int dsp_input_count(int count) |
834 | { | 823 | { |
835 | dsp = &dsp_conf[current_codec]; | 824 | dsp = &dsp_conf[current_codec]; |
836 | |||
837 | /* convert to number of output stereo samples. */ | ||
838 | size /= 2; | ||
839 | 825 | ||
840 | /* Mono means we need half input samples to fill the output buffer */ | 826 | /* count is now the number of resampled input samples. Convert to |
841 | if (dsp->stereo_mode == STEREO_MONO) | ||
842 | size /= 2; | ||
843 | |||
844 | /* size is now the number of resampled input samples. Convert to | ||
845 | original input samples. */ | 827 | original input samples. */ |
846 | if (dsp->frequency != NATIVE_FREQUENCY) | 828 | if (dsp->frequency != NATIVE_FREQUENCY) |
847 | { | 829 | { |
848 | /* Use the real resampling delta = | 830 | /* Use the real resampling delta = |
849 | * (unsigned long) dsp->frequency * 65536 / NATIVE_FREQUENCY, and | 831 | * dsp->frequency * 65536 / NATIVE_FREQUENCY, and |
850 | * round towards zero to avoid buffer overflows. */ | 832 | * round towards zero to avoid buffer overflows. */ |
851 | size = ((unsigned long)size * | 833 | count = (int)(((unsigned long)count * |
852 | resample_data[current_codec].delta) >> 16; | 834 | resample_data[current_codec].delta) >> 16); |
853 | } | 835 | } |
854 | 836 | ||
855 | /* Convert back to bytes. */ | 837 | return count; |
856 | if (dsp->sample_depth > NATIVE_DEPTH) | ||
857 | size *= 4; | ||
858 | else | ||
859 | size *= 2; | ||
860 | |||
861 | return size; | ||
862 | } | 838 | } |
863 | 839 | ||
864 | int dsp_stereo_mode(void) | 840 | 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 { | |||
206 | 206 | ||
207 | #define DIV64(x, y, z) (long)(((long long)(x) << (z))/(y)) | 207 | #define DIV64(x, y, z) (long)(((long long)(x) << (z))/(y)) |
208 | 208 | ||
209 | long dsp_process(char *dest, const char *src[], long size); | 209 | int dsp_process(char *dest, const char *src[], int count); |
210 | long dsp_input_size(long size); | 210 | int dsp_input_count(int count); |
211 | long dsp_output_size(long size); | 211 | int dsp_output_count(int count); |
212 | int dsp_stereo_mode(void); | 212 | int dsp_stereo_mode(void); |
213 | bool dsp_configure(int setting, void *value); | 213 | bool dsp_configure(int setting, void *value); |
214 | void dsp_set_replaygain(bool always); | 214 | 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) | |||
791 | return true; | 791 | return true; |
792 | } | 792 | } |
793 | 793 | ||
794 | void* pcmbuf_request_buffer(size_t length, size_t *realsize) | 794 | void* pcmbuf_request_buffer(int *count) |
795 | { | 795 | { |
796 | if (crossfade_init) | 796 | if (crossfade_init) |
797 | crossfade_start(); | 797 | crossfade_start(); |
798 | 798 | ||
799 | if (crossfade_active) { | 799 | if (crossfade_active) { |
800 | *realsize = MIN(length, PCMBUF_MIX_CHUNK); | 800 | *count = MIN(*count, PCMBUF_MIX_CHUNK/4); |
801 | return fadebuf; | 801 | return fadebuf; |
802 | } | 802 | } |
803 | else | 803 | else |
804 | { | 804 | { |
805 | if(prepare_insert(length)) | 805 | if(prepare_insert(*count << 2)) |
806 | { | 806 | { |
807 | size_t audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos; | 807 | size_t audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos; |
808 | *realsize = length; | ||
809 | if (pcmbuf_size - audiobuffer_index >= PCMBUF_MIN_CHUNK) | 808 | if (pcmbuf_size - audiobuffer_index >= PCMBUF_MIN_CHUNK) |
810 | { | 809 | { |
811 | /* Usual case, there's space here */ | 810 | /* Usual case, there's space here */ |
@@ -821,34 +820,31 @@ void* pcmbuf_request_buffer(size_t length, size_t *realsize) | |||
821 | } | 820 | } |
822 | else | 821 | else |
823 | { | 822 | { |
824 | *realsize = 0; | ||
825 | return NULL; | 823 | return NULL; |
826 | } | 824 | } |
827 | } | 825 | } |
828 | } | 826 | } |
829 | 827 | ||
830 | void* pcmbuf_request_voice_buffer(size_t length, size_t *realsize, bool mix) | 828 | void* pcmbuf_request_voice_buffer(int *count, bool mix) |
831 | { | 829 | { |
832 | if (mix) | 830 | if (mix) |
833 | { | 831 | { |
834 | if (pcmbuf_read == NULL) | 832 | if (pcmbuf_read == NULL) |
835 | { | 833 | { |
836 | *realsize = 0; | ||
837 | return NULL; | 834 | return NULL; |
838 | } | 835 | } |
839 | else if (pcmbuf_mix_chunk || pcmbuf_read->link) | 836 | else if (pcmbuf_mix_chunk || pcmbuf_read->link) |
840 | { | 837 | { |
841 | *realsize = MIN(length, PCMBUF_MIX_CHUNK); | 838 | *count = MIN(*count, PCMBUF_MIX_CHUNK/4); |
842 | return voicebuf; | 839 | return voicebuf; |
843 | } | 840 | } |
844 | else | 841 | else |
845 | { | 842 | { |
846 | *realsize = 0; | ||
847 | return NULL; | 843 | return NULL; |
848 | } | 844 | } |
849 | } | 845 | } |
850 | else | 846 | else |
851 | return pcmbuf_request_buffer(length, realsize); | 847 | return pcmbuf_request_buffer(count); |
852 | } | 848 | } |
853 | 849 | ||
854 | bool pcmbuf_is_crossfade_active(void) | 850 | bool pcmbuf_is_crossfade_active(void) |
@@ -856,8 +852,10 @@ bool pcmbuf_is_crossfade_active(void) | |||
856 | return crossfade_active || crossfade_init; | 852 | return crossfade_active || crossfade_init; |
857 | } | 853 | } |
858 | 854 | ||
859 | void pcmbuf_write_complete(size_t length) | 855 | void pcmbuf_write_complete(int count) |
860 | { | 856 | { |
857 | size_t length = (size_t)(unsigned int)count << 2; | ||
858 | |||
861 | if (crossfade_active) | 859 | if (crossfade_active) |
862 | { | 860 | { |
863 | flush_crossfade(fadebuf, length); | 861 | flush_crossfade(fadebuf, length); |
@@ -874,8 +872,10 @@ void pcmbuf_write_complete(size_t length) | |||
874 | } | 872 | } |
875 | 873 | ||
876 | #if 0 | 874 | #if 0 |
877 | bool pcmbuf_insert_buffer(char *buf, size_t length) | 875 | bool pcmbuf_insert_buffer(char *buf, int count) |
878 | { | 876 | { |
877 | size_t length = (size_t)(unsigned int)count << 2; | ||
878 | |||
879 | if (crossfade_active) | 879 | if (crossfade_active) |
880 | { | 880 | { |
881 | flush_crossfade(buf, length); | 881 | flush_crossfade(buf, length); |
@@ -980,7 +980,7 @@ int pcmbuf_mix_free(void) | |||
980 | return 100; | 980 | return 100; |
981 | } | 981 | } |
982 | 982 | ||
983 | void pcmbuf_mix_voice(size_t length) | 983 | void pcmbuf_mix_voice(int count) |
984 | { | 984 | { |
985 | short *ibuf = (short *)voicebuf; | 985 | short *ibuf = (short *)voicebuf; |
986 | short *obuf; | 986 | short *obuf; |
@@ -998,9 +998,9 @@ void pcmbuf_mix_voice(size_t length) | |||
998 | obuf = (short *)pcmbuf_mix_chunk->addr; | 998 | obuf = (short *)pcmbuf_mix_chunk->addr; |
999 | chunk_samples = pcmbuf_mix_chunk->size / 2; | 999 | chunk_samples = pcmbuf_mix_chunk->size / 2; |
1000 | 1000 | ||
1001 | length /= 2; | 1001 | count <<= 1; |
1002 | 1002 | ||
1003 | while (length-- > 0) { | 1003 | while (count-- > 0) { |
1004 | int sample = *ibuf++; | 1004 | int sample = *ibuf++; |
1005 | if (pcmbuf_mix_sample >= chunk_samples) | 1005 | if (pcmbuf_mix_sample >= chunk_samples) |
1006 | { | 1006 | { |
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)); | |||
63 | size_t pcmbuf_free(void); | 63 | size_t pcmbuf_free(void); |
64 | unsigned int pcmbuf_get_latency(void); | 64 | unsigned int pcmbuf_get_latency(void); |
65 | void pcmbuf_set_low_latency(bool state); | 65 | void pcmbuf_set_low_latency(bool state); |
66 | void pcmbuf_write_complete(size_t length); | 66 | void pcmbuf_write_complete(int count); |
67 | void* pcmbuf_request_buffer(size_t length, size_t *realsize); | 67 | void* pcmbuf_request_buffer(int *count); |
68 | void* pcmbuf_request_voice_buffer(size_t length, size_t *realsize, bool mix); | 68 | void* pcmbuf_request_voice_buffer(int *count, bool mix); |
69 | bool pcmbuf_is_crossfade_enabled(void); | 69 | bool pcmbuf_is_crossfade_enabled(void); |
70 | void pcmbuf_crossfade_enable(bool on_off); | 70 | void pcmbuf_crossfade_enable(bool on_off); |
71 | 71 | ||
72 | int pcmbuf_usage(void); | 72 | int pcmbuf_usage(void); |
73 | int pcmbuf_mix_free(void); | 73 | int pcmbuf_mix_free(void); |
74 | void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude); | 74 | void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude); |
75 | void pcmbuf_mix_voice(size_t length); | 75 | void pcmbuf_mix_voice(int count); |
76 | 76 | ||
77 | int pcmbuf_used_descs(void); | 77 | int pcmbuf_used_descs(void); |
78 | int pcmbuf_descs(void); | 78 | 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) | |||
1022 | 1022 | ||
1023 | #ifdef PLAYBACK_VOICE | 1023 | #ifdef PLAYBACK_VOICE |
1024 | 1024 | ||
1025 | static bool voice_pcmbuf_insert_split_callback( | 1025 | static bool voice_pcmbuf_insert_callback( |
1026 | const void *ch1, const void *ch2, size_t length) | 1026 | const void *ch1, const void *ch2, int count) |
1027 | { | 1027 | { |
1028 | const char* src[2]; | 1028 | const char *src[2] = { ch1, ch2 }; |
1029 | char *dest; | ||
1030 | long input_size; | ||
1031 | size_t output_size; | ||
1032 | 1029 | ||
1033 | src[0] = ch1; | 1030 | while (count > 0) |
1034 | src[1] = ch2; | ||
1035 | |||
1036 | if (dsp_stereo_mode() == STEREO_NONINTERLEAVED) | ||
1037 | length *= 2; /* Length is per channel */ | ||
1038 | |||
1039 | while (length) | ||
1040 | { | 1031 | { |
1041 | long est_output_size = dsp_output_size(length); | 1032 | int out_count = dsp_output_count(count); |
1042 | 1033 | int inp_count; | |
1043 | while ((dest = pcmbuf_request_voice_buffer(est_output_size, | 1034 | char *dest; |
1044 | &output_size, playing)) == NULL) | 1035 | |
1036 | while ((dest = pcmbuf_request_voice_buffer( | ||
1037 | &out_count, playing)) == NULL) | ||
1045 | { | 1038 | { |
1046 | if (playing && audio_codec_loaded) | 1039 | if (playing && audio_codec_loaded) |
1047 | swap_codec(); | 1040 | swap_codec(); |
1048 | else | 1041 | else |
1049 | yield(); | 1042 | yield(); |
1050 | } | 1043 | } |
1051 | 1044 | ||
1052 | /* Get the real input_size for output_size bytes, guarding | 1045 | /* Get the real input_size for output_size bytes, guarding |
1053 | * against resampling buffer overflows. */ | 1046 | * against resampling buffer overflows. */ |
1054 | input_size = dsp_input_size(output_size); | 1047 | inp_count = dsp_input_count(out_count); |
1055 | 1048 | ||
1056 | if (input_size <= 0) | 1049 | if (inp_count <= 0) |
1057 | { | 1050 | { |
1058 | DEBUGF("Error: dsp_input_size(%ld=dsp_output_size(%ld))=%ld<=0\n", | 1051 | DEBUGF("Error: dsp_input_count(%ld=dsp_output_count(%ld))=%ld<=0\n", |
1059 | output_size, length, input_size); | 1052 | out_count, count, inp_count); |
1060 | /* If this happens, there are samples of codec data that don't | 1053 | /* If this happens, there are samples of codec data that don't |
1061 | * become a number of pcm samples, and something is broken */ | 1054 | * become a number of pcm samples, and something is broken */ |
1062 | return false; | 1055 | return false; |
1063 | } | 1056 | } |
1064 | 1057 | ||
1065 | /* Input size has grown, no error, just don't write more than length */ | 1058 | /* Input size has grown, no error, just don't write more than length */ |
1066 | if ((size_t)input_size > length) | 1059 | if (inp_count > count) |
1067 | input_size = length; | 1060 | inp_count = count; |
1068 | 1061 | ||
1069 | output_size = dsp_process(dest, src, input_size); | 1062 | out_count = dsp_process(dest, src, inp_count); |
1070 | 1063 | ||
1071 | if (playing) | 1064 | if (playing) |
1072 | { | 1065 | { |
1073 | pcmbuf_mix_voice(output_size); | 1066 | pcmbuf_mix_voice(out_count); |
1074 | if ((pcmbuf_usage() < 10 || pcmbuf_mix_free() < 30) && | 1067 | if ((pcmbuf_usage() < 10 || pcmbuf_mix_free() < 30) && |
1075 | audio_codec_loaded) | 1068 | audio_codec_loaded) |
1076 | swap_codec(); | 1069 | swap_codec(); |
1077 | } | 1070 | } |
1078 | else | 1071 | else |
1079 | pcmbuf_write_complete(output_size); | 1072 | pcmbuf_write_complete(out_count); |
1080 | 1073 | ||
1081 | length -= input_size; | 1074 | count -= inp_count; |
1082 | } | 1075 | } |
1083 | 1076 | ||
1084 | return true; | 1077 | return true; |
1085 | } /* voice_pcmbuf_insert_split_callback */ | 1078 | } /* voice_pcmbuf_insert_callback */ |
1086 | |||
1087 | static bool voice_pcmbuf_insert_callback(const char *buf, size_t length) | ||
1088 | { | ||
1089 | /* TODO: The audiobuffer API should probably be updated, and be based on | ||
1090 | * pcmbuf_insert_split(). */ | ||
1091 | long real_length = length; | ||
1092 | |||
1093 | if (dsp_stereo_mode() == STEREO_NONINTERLEAVED) | ||
1094 | length /= 2; /* Length is per channel */ | ||
1095 | |||
1096 | /* Second channel is only used for non-interleaved stereo. */ | ||
1097 | return voice_pcmbuf_insert_split_callback(buf, buf + (real_length / 2), | ||
1098 | length); | ||
1099 | } | ||
1100 | 1079 | ||
1101 | static void* voice_get_memory_callback(size_t *size) | 1080 | static void* voice_get_memory_callback(size_t *size) |
1102 | { | 1081 | { |
@@ -1321,30 +1300,22 @@ static void voice_thread(void) | |||
1321 | #endif /* PLAYBACK_VOICE */ | 1300 | #endif /* PLAYBACK_VOICE */ |
1322 | 1301 | ||
1323 | /* --- Codec thread --- */ | 1302 | /* --- Codec thread --- */ |
1324 | 1303 | static bool codec_pcmbuf_insert_callback( | |
1325 | static bool codec_pcmbuf_insert_split_callback( | 1304 | const void *ch1, const void *ch2, int count) |
1326 | const void *ch1, const void *ch2, size_t length) | ||
1327 | { | 1305 | { |
1328 | const char* src[2]; | 1306 | const char *src[2] = { ch1, ch2 }; |
1329 | char *dest; | ||
1330 | long input_size; | ||
1331 | size_t output_size; | ||
1332 | |||
1333 | src[0] = ch1; | ||
1334 | src[1] = ch2; | ||
1335 | |||
1336 | if (dsp_stereo_mode() == STEREO_NONINTERLEAVED) | ||
1337 | length *= 2; /* Length is per channel */ | ||
1338 | 1307 | ||
1339 | while (length) | 1308 | while (count > 0) |
1340 | { | 1309 | { |
1341 | long est_output_size = dsp_output_size(length); | 1310 | int out_count = dsp_output_count(count); |
1311 | int inp_count; | ||
1312 | char *dest; | ||
1313 | |||
1342 | /* Prevent audio from a previous track from playing */ | 1314 | /* Prevent audio from a previous track from playing */ |
1343 | if (ci.new_track || ci.stop_codec) | 1315 | if (ci.new_track || ci.stop_codec) |
1344 | return true; | 1316 | return true; |
1345 | 1317 | ||
1346 | while ((dest = pcmbuf_request_buffer(est_output_size, | 1318 | while ((dest = pcmbuf_request_buffer(&out_count)) == NULL) |
1347 | &output_size)) == NULL) | ||
1348 | { | 1319 | { |
1349 | sleep(1); | 1320 | sleep(1); |
1350 | if (ci.seek_time || ci.new_track || ci.stop_codec) | 1321 | if (ci.seek_time || ci.new_track || ci.stop_codec) |
@@ -1353,24 +1324,24 @@ static bool codec_pcmbuf_insert_split_callback( | |||
1353 | 1324 | ||
1354 | /* Get the real input_size for output_size bytes, guarding | 1325 | /* Get the real input_size for output_size bytes, guarding |
1355 | * against resampling buffer overflows. */ | 1326 | * against resampling buffer overflows. */ |
1356 | input_size = dsp_input_size(output_size); | 1327 | inp_count = dsp_input_count(out_count); |
1357 | 1328 | ||
1358 | if (input_size <= 0) | 1329 | if (inp_count <= 0) |
1359 | { | 1330 | { |
1360 | DEBUGF("Error: dsp_input_size(%ld=dsp_output_size(%ld))=%ld<=0\n", | 1331 | DEBUGF("Error: dsp_input_count(%ld=dsp_output_count(%ld))=%ld<=0\n", |
1361 | output_size, length, input_size); | 1332 | out_count, count, inp_count); |
1362 | /* If this happens, there are samples of codec data that don't | 1333 | /* If this happens, there are samples of codec data that don't |
1363 | * become a number of pcm samples, and something is broken */ | 1334 | * become a number of pcm samples, and something is broken */ |
1364 | return false; | 1335 | return false; |
1365 | } | 1336 | } |
1366 | 1337 | ||
1367 | /* Input size has grown, no error, just don't write more than length */ | 1338 | /* Input size has grown, no error, just don't write more than length */ |
1368 | if ((size_t)input_size > length) | 1339 | if (inp_count > count) |
1369 | input_size = length; | 1340 | inp_count = count; |
1370 | 1341 | ||
1371 | output_size = dsp_process(dest, src, input_size); | 1342 | out_count = dsp_process(dest, src, inp_count); |
1372 | 1343 | ||
1373 | pcmbuf_write_complete(output_size); | 1344 | pcmbuf_write_complete(out_count); |
1374 | 1345 | ||
1375 | #ifdef PLAYBACK_VOICE | 1346 | #ifdef PLAYBACK_VOICE |
1376 | if ((voice_is_playing || voice_thread_start) | 1347 | if ((voice_is_playing || voice_thread_start) |
@@ -1381,26 +1352,12 @@ static bool codec_pcmbuf_insert_split_callback( | |||
1381 | swap_codec(); | 1352 | swap_codec(); |
1382 | } | 1353 | } |
1383 | #endif | 1354 | #endif |
1384 | 1355 | ||
1385 | length -= input_size; | 1356 | count -= inp_count; |
1386 | } | 1357 | } |
1387 | 1358 | ||
1388 | return true; | 1359 | return true; |
1389 | } /* codec_pcmbuf_insert_split_callback */ | 1360 | } /* codec_pcmbuf_insert_callback */ |
1390 | |||
1391 | static bool codec_pcmbuf_insert_callback(const char *buf, size_t length) | ||
1392 | { | ||
1393 | /* TODO: The audiobuffer API should probably be updated, and be based on | ||
1394 | * pcmbuf_insert_split(). */ | ||
1395 | long real_length = length; | ||
1396 | |||
1397 | if (dsp_stereo_mode() == STEREO_NONINTERLEAVED) | ||
1398 | length /= 2; /* Length is per channel */ | ||
1399 | |||
1400 | /* Second channel is only used for non-interleaved stereo. */ | ||
1401 | return codec_pcmbuf_insert_split_callback(buf, buf + (real_length / 2), | ||
1402 | length); | ||
1403 | } | ||
1404 | 1361 | ||
1405 | static void* codec_get_memory_callback(size_t *size) | 1362 | static void* codec_get_memory_callback(size_t *size) |
1406 | { | 1363 | { |
@@ -3523,7 +3480,6 @@ static void audio_playback_init(void) | |||
3523 | /* Initialize codec api. */ | 3480 | /* Initialize codec api. */ |
3524 | ci.read_filebuf = codec_filebuf_callback; | 3481 | ci.read_filebuf = codec_filebuf_callback; |
3525 | ci.pcmbuf_insert = codec_pcmbuf_insert_callback; | 3482 | ci.pcmbuf_insert = codec_pcmbuf_insert_callback; |
3526 | ci.pcmbuf_insert_split = codec_pcmbuf_insert_split_callback; | ||
3527 | ci.get_codec_memory = codec_get_memory_callback; | 3483 | ci.get_codec_memory = codec_get_memory_callback; |
3528 | ci.request_buffer = codec_request_buffer_callback; | 3484 | ci.request_buffer = codec_request_buffer_callback; |
3529 | ci.advance_buffer = codec_advance_buffer_callback; | 3485 | ci.advance_buffer = codec_advance_buffer_callback; |
@@ -3543,7 +3499,6 @@ static void audio_playback_init(void) | |||
3543 | memset(&id3_voice, 0, sizeof(struct mp3entry)); | 3499 | memset(&id3_voice, 0, sizeof(struct mp3entry)); |
3544 | ci_voice.read_filebuf = voice_filebuf_callback; | 3500 | ci_voice.read_filebuf = voice_filebuf_callback; |
3545 | ci_voice.pcmbuf_insert = voice_pcmbuf_insert_callback; | 3501 | ci_voice.pcmbuf_insert = voice_pcmbuf_insert_callback; |
3546 | ci_voice.pcmbuf_insert_split = voice_pcmbuf_insert_split_callback; | ||
3547 | ci_voice.get_codec_memory = voice_get_memory_callback; | 3502 | ci_voice.get_codec_memory = voice_get_memory_callback; |
3548 | ci_voice.request_buffer = voice_request_buffer_callback; | 3503 | ci_voice.request_buffer = voice_request_buffer_callback; |
3549 | ci_voice.advance_buffer = voice_advance_buffer_callback; | 3504 | ci_voice.advance_buffer = voice_advance_buffer_callback; |