summaryrefslogtreecommitdiff
path: root/apps/playback.c
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2005-06-26 19:41:29 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2005-06-26 19:41:29 +0000
commitd8cb703b1e86c9f910211a976d8bed0c7a99379a (patch)
tree6db3b698d83e639974bd6603225ff11891652113 /apps/playback.c
parent316eb6538e2fc88efa93248deb761679071409f1 (diff)
downloadrockbox-d8cb703b1e86c9f910211a976d8bed0c7a99379a.tar.gz
rockbox-d8cb703b1e86c9f910211a976d8bed0c7a99379a.zip
Initial DSP implementation. DSP supports resampling audio stream from
codecs (currently works corrently only with mp3's, somebody should fix that). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6877 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/playback.c')
-rw-r--r--apps/playback.c131
1 files changed, 123 insertions, 8 deletions
diff --git a/apps/playback.c b/apps/playback.c
index 500f44e45b..996e825e13 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -49,6 +49,7 @@
49#include "playback.h" 49#include "playback.h"
50#include "pcm_playback.h" 50#include "pcm_playback.h"
51#include "buffer.h" 51#include "buffer.h"
52#include "dsp.h"
52#ifdef HAVE_LCD_BITMAP 53#ifdef HAVE_LCD_BITMAP
53#include "icons.h" 54#include "icons.h"
54#include "peakmeter.h" 55#include "peakmeter.h"
@@ -171,7 +172,7 @@ int mp3_get_file_pos(void);
171 172
172/* Simulator stubs. */ 173/* Simulator stubs. */
173#ifdef SIMULATOR 174#ifdef SIMULATOR
174bool audiobuffer_insert(char *buf, size_t length) 175bool pcm_insert_buffer(char *buf, size_t length)
175{ 176{
176 (void)buf; 177 (void)buf;
177 (void)length; 178 (void)length;
@@ -179,6 +180,20 @@ bool audiobuffer_insert(char *buf, size_t length)
179 return true; 180 return true;
180} 181}
181 182
183void pcm_flush_buffer(size_t length)
184{
185 (void)length;
186}
187
188
189void* pcm_request_buffer(size_t length, size_t *realsize)
190{
191 (void)length;
192 (void)realsize;
193
194 return NULL;
195}
196
182void audiobuffer_add_event(void (*event_handler)(void)) 197void audiobuffer_add_event(void (*event_handler)(void))
183{ 198{
184 (void)event_handler; 199 (void)event_handler;
@@ -229,6 +244,92 @@ int ata_sleep(void)
229} 244}
230#endif 245#endif
231 246
247bool codec_audiobuffer_insert_callback(char *buf, size_t length)
248{
249 char *dest;
250 size_t realsize;
251 int factor;
252 int next_channel = 0;
253 int processed_length;
254
255 /* If non-interleaved stereo mode. */
256 if (dsp_config.stereo_mode == STEREO_NONINTERLEAVED) {
257 next_channel = length / 2;
258 }
259
260 if (dsp_config.sample_depth > 16) {
261 length /= 2;
262 factor = 1;
263 } else {
264 factor = 0;
265 }
266
267 while (length > 0) {
268 /* Request a few extra bytes for resampling. */
269 /* FIXME: Required extra bytes SHOULD be calculated. */
270 while ((dest = pcm_request_buffer(length+16384, &realsize)) == NULL)
271 yield();
272
273 if (realsize < 16384) {
274 pcm_flush_buffer(0);
275 continue ;
276 }
277
278 realsize -= 16384;
279
280 if (next_channel) {
281 processed_length = dsp_process(dest, buf, realsize / 4) * 2;
282 dsp_process(dest, buf + next_channel, realsize / 4);
283 } else {
284 processed_length = dsp_process(dest, buf, realsize / 2);
285 }
286 pcm_flush_buffer(processed_length);
287 length -= realsize;
288 buf += realsize << factor;
289 }
290
291 return true;
292}
293
294bool codec_audiobuffer_insert_split_callback(void *ch1, void *ch2,
295 size_t length)
296{
297 char *dest;
298 size_t realsize;
299 int factor;
300 int processed_length;
301
302 /* non-interleaved stereo mode. */
303 if (dsp_config.sample_depth > 16) {
304 factor = 0;
305 } else {
306 length /= 2;
307 factor = 1;
308 }
309
310 while (length > 0) {
311 /* Request a few extra bytes for resampling. */
312 while ((dest = pcm_request_buffer(length+4096, &realsize)) == NULL)
313 yield();
314
315 if (realsize < 4096) {
316 pcm_flush_buffer(0);
317 continue ;
318 }
319
320 realsize -= 4096;
321
322 processed_length = dsp_process(dest, ch1, realsize / 4) * 2;
323 dsp_process(dest, ch2, realsize / 4);
324 pcm_flush_buffer(processed_length);
325 length -= realsize;
326 ch1 += realsize >> factor;
327 ch2 += realsize >> factor;
328 }
329
330 return true;
331}
332
232void* get_codec_memory_callback(size_t *size) 333void* get_codec_memory_callback(size_t *size)
233{ 334{
234 *size = MALLOC_BUFSIZE; 335 *size = MALLOC_BUFSIZE;
@@ -260,7 +361,7 @@ size_t codec_filebuf_callback(void *ptr, size_t size)
260 361
261 if (ci.stop_codec || !playing) 362 if (ci.stop_codec || !playing)
262 return 0; 363 return 0;
263 364
264 copy_n = MIN((off_t)size, (off_t)cur_ti->available + cur_ti->filerem); 365 copy_n = MIN((off_t)size, (off_t)cur_ti->available + cur_ti->filerem);
265 366
266 while (copy_n > cur_ti->available) { 367 while (copy_n > cur_ti->available) {
@@ -283,7 +384,7 @@ size_t codec_filebuf_callback(void *ptr, size_t size)
283 buf_ridx -= codecbuflen; 384 buf_ridx -= codecbuflen;
284 ci.curpos += copy_n; 385 ci.curpos += copy_n;
285 cur_ti->available -= copy_n; 386 cur_ti->available -= copy_n;
286 codecbufused -= copy_n; 387 codecbufused -= copy_n;
287 388
288 return copy_n; 389 return copy_n;
289} 390}
@@ -427,8 +528,18 @@ void codec_configure_callback(int setting, void *value)
427 conf_bufferlimit = (unsigned int)value; 528 conf_bufferlimit = (unsigned int)value;
428 break; 529 break;
429 530
531 case CODEC_DSP_ENABLE:
532 if ((bool)value)
533 ci.audiobuffer_insert = codec_audiobuffer_insert_callback;
534 else
535 ci.audiobuffer_insert = pcm_insert_buffer;
536 break ;
537
538#ifndef SIMULATOR
430 default: 539 default:
431 logf("Illegal key: %d", setting); 540 if (!dsp_configure(setting, value))
541 logf("Illegal key: %d", setting);
542#endif
432 } 543 }
433} 544}
434 545
@@ -647,6 +758,8 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
647 conf_bufferlimit = 0; 758 conf_bufferlimit = 0;
648 conf_watermark = AUDIO_DEFAULT_WATERMARK; 759 conf_watermark = AUDIO_DEFAULT_WATERMARK;
649 conf_filechunk = AUDIO_DEFAULT_FILECHUNK; 760 conf_filechunk = AUDIO_DEFAULT_FILECHUNK;
761 dsp_configure(DSP_RESET, 0);
762 ci.configure(CODEC_DSP_ENABLE, false);
650 } 763 }
651 764
652 tracks[track_widx].codecbuf = &codecbuf[buf_widx]; 765 tracks[track_widx].codecbuf = &codecbuf[buf_widx];
@@ -697,7 +810,7 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
697 copy_n = MIN(size - i, copy_n); 810 copy_n = MIN(size - i, copy_n);
698 copy_n = MIN((int)fill_bytesleft, copy_n); 811 copy_n = MIN((int)fill_bytesleft, copy_n);
699 rc = read(fd, &codecbuf[buf_widx], copy_n); 812 rc = read(fd, &codecbuf[buf_widx], copy_n);
700 if (rc < 0) { 813 if (rc <= 0) {
701 logf("File error!"); 814 logf("File error!");
702 close(fd); 815 close(fd);
703 return false; 816 return false;
@@ -1152,7 +1265,7 @@ struct mp3entry* audio_next_track(void)
1152 1265
1153bool audio_has_changed_track(void) 1266bool audio_has_changed_track(void)
1154{ 1267{
1155 if (track_changed && track_count > 0) { 1268 if (track_changed && track_count > 0 && playing) {
1156 if (!cur_ti->taginfo_ready) 1269 if (!cur_ti->taginfo_ready)
1157 return false; 1270 return false;
1158 track_changed = false; 1271 track_changed = false;
@@ -1384,6 +1497,7 @@ int mp3_get_file_pos(void)
1384void audio_set_buffer_margin(int seconds) 1497void audio_set_buffer_margin(int seconds)
1385{ 1498{
1386 (void)seconds; 1499 (void)seconds;
1500 logf("bufmargin: %d", seconds);
1387} 1501}
1388#endif 1502#endif
1389 1503
@@ -1395,7 +1509,7 @@ void mpeg_id3_options(bool _v1first)
1395void audio_init(void) 1509void audio_init(void)
1396{ 1510{
1397 logf("audio api init"); 1511 logf("audio api init");
1398 codecbuflen = audiobufend - audiobuf - PCMBUF_SIZE 1512 codecbuflen = audiobufend - audiobuf - PCMBUF_SIZE - PCMBUF_GUARD
1399 - MALLOC_BUFSIZE - GUARD_BUFSIZE; 1513 - MALLOC_BUFSIZE - GUARD_BUFSIZE;
1400 //codecbuflen = 2*512*1024; 1514 //codecbuflen = 2*512*1024;
1401 codecbufused = 0; 1515 codecbufused = 0;
@@ -1412,7 +1526,8 @@ void audio_init(void)
1412 1526
1413 /* Initialize codec api. */ 1527 /* Initialize codec api. */
1414 ci.read_filebuf = codec_filebuf_callback; 1528 ci.read_filebuf = codec_filebuf_callback;
1415 ci.audiobuffer_insert = audiobuffer_insert; 1529 ci.audiobuffer_insert = pcm_insert_buffer;
1530 ci.audiobuffer_insert_split = codec_audiobuffer_insert_split_callback;
1416 ci.get_codec_memory = get_codec_memory_callback; 1531 ci.get_codec_memory = get_codec_memory_callback;
1417 ci.request_buffer = codec_request_buffer_callback; 1532 ci.request_buffer = codec_request_buffer_callback;
1418 ci.advance_buffer = codec_advance_buffer_callback; 1533 ci.advance_buffer = codec_advance_buffer_callback;