diff options
Diffstat (limited to 'apps/codecs/libgme/hes_apu_adpcm.h')
-rw-r--r-- | apps/codecs/libgme/hes_apu_adpcm.h | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/apps/codecs/libgme/hes_apu_adpcm.h b/apps/codecs/libgme/hes_apu_adpcm.h new file mode 100644 index 0000000000..5478f2b360 --- /dev/null +++ b/apps/codecs/libgme/hes_apu_adpcm.h | |||
@@ -0,0 +1,89 @@ | |||
1 | // Turbo Grafx 16 (PC Engine) ADPCM sound chip emulator | ||
2 | |||
3 | // Game_Music_Emu 0.6-pre | ||
4 | #ifndef HES_APU_ADPCM_H | ||
5 | #define HES_APU_ADPCM_H | ||
6 | |||
7 | #include "blargg_source.h" | ||
8 | #include "blargg_common.h" | ||
9 | #include "blip_buffer.h" | ||
10 | |||
11 | enum { adpcm_amp_range = 2048 }; | ||
12 | enum { adpcm_osc_count = 1 }; // 0 <= chan < osc_count | ||
13 | |||
14 | // Registers are at io_addr to io_addr+io_size-1 | ||
15 | enum { io_addr = 0x1800 }; | ||
16 | enum { io_size = 0x400 }; | ||
17 | |||
18 | struct State | ||
19 | { | ||
20 | byte pcmbuf [0x10000]; | ||
21 | byte port [0x10]; | ||
22 | int ad_sample; | ||
23 | int ad_ref_index; | ||
24 | bool ad_low_nibble; | ||
25 | int freq; | ||
26 | unsigned short addr; | ||
27 | unsigned short writeptr; | ||
28 | unsigned short readptr; | ||
29 | unsigned short playptr; | ||
30 | byte playflag; | ||
31 | byte repeatflag; | ||
32 | int length; | ||
33 | int playlength; | ||
34 | int playedsamplecount; | ||
35 | int volume; | ||
36 | int fadetimer; | ||
37 | int fadecount; | ||
38 | }; | ||
39 | |||
40 | struct Hes_Apu_Adpcm { | ||
41 | struct State state; | ||
42 | struct Blip_Synth synth; | ||
43 | |||
44 | struct Blip_Buffer* output; | ||
45 | blip_time_t last_time; | ||
46 | double next_timer; | ||
47 | int last_amp; | ||
48 | }; | ||
49 | |||
50 | // Init HES adpcm sound chip | ||
51 | void Adpcm_init( struct Hes_Apu_Adpcm* this ); | ||
52 | |||
53 | // Rest HES adpcm sound chip | ||
54 | void Adpcm_reset( struct Hes_Apu_Adpcm* this ); | ||
55 | |||
56 | // Sets buffer(s) to generate sound into, or 0 to mute. If only center is not 0, | ||
57 | // output is mono. | ||
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 ) | ||
59 | { | ||
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 | ||
63 | |||
64 | #if defined(ROCKBOX) | ||
65 | (void) chan; | ||
66 | #endif | ||
67 | |||
68 | if ( !center || !left || !right ) | ||
69 | { | ||
70 | left = center; | ||
71 | right = center; | ||
72 | } | ||
73 | |||
74 | this->output = center; | ||
75 | } | ||
76 | |||
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; | ||
79 | |||
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; | ||
82 | |||
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; | ||
86 | |||
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 ); } | ||
89 | #endif | ||