summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libgme/ay_apu.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libgme/ay_apu.h')
-rw-r--r--lib/rbcodec/codecs/libgme/ay_apu.h79
1 files changed, 79 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libgme/ay_apu.h b/lib/rbcodec/codecs/libgme/ay_apu.h
new file mode 100644
index 0000000000..3df6ba1118
--- /dev/null
+++ b/lib/rbcodec/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
12enum { ay_reg_count = 16 };
13enum { ay_osc_count = 3 };
14enum { ay_amp_range = 255 };
15
16struct 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
25struct 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
43void Ay_apu_init( struct Ay_Apu* this );
44
45// Writes to address register
46static 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
49void run_until( struct Ay_Apu* this, blip_time_t final_end_time );;
50void write_data_( struct Ay_Apu* this, int addr, int data );
51static 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
54int Ay_apu_read( struct Ay_Apu* this );
55
56// Resets sound chip
57void Ay_apu_reset( struct Ay_Apu* this );
58
59// Sets overall volume, where 1.0 is normal
60static inline void Ay_apu_volume( struct Ay_Apu* this, int v ) { Synth_volume( &this->synth_, (v*7)/10 /ay_osc_count/ay_amp_range ); }
61
62static 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.
70static 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