summaryrefslogtreecommitdiff
path: root/apps/codecs/libgme/kss_emu.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libgme/kss_emu.c')
-rw-r--r--apps/codecs/libgme/kss_emu.c373
1 files changed, 102 insertions, 271 deletions
diff --git a/apps/codecs/libgme/kss_emu.c b/apps/codecs/libgme/kss_emu.c
index 060a5b74b0..ba80ef613e 100644
--- a/apps/codecs/libgme/kss_emu.c
+++ b/apps/codecs/libgme/kss_emu.c
@@ -1,4 +1,4 @@
1// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/ 1// Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/
2 2
3#include "kss_emu.h" 3#include "kss_emu.h"
4 4
@@ -17,29 +17,14 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
17 17
18#include "blargg_source.h" 18#include "blargg_source.h"
19 19
20long const clock_rate = 3579545; 20int const clock_rate = 3579545;
21 21
22const char gme_wrong_file_type [] = "Wrong file type for this emulator"; 22const char gme_wrong_file_type [] = "Wrong file type for this emulator";
23 23
24int const stereo = 2; // number of channels for stereo
25int const silence_max = 6; // seconds
26int const silence_threshold = 0x10;
27long const fade_block_size = 512;
28int const fade_shift = 8; // fade ends with gain at 1.0 / (1 << fade_shift)
29
30static void clear_track_vars( struct Kss_Emu* this ) 24static void clear_track_vars( struct Kss_Emu* this )
31{ 25{
32 this->current_track = -1; 26 this->current_track = -1;
33 this->out_time = 0; 27 track_stop( &this->track_filter );
34 this->emu_time = 0;
35 this->emu_track_ended_ = true;
36 this->track_ended = true;
37 this->fade_start = INT_MAX / 2 + 1;
38 this->fade_step = 1;
39 this->silence_time = 0;
40 this->silence_count = 0;
41 this->buf_remain = 0;
42 // warning(); // clear warning
43} 28}
44 29
45static blargg_err_t init_opl_apu( enum opl_type_t type, struct Opl_Apu* out ) 30static blargg_err_t init_opl_apu( enum opl_type_t type, struct Opl_Apu* out )
@@ -58,17 +43,15 @@ void Kss_init( struct Kss_Emu* this )
58 this->chip_flags = 0; 43 this->chip_flags = 0;
59 44
60 // defaults 45 // defaults
61 this->max_initial_silence = 2; 46 this->tfilter = *track_get_setup( &this->track_filter );
62 this->silence_lookahead = 6; 47 this->tfilter.max_initial = 2;
63 this->ignore_silence = false; 48 this->tfilter.lookahead = 6;
64 49 this->track_filter.silence_ignored_ = false;
65 this->voice_count = 0;
66 clear_track_vars( this );
67 50
68 memset( this->unmapped_read, 0xFF, sizeof this->unmapped_read ); 51 memset( this->unmapped_read, 0xFF, sizeof this->unmapped_read );
69 52
70 // Init all stuff 53 // Init all stuff
71 Buffer_init( &this->stereo_buffer ); 54 Buffer_init( &this->stereo_buf );
72 55
73 Z80_init( &this->cpu ); 56 Z80_init( &this->cpu );
74 Rom_init( &this->rom, page_size ); 57 Rom_init( &this->rom, page_size );
@@ -83,6 +66,10 @@ void Kss_init( struct Kss_Emu* this )
83 init_opl_apu( type_msxmusic, &this->msx.music ); 66 init_opl_apu( type_msxmusic, &this->msx.music );
84 init_opl_apu( type_msxaudio, &this->msx.audio ); 67 init_opl_apu( type_msxaudio, &this->msx.audio );
85#endif 68#endif
69
70 this->voice_count = 0;
71 this->voice_types = 0;
72 clear_track_vars( this );
86} 73}
87 74
88// Track info 75// Track info
@@ -96,7 +83,7 @@ static blargg_err_t check_kss_header( void const* header )
96 83
97// Setup 84// Setup
98 85
99static void update_gain( struct Kss_Emu* this ) 86static void update_gain_( struct Kss_Emu* this )
100{ 87{
101 int g = this->gain; 88 int g = this->gain;
102 if ( msx_music_enabled( this ) || msx_audio_enabled( this ) 89 if ( msx_music_enabled( this ) || msx_audio_enabled( this )
@@ -118,6 +105,15 @@ static void update_gain( struct Kss_Emu* this )
118 if ( msx_audio_enabled( this ) ) Opl_volume( &this->msx.audio, g ); 105 if ( msx_audio_enabled( this ) ) Opl_volume( &this->msx.audio, g );
119} 106}
120 107
108static void update_gain( struct Kss_Emu* this )
109{
110 if ( this->scc_accessed )
111 {
112 /* dprintf( "SCC accessed\n" ); */
113 update_gain_( this );
114 }
115}
116
121blargg_err_t Kss_load_mem( struct Kss_Emu* this, const void* data, long size ) 117blargg_err_t Kss_load_mem( struct Kss_Emu* this, const void* data, long size )
122{ 118{
123 /* warning( core.warning() ); */ 119 /* warning( core.warning() ); */
@@ -176,6 +172,10 @@ blargg_err_t Kss_load_mem( struct Kss_Emu* this, const void* data, long size )
176 172
177 // sms.psg 173 // sms.psg
178 this->voice_count = sms_osc_count; 174 this->voice_count = sms_osc_count;
175 static int const types [sms_osc_count + opl_osc_count] = {
176 wave_type+1, wave_type+3, wave_type+2, mixed_type+1, wave_type+0
177 };
178 this->voice_types = types;
179 this->chip_flags |= sms_psg_flag; 179 this->chip_flags |= sms_psg_flag;
180 180
181 // sms.fm 181 // sms.fm
@@ -191,6 +191,10 @@ blargg_err_t Kss_load_mem( struct Kss_Emu* this, const void* data, long size )
191 191
192 // msx.psg 192 // msx.psg
193 this->voice_count = ay_osc_count; 193 this->voice_count = ay_osc_count;
194 static int const types [ay_osc_count + opl_osc_count] = {
195 wave_type+1, wave_type+3, wave_type+2, wave_type+0
196 };
197 this->voice_types = types;
194 this->chip_flags |= msx_psg_flag; 198 this->chip_flags |= msx_psg_flag;
195 199
196 /* if ( this->header.device_flags & 0x10 ) 200 /* if ( this->header.device_flags & 0x10 )
@@ -220,21 +224,27 @@ blargg_err_t Kss_load_mem( struct Kss_Emu* this, const void* data, long size )
220 // msx.scc 224 // msx.scc
221 this->chip_flags |= msx_scc_flag; 225 this->chip_flags |= msx_scc_flag;
222 this->voice_count = ay_osc_count + scc_osc_count; 226 this->voice_count = ay_osc_count + scc_osc_count;
227 static int const types [ay_osc_count + scc_osc_count] = {
228 wave_type+1, wave_type+3, wave_type+2,
229 wave_type+0, wave_type+4, wave_type+5, wave_type+6, wave_type+7,
230 };
231 this->voice_types = types;
223 } 232 }
224 } 233 }
225 234
226 this->silence_lookahead = 6; 235 this->tfilter.lookahead = 6;
227 if ( sms_fm_enabled( this ) || msx_music_enabled( this ) || msx_audio_enabled( this ) ) 236 if ( sms_fm_enabled( this ) || msx_music_enabled( this ) || msx_audio_enabled( this ) )
228 { 237 {
229 if ( !Opl_supported() ) 238 if ( !Opl_supported() )
230 ; /* warning( "FM sound not supported" ); */ 239 ; /* warning( "FM sound not supported" ); */
231 else 240 else
232 this->silence_lookahead = 3; // Opl_Apu is really slow 241 this->tfilter.lookahead = 3; // Opl_Apu is really slow
233 } 242 }
234 243
235 this->clock_rate_ = clock_rate; 244 this->clock_rate_ = clock_rate;
236 Buffer_clock_rate( &this->stereo_buffer, clock_rate ); 245 Buffer_clock_rate( &this->stereo_buf, clock_rate );
237 this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buffer ); 246 RETURN_ERR( Buffer_set_channel_count( &this->stereo_buf, this->voice_count, this->voice_types ) );
247 this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buf );
238 248
239 Sound_set_tempo( this, this->tempo ); 249 Sound_set_tempo( this, this->tempo );
240 Sound_mute_voices( this, this->mute_mask_ ); 250 Sound_mute_voices( this, this->mute_mask_ );
@@ -265,8 +275,8 @@ static void set_voice( struct Kss_Emu* this, int i, struct Blip_Buffer* center,
265 } 275 }
266 276
267 if ( msx_scc_enabled( this ) && i < scc_osc_count ) Scc_set_output( &this->msx.scc, i, center ); 277 if ( msx_scc_enabled( this ) && i < scc_osc_count ) Scc_set_output( &this->msx.scc, i, center );
268 if ( msx_music_enabled( this ) && i < opl_osc_count ) Opl_set_output( &this->msx.music, center ); 278 if ( msx_music_enabled( this ) && i < opl_osc_count ) Opl_set_output( &this->msx.music, center );
269 if ( msx_audio_enabled( this ) && i < opl_osc_count ) Opl_set_output( &this->msx.audio, center ); 279 if ( msx_audio_enabled( this ) && i < opl_osc_count ) Opl_set_output( &this->msx.audio, center );
270 } 280 }
271} 281}
272 282
@@ -465,15 +475,17 @@ blargg_err_t end_frame( struct Kss_Emu* this, kss_time_t end )
465 475
466// MUSIC 476// MUSIC
467 477
468 478blargg_err_t Kss_set_sample_rate( struct Kss_Emu* this, int rate )
469blargg_err_t Kss_set_sample_rate( struct Kss_Emu* this, long rate )
470{ 479{
471 require( !this->sample_rate ); // sample rate can't be changed once set 480 require( !this->sample_rate ); // sample rate can't be changed once set
472 RETURN_ERR( Buffer_set_sample_rate( &this->stereo_buffer, rate, 1000 / 20 ) ); 481 RETURN_ERR( Buffer_set_sample_rate( &this->stereo_buf, rate, 1000 / 20 ) );
473 482
474 // Set bass frequency 483 // Set bass frequency
475 Buffer_bass_freq( &this->stereo_buffer, 180 ); 484 Buffer_bass_freq( &this->stereo_buf, 180 );
485
476 this->sample_rate = rate; 486 this->sample_rate = rate;
487 RETURN_ERR( track_init( &this->track_filter, this ) );
488 this->tfilter.max_silence = 6 * stereo * this->sample_rate;
477 return 0; 489 return 0;
478} 490}
479 491
@@ -501,7 +513,7 @@ void Sound_mute_voices( struct Kss_Emu* this, int mask )
501 } 513 }
502 else 514 else
503 { 515 {
504 struct channel_t ch = Buffer_channel( &this->stereo_buffer ); 516 struct channel_t ch = Buffer_channel( &this->stereo_buf, i );
505 assert( (ch.center && ch.left && ch.right) || 517 assert( (ch.center && ch.left && ch.right) ||
506 (!ch.center && !ch.left && !ch.right) ); // all or nothing 518 (!ch.center && !ch.left && !ch.right) ); // all or nothing
507 set_voice( this, i, ch.center, ch.left, ch.right ); 519 set_voice( this, i, ch.center, ch.left, ch.right );
@@ -523,7 +535,6 @@ void Sound_set_tempo( struct Kss_Emu* this, int t )
523 this->play_period = (blip_time_t) ((period * FP_ONE_TEMPO) / t); 535 this->play_period = (blip_time_t) ((period * FP_ONE_TEMPO) / t);
524} 536}
525 537
526void fill_buf( struct Kss_Emu* this );
527blargg_err_t Kss_start_track( struct Kss_Emu* this, int track ) 538blargg_err_t Kss_start_track( struct Kss_Emu* this, int track )
528{ 539{
529 clear_track_vars( this ); 540 clear_track_vars( this );
@@ -536,7 +547,7 @@ blargg_err_t Kss_start_track( struct Kss_Emu* this, int track )
536 547
537 this->current_track = track; 548 this->current_track = track;
538 549
539 Buffer_clear( &this->stereo_buffer ); 550 Buffer_clear( &this->stereo_buf );
540 551
541 if ( sms_psg_enabled( this ) ) Sms_apu_reset( &this->sms.psg, 0, 0 ); 552 if ( sms_psg_enabled( this ) ) Sms_apu_reset( &this->sms.psg, 0, 0 );
542 if ( sms_fm_enabled( this ) ) Opl_reset( &this->sms.fm ); 553 if ( sms_fm_enabled( this ) ) Opl_reset( &this->sms.fm );
@@ -546,7 +557,7 @@ blargg_err_t Kss_start_track( struct Kss_Emu* this, int track )
546 if ( msx_audio_enabled( this ) ) Opl_reset( &this->msx.audio ); 557 if ( msx_audio_enabled( this ) ) Opl_reset( &this->msx.audio );
547 558
548 this->scc_accessed = false; 559 this->scc_accessed = false;
549 update_gain( this ); 560 update_gain_( this );
550 561
551 memset( this->ram, 0xC9, 0x4000 ); 562 memset( this->ram, 0xC9, 0x4000 );
552 memset( this->ram + 0x4000, 0, sizeof this->ram - 0x4000 ); 563 memset( this->ram + 0x4000, 0, sizeof this->ram - 0x4000 );
@@ -598,286 +609,106 @@ blargg_err_t Kss_start_track( struct Kss_Emu* this, int track )
598 this->gain_updated = false; 609 this->gain_updated = false;
599 jsr( this, this->header.init_addr ); 610 jsr( this, this->header.init_addr );
600 611
601 this->emu_track_ended_ = false; 612 // convert filter times to samples
602 this->track_ended = false; 613 struct setup_t s = this->tfilter;
614 s.max_initial *= this->sample_rate * stereo;
615 #ifdef GME_DISABLE_SILENCE_LOOKAHEAD
616 s.lookahead = 1;
617 #endif
618 track_setup( &this->track_filter, &s );
603 619
604 if ( !this->ignore_silence ) 620 return track_start( &this->track_filter );
605 {
606 // play until non-silence or end of track
607 long end;
608 for ( end = this->max_initial_silence * stereo * this->sample_rate; this->emu_time < end; )
609 {
610 fill_buf( this );
611 if ( this->buf_remain | (int) this->emu_track_ended_ )
612 break;
613 }
614
615 this->emu_time = this->buf_remain;
616 this->out_time = 0;
617 this->silence_time = 0;
618 this->silence_count = 0;
619 }
620 /* return track_ended() ? warning() : 0; */
621 return 0;
622} 621}
623 622
624// Tell/Seek 623// Tell/Seek
625 624
626static blargg_long msec_to_samples( blargg_long msec, long sample_rate ) 625static int msec_to_samples( int msec, int sample_rate )
627{ 626{
628 blargg_long sec = msec / 1000; 627 int sec = msec / 1000;
629 msec -= sec * 1000; 628 msec -= sec * 1000;
630 return (sec * sample_rate + msec * sample_rate / 1000) * stereo; 629 return (sec * sample_rate + msec * sample_rate / 1000) * stereo;
631} 630}
632 631
633long Track_tell( struct Kss_Emu* this ) 632int Track_tell( struct Kss_Emu* this )
634{ 633{
635 blargg_long rate = this->sample_rate * stereo; 634 int rate = this->sample_rate * stereo;
636 blargg_long sec = this->out_time / rate; 635 int sec = track_sample_count( &this->track_filter ) / rate;
637 return sec * 1000 + (this->out_time - sec * rate) * 1000 / rate; 636 return sec * 1000 + (track_sample_count( &this->track_filter ) - sec * rate) * 1000 / rate;
638} 637}
639 638
640blargg_err_t Track_seek( struct Kss_Emu* this, long msec ) 639blargg_err_t Track_seek( struct Kss_Emu* this, int msec )
641{ 640{
642 blargg_long time = msec_to_samples( msec, this->sample_rate ); 641 int time = msec_to_samples( msec, this->sample_rate );
643 if ( time < this->out_time ) 642 if ( time < track_sample_count( &this->track_filter ) )
644 RETURN_ERR( Kss_start_track( this, this->current_track ) ); 643 RETURN_ERR( Kss_start_track( this, this->current_track ) );
645 return Track_skip( this, time - this->out_time ); 644 return Track_skip( this, time - track_sample_count( &this->track_filter ) );
646} 645}
647 646
648blargg_err_t play_( struct Kss_Emu* this, long count, sample_t* out ); 647blargg_err_t skip_( void *emu, int count )
649static blargg_err_t skip_( struct Kss_Emu* this, long count )
650{ 648{
649 struct Kss_Emu* this = (struct Kss_Emu*) emu;
650
651 // for long skip, mute sound 651 // for long skip, mute sound
652 const long threshold = 30000; 652 const int threshold = 32768;
653 if ( count > threshold ) 653 if ( count > threshold )
654 { 654 {
655 int saved_mute = this->mute_mask_; 655 int saved_mute = this->mute_mask_;
656 Sound_mute_voices( this, ~0 ); 656 Sound_mute_voices( this, ~0 );
657
658 while ( count > threshold / 2 && !this->emu_track_ended_ )
659 {
660 RETURN_ERR( play_( this, buf_size, this->buf ) );
661 count -= buf_size;
662 }
663
664 Sound_mute_voices( this, saved_mute );
665 }
666
667 while ( count && !this->emu_track_ended_ )
668 {
669 long n = buf_size;
670 if ( n > count )
671 n = count;
672 count -= n;
673 RETURN_ERR( play_( this, n, this->buf ) );
674 }
675 return 0;
676}
677 657
678blargg_err_t Track_skip( struct Kss_Emu* this, long count ) 658 int n = count - threshold/2;
679{ 659 n &= ~(2048-1); // round to multiple of 2048
680 require( this->current_track >= 0 ); // start_track() must have been called already
681 this->out_time += count;
682
683 // remove from silence and buf first
684 {
685 long n = min( count, this->silence_count );
686 this->silence_count -= n;
687 count -= n;
688
689 n = min( count, this->buf_remain );
690 this->buf_remain -= n;
691 count -= n; 660 count -= n;
692 } 661 RETURN_ERR( skippy_( &this->track_filter, n ) );
693
694 if ( count && !this->emu_track_ended_ )
695 {
696 this->emu_time += count;
697 if ( skip_( this, count ) )
698 this->emu_track_ended_ = true;
699 }
700
701 if ( !(this->silence_count | this->buf_remain) ) // caught up to emulator, so update track ended
702 this->track_ended |= this->emu_track_ended_;
703
704 return 0;
705}
706
707// Fading
708 662
709void Track_set_fade( struct Kss_Emu* this, long start_msec, long length_msec ) 663 Sound_mute_voices( this, saved_mute );
710{
711 this->fade_step = this->sample_rate * length_msec / (fade_block_size * fade_shift * 1000 / stereo);
712 this->fade_start = msec_to_samples( start_msec, this->sample_rate );
713}
714
715// unit / pow( 2.0, (double) x / step )
716static int int_log( blargg_long x, int step, int unit )
717{
718 int shift = x / step;
719 int fraction = (x - shift * step) * unit / step;
720 return ((unit - fraction) + (fraction >> 1)) >> shift;
721}
722
723static void handle_fade( struct Kss_Emu *this, long out_count, sample_t* out )
724{
725 int i;
726 for ( i = 0; i < out_count; i += fade_block_size )
727 {
728 int const shift = 14;
729 int const unit = 1 << shift;
730 int gain = int_log( (this->out_time + i - this->fade_start) / fade_block_size,
731 this->fade_step, unit );
732 if ( gain < (unit >> fade_shift) )
733 this->track_ended = this->emu_track_ended_ = true;
734
735 sample_t* io = &out [i];
736 int count;
737 for ( count = min( fade_block_size, out_count - i ); count; --count )
738 {
739 *io = (sample_t) ((*io * gain) >> shift);
740 ++io;
741 }
742 } 664 }
743}
744
745// Silence detection
746 665
747static void emu_play( struct Kss_Emu* this, long count, sample_t* out ) 666 return skippy_( &this->track_filter, count );
748{
749 check( current_track_ >= 0 );
750 this->emu_time += count;
751 if ( this->current_track >= 0 && !this->emu_track_ended_ ) {
752 if ( play_( this, count, out ) )
753 this->emu_track_ended_ = true;
754 }
755 else
756 memset( out, 0, count * sizeof *out );
757} 667}
758 668
759// number of consecutive silent samples at end 669blargg_err_t Track_skip( struct Kss_Emu* this, int count )
760static long count_silence( sample_t* begin, long size )
761{ 670{
762 sample_t first = *begin; 671 require( this->current_track >= 0 ); // start_track() must have been called already
763 *begin = silence_threshold; // sentinel 672 return track_skip( &this->track_filter, count );
764 sample_t* p = begin + size;
765 while ( (unsigned) (*--p + silence_threshold / 2) <= (unsigned) silence_threshold ) { }
766 *begin = first;
767 return size - (p - begin);
768} 673}
769 674
770// fill internal buffer and check it for silence 675void Track_set_fade( struct Kss_Emu* this, int start_msec, int length_msec )
771void fill_buf( struct Kss_Emu* this )
772{ 676{
773 assert( !this->buf_remain ); 677 track_set_fade( &this->track_filter, msec_to_samples( start_msec, this->sample_rate ),
774 if ( !this->emu_track_ended_ ) 678 length_msec * this->sample_rate / (1000 / stereo) );
775 {
776 emu_play( this, buf_size, this->buf );
777 long silence = count_silence( this->buf, buf_size );
778 if ( silence < buf_size )
779 {
780 this->silence_time = this->emu_time - silence;
781 this->buf_remain = buf_size;
782 return;
783 }
784 }
785 this->silence_count += buf_size;
786} 679}
787 680
788blargg_err_t Kss_play( struct Kss_Emu* this, long out_count, sample_t* out ) 681blargg_err_t Kss_play( struct Kss_Emu* this, int out_count, sample_t* out )
789{ 682{
790 if ( this->track_ended ) 683 require( this->current_track >= 0 );
791 { 684 require( out_count % stereo == 0 );
792 memset( out, 0, out_count * sizeof *out ); 685 return track_play( &this->track_filter, out_count, out );
793 }
794 else
795 {
796 require( this->current_track >= 0 );
797 require( out_count % stereo == 0 );
798
799 assert( this->emu_time >= this->out_time );
800
801 // prints nifty graph of how far ahead we are when searching for silence
802 //debug_printf( "%*s \n", int ((emu_time - out_time) * 7 / sample_rate()), "*" );
803
804 long pos = 0;
805 if ( this->silence_count )
806 {
807 // during a run of silence, run emulator at >=2x speed so it gets ahead
808 long ahead_time = this->silence_lookahead * (this->out_time + out_count -this->silence_time) + this->silence_time;
809 while ( this->emu_time < ahead_time && !(this->buf_remain |this-> emu_track_ended_) )
810 fill_buf( this );
811
812 // fill with silence
813 pos = min( this->silence_count, out_count );
814 memset( out, 0, pos * sizeof *out );
815 this->silence_count -= pos;
816
817 if ( this->emu_time - this->silence_time > silence_max * stereo * this->sample_rate )
818 {
819 this->track_ended = this->emu_track_ended_ = true;
820 this->silence_count = 0;
821 this->buf_remain = 0;
822 }
823 }
824
825 if ( this->buf_remain )
826 {
827 // empty silence buf
828 long n = min( this->buf_remain, out_count - pos );
829 memcpy( &out [pos], this->buf + (buf_size - this->buf_remain), n * sizeof *out );
830 this->buf_remain -= n;
831 pos += n;
832 }
833
834 // generate remaining samples normally
835 long remain = out_count - pos;
836 if ( remain )
837 {
838 emu_play( this, remain, out + pos );
839 this->track_ended |= this->emu_track_ended_;
840
841 if ( !this->ignore_silence || this->out_time > this->fade_start )
842 {
843 // check end for a new run of silence
844 long silence = count_silence( out + pos, remain );
845 if ( silence < remain )
846 this->silence_time = this->emu_time - silence;
847
848 if ( this->emu_time - this->silence_time >= buf_size )
849 fill_buf( this ); // cause silence detection on next play()
850 }
851 }
852
853 if ( this->out_time > this->fade_start )
854 handle_fade( this, out_count, out );
855 }
856 this->out_time += out_count;
857 return 0;
858} 686}
859 687
860blargg_err_t play_( struct Kss_Emu* this, long count, sample_t* out ) 688blargg_err_t play_( void *emu, int count, sample_t* out )
861{ 689{
862 long remain = count; 690 struct Kss_Emu* this = (struct Kss_Emu*) emu;
691
692 int remain = count;
863 while ( remain ) 693 while ( remain )
864 { 694 {
865 remain -= Buffer_read_samples( &this->stereo_buffer, &out [count - remain], remain ); 695 Buffer_disable_immediate_removal( &this->stereo_buf );
696 remain -= Buffer_read_samples( &this->stereo_buf, &out [count - remain], remain );
866 if ( remain ) 697 if ( remain )
867 { 698 {
868 if ( this->buf_changed_count != Buffer_channels_changed_count( &this->stereo_buffer ) ) 699 if ( this->buf_changed_count != Buffer_channels_changed_count( &this->stereo_buf ) )
869 { 700 {
870 this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buffer ); 701 this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buf );
702
703 // Remute voices
871 Sound_mute_voices( this, this->mute_mask_ ); 704 Sound_mute_voices( this, this->mute_mask_ );
872 } 705 }
873 int msec = Buffer_length( &this->stereo_buffer ); 706 int msec = Buffer_length( &this->stereo_buf );
874 /* blip_time_t clocks_emulated = (blargg_long) msec * clock_rate_ / 1000; */
875 blip_time_t clocks_emulated = msec * this->clock_rate_ / 1000 - 100; 707 blip_time_t clocks_emulated = msec * this->clock_rate_ / 1000 - 100;
876 RETURN_ERR( run_clocks( this, &clocks_emulated ) ); 708 RETURN_ERR( run_clocks( this, &clocks_emulated ) );
877 assert( clocks_emulated ); 709 assert( clocks_emulated );
878 Buffer_end_frame( &this->stereo_buffer, clocks_emulated ); 710 Buffer_end_frame( &this->stereo_buf, clocks_emulated );
879 } 711 }
880 } 712 }
881 return 0; 713 return 0;
882} 714}
883