diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2011-04-27 03:08:23 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2011-04-27 03:08:23 +0000 |
commit | c537d5958e8b421ac4f9bef6c8b9e7425a6cf167 (patch) | |
tree | 7ed36518fb6524da7bbd913ba7619b85b5d15d23 /apps/codecs/spc.c | |
parent | dcf0f8de4a37ff1d2ea510aef75fa67977a8bdcc (diff) | |
download | rockbox-c537d5958e8b421ac4f9bef6c8b9e7425a6cf167.tar.gz rockbox-c537d5958e8b421ac4f9bef6c8b9e7425a6cf167.zip |
Commit FS#12069 - Playback rework - first stages. Gives as thorough as possible a treatment of codec management, track change and metadata logic as possible while maintaining fairly narrow focus and not rewriting everything all at once. Please see the rockbox-dev mail archive on 2011-04-25 (Playback engine rework) for a more thorough manifest of what was addressed. Plugins and codecs become incompatible.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29785 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/spc.c')
-rw-r--r-- | apps/codecs/spc.c | 128 |
1 files changed, 57 insertions, 71 deletions
diff --git a/apps/codecs/spc.c b/apps/codecs/spc.c index 4db2878964..1b49761810 100644 --- a/apps/codecs/spc.c +++ b/apps/codecs/spc.c | |||
@@ -260,14 +260,6 @@ static inline void samples_release_rdbuf(void) | |||
260 | static inline int32_t * samples_get_rdbuf(void) | 260 | static inline int32_t * samples_get_rdbuf(void) |
261 | { | 261 | { |
262 | ci->semaphore_wait(&sample_queue.emu_sem_head, TIMEOUT_BLOCK); | 262 | ci->semaphore_wait(&sample_queue.emu_sem_head, TIMEOUT_BLOCK); |
263 | |||
264 | if (ci->stop_codec || ci->new_track) | ||
265 | { | ||
266 | /* Told to stop. Buffer must be released. */ | ||
267 | samples_release_rdbuf(); | ||
268 | return NULL; | ||
269 | } | ||
270 | |||
271 | return sample_queue.wav_chunk[sample_queue.head & WAV_CHUNK_MASK].audio; | 263 | return sample_queue.wav_chunk[sample_queue.head & WAV_CHUNK_MASK].audio; |
272 | } | 264 | } |
273 | 265 | ||
@@ -390,11 +382,10 @@ static inline void spc_emu_quit(void) | |||
390 | } | 382 | } |
391 | } | 383 | } |
392 | 384 | ||
393 | static inline bool spc_play_get_samples(int32_t **samples) | 385 | static inline int32_t * spc_play_get_samples(void) |
394 | { | 386 | { |
395 | /* obtain filled samples buffer */ | 387 | /* obtain filled samples buffer */ |
396 | *samples = samples_get_rdbuf(); | 388 | return samples_get_rdbuf(); |
397 | return *samples != NULL; | ||
398 | } | 389 | } |
399 | 390 | ||
400 | static inline void spc_play_send_samples(int32_t *samples) | 391 | static inline void spc_play_send_samples(int32_t *samples) |
@@ -433,15 +424,14 @@ static inline void spc_play_send_samples(int32_t *samples) | |||
433 | #define spc_emu_quit() | 424 | #define spc_emu_quit() |
434 | #define samples_release_rdbuf() | 425 | #define samples_release_rdbuf() |
435 | 426 | ||
436 | static inline bool spc_play_get_samples(int32_t **samples) | 427 | static inline int32_t * spc_play_get_samples(void) |
437 | { | 428 | { |
438 | ENTER_TIMER(render); | 429 | ENTER_TIMER(render); |
439 | /* fill samples buffer */ | 430 | /* fill samples buffer */ |
440 | if ( SPC_play(&spc_emu,WAV_CHUNK_SIZE*2,wav_chunk) ) | 431 | if ( SPC_play(&spc_emu,WAV_CHUNK_SIZE*2,wav_chunk) ) |
441 | assert( false ); | 432 | assert( false ); |
442 | EXIT_TIMER(render); | 433 | EXIT_TIMER(render); |
443 | *samples = wav_chunk; | 434 | return wav_chunk; |
444 | return true; | ||
445 | } | 435 | } |
446 | #endif /* SPC_DUAL_CORE */ | 436 | #endif /* SPC_DUAL_CORE */ |
447 | 437 | ||
@@ -454,6 +444,7 @@ static int play_track( void ) | |||
454 | unsigned long fadeendsample = (ID666.length+ID666.fade)*(long long) SAMPLE_RATE/1000; | 444 | unsigned long fadeendsample = (ID666.length+ID666.fade)*(long long) SAMPLE_RATE/1000; |
455 | int fadedec = 0; | 445 | int fadedec = 0; |
456 | int fadevol = 0x7fffffffl; | 446 | int fadevol = 0x7fffffffl; |
447 | intptr_t param; | ||
457 | 448 | ||
458 | if (fadeendsample>fadestartsample) | 449 | if (fadeendsample>fadestartsample) |
459 | fadedec=0x7fffffffl/(fadeendsample-fadestartsample)+1; | 450 | fadedec=0x7fffffffl/(fadeendsample-fadestartsample)+1; |
@@ -462,25 +453,26 @@ static int play_track( void ) | |||
462 | 453 | ||
463 | while ( 1 ) | 454 | while ( 1 ) |
464 | { | 455 | { |
465 | ci->yield(); | 456 | enum codec_command_action action = ci->get_command(¶m); |
466 | if (ci->stop_codec || ci->new_track) { | 457 | |
458 | if (action == CODEC_ACTION_HALT) | ||
467 | break; | 459 | break; |
468 | } | ||
469 | 460 | ||
470 | if (ci->seek_time) { | 461 | if (action == CODEC_ACTION_SEEK_TIME) { |
471 | int curtime = sampleswritten*1000LL/SAMPLE_RATE; | 462 | int curtime = sampleswritten*1000LL/SAMPLE_RATE; |
472 | DEBUGF("seek to %ld\ncurrently at %d\n",ci->seek_time,curtime); | 463 | DEBUGF("seek to %ld\ncurrently at %d\n", (long)param, curtime); |
473 | if (ci->seek_time < curtime) { | 464 | if (param < curtime) { |
474 | DEBUGF("seek backwards = reset\n"); | 465 | DEBUGF("seek backwards = reset\n"); |
466 | ci->set_elapsed(0); | ||
475 | ci->seek_complete(); | 467 | ci->seek_complete(); |
476 | return 1; | 468 | return 1; |
477 | } | 469 | } |
470 | |||
471 | ci->set_elapsed(curtime); | ||
478 | ci->seek_complete(); | 472 | ci->seek_complete(); |
479 | } | 473 | } |
480 | 474 | ||
481 | int32_t *samples; | 475 | int32_t *samples = spc_play_get_samples(); |
482 | if (!spc_play_get_samples(&samples)) | ||
483 | break; | ||
484 | 476 | ||
485 | sampleswritten += WAV_CHUNK_SIZE; | 477 | sampleswritten += WAV_CHUNK_SIZE; |
486 | 478 | ||
@@ -532,67 +524,61 @@ static int play_track( void ) | |||
532 | } | 524 | } |
533 | 525 | ||
534 | /* this is the codec entry point */ | 526 | /* this is the codec entry point */ |
535 | enum codec_status codec_main(void) | 527 | enum codec_status codec_main(enum codec_entry_call_reason reason) |
536 | { | 528 | { |
537 | enum codec_status stat = CODEC_ERROR; | 529 | if (reason == CODEC_LOAD) { |
538 | 530 | if (!spc_emu_start()) | |
539 | if (!spc_emu_start()) | 531 | return CODEC_ERROR; |
540 | goto codec_quit; | ||
541 | |||
542 | do | ||
543 | { | ||
544 | DEBUGF("SPC: next_track\n"); | ||
545 | if (codec_init()) { | ||
546 | goto codec_quit; | ||
547 | } | ||
548 | DEBUGF("SPC: after init\n"); | ||
549 | 532 | ||
550 | ci->configure(DSP_SET_SAMPLE_DEPTH, 24); | 533 | ci->configure(DSP_SET_SAMPLE_DEPTH, 24); |
551 | ci->configure(DSP_SET_FREQUENCY, SAMPLE_RATE); | 534 | ci->configure(DSP_SET_FREQUENCY, SAMPLE_RATE); |
552 | ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED); | 535 | ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED); |
536 | } | ||
537 | else if (reason == CODEC_UNLOAD) { | ||
538 | spc_emu_quit(); | ||
539 | } | ||
553 | 540 | ||
554 | /* wait for track info to load */ | 541 | return CODEC_OK; |
555 | if (codec_wait_taginfo() != 0) | 542 | } |
556 | continue; | ||
557 | |||
558 | codec_set_replaygain(ci->id3); | ||
559 | 543 | ||
560 | /* Read the entire file */ | 544 | /* this is called for each file to process */ |
561 | DEBUGF("SPC: request initial buffer\n"); | 545 | enum codec_status codec_run(void) |
562 | ci->seek_buffer(0); | 546 | { |
563 | size_t buffersize; | 547 | DEBUGF("SPC: next_track\n"); |
564 | uint8_t* buffer = ci->request_buffer(&buffersize, ci->filesize); | 548 | if (codec_init()) |
565 | if (!buffer) { | 549 | return CODEC_ERROR; |
566 | goto codec_quit; | 550 | DEBUGF("SPC: after init\n"); |
551 | |||
552 | codec_set_replaygain(ci->id3); | ||
553 | |||
554 | /* Read the entire file */ | ||
555 | DEBUGF("SPC: request initial buffer\n"); | ||
556 | ci->seek_buffer(0); | ||
557 | size_t buffersize; | ||
558 | uint8_t* buffer = ci->request_buffer(&buffersize, ci->filesize); | ||
559 | if (!buffer) | ||
560 | return CODEC_ERROR; | ||
561 | |||
562 | DEBUGF("SPC: read size = 0x%lx\n",(unsigned long)buffersize); | ||
563 | do | ||
564 | { | ||
565 | if (load_spc_buffer(buffer, buffersize)) { | ||
566 | DEBUGF("SPC load failure\n"); | ||
567 | return CODEC_ERROR; | ||
567 | } | 568 | } |
568 | 569 | ||
569 | DEBUGF("SPC: read size = 0x%lx\n",(unsigned long)buffersize); | 570 | LoadID666(buffer+0x2e); |
570 | do | ||
571 | { | ||
572 | if (load_spc_buffer(buffer, buffersize)) { | ||
573 | DEBUGF("SPC load failure\n"); | ||
574 | goto codec_quit; | ||
575 | } | ||
576 | |||
577 | LoadID666(buffer+0x2e); | ||
578 | 571 | ||
579 | if (ci->global_settings->repeat_mode!=REPEAT_ONE && ID666.length==0) { | 572 | if (ci->global_settings->repeat_mode!=REPEAT_ONE && ID666.length==0) { |
580 | ID666.length=3*60*1000; /* 3 minutes */ | 573 | ID666.length=3*60*1000; /* 3 minutes */ |
581 | ID666.fade=5*1000; /* 5 seconds */ | 574 | ID666.fade=5*1000; /* 5 seconds */ |
582 | } | ||
583 | |||
584 | reset_profile_timers(); | ||
585 | } | 575 | } |
586 | while ( play_track() ); | ||
587 | 576 | ||
588 | print_timers(ci->id3->path); | 577 | reset_profile_timers(); |
589 | } | 578 | } |
590 | while ( ci->request_next_track() ); | 579 | while ( play_track() ); |
591 | 580 | ||
592 | stat = CODEC_OK; | 581 | print_timers(ci->id3->path); |
593 | 582 | ||
594 | codec_quit: | 583 | return CODEC_OK; |
595 | spc_emu_quit(); | ||
596 | |||
597 | return stat; | ||
598 | } | 584 | } |