diff options
Diffstat (limited to 'apps/codecs/libgme/ay_apu.h')
-rw-r--r-- | apps/codecs/libgme/ay_apu.h | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/apps/codecs/libgme/ay_apu.h b/apps/codecs/libgme/ay_apu.h new file mode 100644 index 0000000000..ccdd204c46 --- /dev/null +++ b/apps/codecs/libgme/ay_apu.h | |||
@@ -0,0 +1,79 @@ | |||
1 | // AY-3-8910 sound chip ulator | ||
2 | |||
3 | // Game_Music_Emu 0.6-pre | ||
4 | #ifndef AY_APU_H | ||
5 | #define AY_APU_H | ||
6 | |||
7 | #include "blargg_common.h" | ||
8 | #include "blargg_source.h" | ||
9 | #include "blip_buffer.h" | ||
10 | |||
11 | // Number of registers | ||
12 | enum { ay_reg_count = 16 }; | ||
13 | enum { ay_osc_count = 3 }; | ||
14 | enum { ay_amp_range = 255 }; | ||
15 | |||
16 | struct osc_t | ||
17 | { | ||
18 | blip_time_t period; | ||
19 | blip_time_t delay; | ||
20 | short last_amp; | ||
21 | short phase; | ||
22 | struct Blip_Buffer* output; | ||
23 | }; | ||
24 | |||
25 | struct Ay_Apu { | ||
26 | struct osc_t oscs [ay_osc_count]; | ||
27 | |||
28 | blip_time_t last_time; | ||
29 | byte addr_; | ||
30 | byte regs [ay_reg_count]; | ||
31 | |||
32 | blip_time_t noise_delay; | ||
33 | unsigned noise_lfsr; | ||
34 | |||
35 | blip_time_t env_delay; | ||
36 | byte const* env_wave; | ||
37 | int env_pos; | ||
38 | byte env_modes [8] [48]; // values already passed through volume table | ||
39 | |||
40 | struct Blip_Synth synth_; // used by Ay_Core for beeper sound | ||
41 | }; | ||
42 | |||
43 | void Ay_apu_init( struct Ay_Apu* this ); | ||
44 | |||
45 | // Writes to address register | ||
46 | static inline void Ay_apu_write_addr( struct Ay_Apu* this, int data ) { this->addr_ = data & 0x0F; } | ||
47 | |||
48 | // Emulates to time t, then writes to current data register | ||
49 | void run_until( struct Ay_Apu* this, blip_time_t final_end_time ) ICODE_ATTR;; | ||
50 | void write_data_( struct Ay_Apu* this, int addr, int data ) ICODE_ATTR; | ||
51 | static inline void Ay_apu_write_data( struct Ay_Apu* this, blip_time_t t, int data ) { run_until( this, t ); write_data_( this, this->addr_, data ); } | ||
52 | |||
53 | // Reads from current data register | ||
54 | int Ay_apu_read( struct Ay_Apu* this ); | ||
55 | |||
56 | // Resets sound chip | ||
57 | void Ay_apu_reset( struct Ay_Apu* this ); | ||
58 | |||
59 | // Sets overall volume, where 1.0 is normal | ||
60 | static inline void Ay_apu_volume( struct Ay_Apu* this, double v ) { Synth_volume( &this->synth_, 0.7/ay_osc_count/ay_amp_range * v ); } | ||
61 | |||
62 | static inline void Ay_apu_set_output( struct Ay_Apu* this, int i, struct Blip_Buffer* out ) | ||
63 | { | ||
64 | assert( (unsigned) i < ay_osc_count ); | ||
65 | this->oscs [i].output = out; | ||
66 | } | ||
67 | |||
68 | // Emulates to time t, then subtracts t from the current time. | ||
69 | // OK if previous write call had time slightly after t. | ||
70 | static inline void Ay_apu_end_frame( struct Ay_Apu* this, blip_time_t time ) | ||
71 | { | ||
72 | if ( time > this->last_time ) | ||
73 | run_until( this, time ); | ||
74 | |||
75 | this->last_time -= time; | ||
76 | assert( this->last_time >= 0 ); | ||
77 | } | ||
78 | |||
79 | #endif | ||