1 // Turbo Grafx 16 (PC Engine) ADPCM sound chip emulator
3 // Game_Music_Emu 0.6-pre
4 #ifndef HES_APU_ADPCM_H
5 #define HES_APU_ADPCM_H
7 #include "blargg_source.h"
8 #include "blargg_common.h"
9 #include "blip_buffer.h"
11 enum { adpcm_amp_range
= 2048 };
12 enum { adpcm_osc_count
= 1 }; // 0 <= chan < osc_count
14 // Registers are at io_addr to io_addr+io_size-1
15 enum { io_addr
= 0x1800 };
16 enum { io_size
= 0x400 };
20 byte pcmbuf
[0x10000];
27 unsigned short writeptr
;
28 unsigned short readptr
;
29 unsigned short playptr
;
34 int playedsamplecount
;
40 struct Hes_Apu_Adpcm
{
42 struct Blip_Synth synth
;
44 struct Blip_Buffer
* output
;
45 blip_time_t last_time
;
50 // Init HES adpcm sound chip
51 void Adpcm_init( struct Hes_Apu_Adpcm
* this );
53 // Rest HES adpcm sound chip
54 void Adpcm_reset( struct Hes_Apu_Adpcm
* this );
56 // Sets buffer(s) to generate sound into, or 0 to mute. If only center is not 0,
58 static inline void Adpcm_set_output( struct Hes_Apu_Adpcm
* this, int chan
, struct Blip_Buffer
* center
, struct Blip_Buffer
* left
, struct Blip_Buffer
* right
)
60 // Must be silent (all NULL), mono (left and right NULL), or stereo (none NULL)
61 require( !center
|| (center
&& !left
&& !right
) || (center
&& left
&& right
) );
62 require( (unsigned) chan
< adpcm_osc_count
); // fails if you pass invalid osc index
68 if ( !center
|| !left
|| !right
)
74 this->output
= center
;
77 // Emulates to time t, then writes data to addr
78 void Adpcm_write_data( struct Hes_Apu_Adpcm
* this, blip_time_t t
, int addr
, int data
) ICODE_ATTR
;
80 // Emulates to time t, then reads from addr
81 int Adpcm_read_data( struct Hes_Apu_Adpcm
* this, blip_time_t t
, int addr
) ICODE_ATTR
;
83 // Emulates to time t, then subtracts t from the current time.
84 // OK if previous write call had time slightly after t.
85 void Adpcm_end_frame( struct Hes_Apu_Adpcm
* this,blip_time_t t
) ICODE_ATTR
;
87 // Sets overall volume, where 1.0 is normal
88 static inline void Adpcm_volume( struct Hes_Apu_Adpcm
* this, double v
) { Synth_volume( &this->synth
, 0.6 / adpcm_osc_count
/ adpcm_amp_range
* v
); }