summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libgme/nes_oscs.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libgme/nes_oscs.h')
-rw-r--r--lib/rbcodec/codecs/libgme/nes_oscs.h164
1 files changed, 164 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libgme/nes_oscs.h b/lib/rbcodec/codecs/libgme/nes_oscs.h
new file mode 100644
index 0000000000..1eeb302e6c
--- /dev/null
+++ b/lib/rbcodec/codecs/libgme/nes_oscs.h
@@ -0,0 +1,164 @@
1// Private oscillators used by Nes_Apu
2
3// Nes_Snd_Emu 0.1.8
4#ifndef NES_OSCS_H
5#define NES_OSCS_H
6
7#include "blargg_common.h"
8#include "blip_buffer.h"
9#include "nes_cpu.h"
10
11struct Nes_Apu;
12
13struct Nes_Osc
14{
15 unsigned char regs [4];
16 bool reg_written [4];
17 struct Blip_Buffer* output;
18 int length_counter;// length counter (0 if unused by oscillator)
19 int delay; // delay until next (potential) transition
20 int last_amp; // last amplitude oscillator was outputting
21};
22
23void Osc_clock_length( struct Nes_Osc* this, int halt_mask );
24static inline int Osc_period( struct Nes_Osc* this )
25{
26 return (this->regs [3] & 7) * 0x100 + (this->regs [2] & 0xFF);
27}
28
29static inline void Osc_reset( struct Nes_Osc* this )
30{
31 this->delay = 0;
32 this->last_amp = 0;
33}
34
35static inline int Osc_update_amp( struct Nes_Osc* this, int amp )
36{
37 int delta = amp - this->last_amp;
38 this->last_amp = amp;
39 return delta;
40}
41
42// Nes_Square
43
44enum { negate_flag = 0x08 };
45enum { shift_mask = 0x07 };
46enum { square_phase_range = 8 };
47
48typedef struct Blip_Synth Synth;
49
50struct Nes_Square
51{
52 struct Nes_Osc osc;
53 int envelope;
54 int env_delay;
55 int phase;
56 int sweep_delay;
57
58 Synth* synth; // shared between squares
59};
60
61static inline void Square_set_synth( struct Nes_Square* this, Synth* s ) { this->synth = s; }
62
63void Square_clock_sweep( struct Nes_Square* this, int adjust );
64void Square_run( struct Nes_Square* this, nes_time_t, nes_time_t );
65
66static inline void Square_reset( struct Nes_Square* this )
67{
68 this->sweep_delay = 0;
69 this->envelope = 0;
70 this->env_delay = 0;
71 Osc_reset( &this->osc );
72}
73
74void Square_clock_envelope( struct Nes_Square* this );
75int Square_volume( struct Nes_Square* this );
76
77// Nes_Triangle
78
79enum { Triangle_phase_range = 16 };
80
81struct Nes_Triangle
82{
83 struct Nes_Osc osc;
84
85 int phase;
86 int linear_counter;
87 struct Blip_Synth synth;
88};
89
90void Triangle_run( struct Nes_Triangle* this, nes_time_t, nes_time_t );
91void Triangle_clock_linear_counter( struct Nes_Triangle* this );
92
93static inline void Triangle_reset( struct Nes_Triangle* this )
94{
95 this->linear_counter = 0;
96 this->phase = 1;
97 Osc_reset( &this->osc );
98}
99
100// Nes_Noise
101struct Nes_Noise
102{
103 struct Nes_Osc osc;
104
105 int envelope;
106 int env_delay;
107 int noise;
108 struct Blip_Synth synth;
109};
110
111void Noise_clock_envelope( struct Nes_Noise* this );
112int Noise_volume( struct Nes_Noise* this );
113void Noise_run( struct Nes_Noise* this, nes_time_t, nes_time_t );
114
115static inline void Noise_reset( struct Nes_Noise* this )
116{
117 this->noise = 1 << 14;
118 this->envelope = 0;
119 this->env_delay = 0;
120 Osc_reset( &this->osc );
121}
122
123// Nes_Dmc
124
125enum { loop_flag = 0x40 };
126
127struct Nes_Dmc
128{
129 struct Nes_Osc osc;
130
131 int address; // address of next byte to read
132 int period;
133 int buf;
134 int bits_remain;
135 int bits;
136 bool buf_full;
137 bool silence;
138
139 int dac;
140
141 nes_time_t next_irq;
142 bool irq_enabled;
143 bool irq_flag;
144 bool pal_mode;
145 bool nonlinear;
146
147 int (*prg_reader)( void*, int ); // needs to be initialized to prg read function
148 void* prg_reader_data;
149
150 struct Nes_Apu* apu;
151
152 struct Blip_Synth synth;
153};
154
155void Dmc_start( struct Nes_Dmc* this );
156void Dmc_write_register( struct Nes_Dmc* this, int, int );
157void Dmc_run( struct Nes_Dmc* this, nes_time_t, nes_time_t );
158void Dmc_recalc_irq( struct Nes_Dmc* this );
159void Dmc_fill_buffer( struct Nes_Dmc* this );
160void Dmc_reset( struct Nes_Dmc* this );
161
162int Dmc_count_reads( struct Nes_Dmc* this, nes_time_t, nes_time_t* );
163
164#endif