5th part of FS#12176. Further fixed point migration. Only two emulators (ym2413,...
[kugel-rb.git] / apps / codecs / libgme / sms_fm_apu.c
blob5240405ad199e456b139231a8535095408bf3414
1 #include "sms_fm_apu.h"
3 #include "blargg_source.h"
5 void Fm_apu_create( struct Sms_Fm_Apu* this )
6 {
7 Synth_init( &this->synth );
8 Ym2413_init( &this->apu );
11 blargg_err_t Fm_apu_init( struct Sms_Fm_Apu* this, int clock_rate, int sample_rate )
13 this->period_ = (blip_time_t) (clock_rate / sample_rate);
14 CHECK_ALLOC( !Ym2413_set_rate( &this->apu, sample_rate, clock_rate ) );
16 Fm_apu_set_output( this, 0 );
17 Fm_apu_volume( this, (int)FP_ONE_VOLUME );
18 Fm_apu_reset( this );
19 return 0;
22 void Fm_apu_reset( struct Sms_Fm_Apu* this )
24 this->addr = 0;
25 this->next_time = 0;
26 this->last_amp = 0;
28 Ym2413_reset( &this->apu );
31 void fm_run_until( struct Sms_Fm_Apu* this, blip_time_t end_time ) ICODE_ATTR;
32 void Fm_apu_write_data( struct Sms_Fm_Apu* this, blip_time_t time, int data )
34 if ( time > this->next_time )
35 fm_run_until( this, time );
37 Ym2413_write( &this->apu, this->addr, data );
40 void fm_run_until( struct Sms_Fm_Apu* this, blip_time_t end_time )
42 assert( end_time > this->next_time );
44 struct Blip_Buffer* const output = this->output_;
45 if ( !output )
47 this->next_time = end_time;
48 return;
51 blip_time_t time = this->next_time;
52 struct Ym2413_Emu* emu = &this->apu;
55 short samples [2];
56 Ym2413_run( emu, 1, samples );
57 int amp = (samples [0] + samples [1]) >> 1;
59 int delta = amp - this->last_amp;
60 if ( delta )
62 this->last_amp = amp;
63 Synth_offset_inline( &this->synth, time, delta, output );
65 time += this->period_;
67 while ( time < end_time );
69 this->next_time = time;
72 void Fm_apu_end_frame( struct Sms_Fm_Apu* this, blip_time_t time )
74 if ( time > this->next_time )
75 fm_run_until( this, time );
77 this->next_time -= time;
78 assert( this->next_time >= 0 );
80 if ( this->output_ )
81 Blip_set_modified( this->output_ );