summaryrefslogtreecommitdiff
path: root/apps/codecs/spc.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/spc.c')
-rw-r--r--apps/codecs/spc.c128
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)
260static inline int32_t * samples_get_rdbuf(void) 260static 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
393static inline bool spc_play_get_samples(int32_t **samples) 385static 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
400static inline void spc_play_send_samples(int32_t *samples) 391static 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
436static inline bool spc_play_get_samples(int32_t **samples) 427static 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(&param);
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 */
535enum codec_status codec_main(void) 527enum 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"); 545enum 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
594codec_quit: 583 return CODEC_OK;
595 spc_emu_quit();
596
597 return stat;
598} 584}