summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libgme/emu8950.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libgme/emu8950.h')
-rw-r--r--lib/rbcodec/codecs/libgme/emu8950.h248
1 files changed, 248 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libgme/emu8950.h b/lib/rbcodec/codecs/libgme/emu8950.h
new file mode 100644
index 0000000000..02169050d2
--- /dev/null
+++ b/lib/rbcodec/codecs/libgme/emu8950.h
@@ -0,0 +1,248 @@
1#ifndef __Y8950_HH__
2#define __Y8950_HH__
3
4#include "blargg_common.h"
5#include "emuadpcm.h"
6
7#define AUDIO_MONO_BUFFER_SIZE 1024
8
9// Dynamic range of envelope
10static const double EG_STEP = 0.1875;
11#define EG_BITS 9
12#define EG_MUTE (1<<EG_BITS)
13// Dynamic range of sustine level
14static const double SL_STEP = 3.0;
15static const int SL_BITS = 4;
16#define SL_MUTE (1<<SL_BITS)
17// Size of Sintable ( 1 -- 18 can be used, but 7 -- 14 recommended.)
18#define PG_BITS 10
19#define PG_WIDTH (1<<PG_BITS)
20// Phase increment counter
21static const int DP_BITS = 19;
22#define DP_WIDTH (1<<DP_BITS)
23#define DP_BASE_BITS (DP_BITS - PG_BITS)
24// Bits for envelope phase incremental counter
25static const int EG_DP_BITS = 23;
26#define EG_DP_WIDTH (1<<EG_DP_BITS)
27// Dynamic range of total level
28static const double TL_STEP = 0.75;
29#define TL_BITS 6
30#define TL_MUTE (1<<TL_BITS)
31
32static const double DB_STEP = 0.1875;
33#define DB_BITS 9
34#define DB_MUTE (1<<DB_BITS)
35// PM table is calcurated by PM_AMP * pow(2,PM_DEPTH*sin(x)/1200)
36static const int PM_AMP_BITS = 8;
37#define PM_AMP (1<<PM_AMP_BITS)
38
39
40
41static const int CLK_FREQ = 3579545;
42static const double MPI = 3.14159265358979;
43// PM speed(Hz) and depth(cent)
44static const double PM_SPEED = 6.4;
45static const double PM_DEPTH = (13.75/2);
46static const double PM_DEPTH2 = 13.75;
47// AM speed(Hz) and depth(dB)
48static const double AM_SPEED = 3.7;
49static const double AM_DEPTH = 1.0;
50static const double AM_DEPTH2 = 4.8;
51// Bits for liner value
52static const int DB2LIN_AMP_BITS = 11;
53#define SLOT_AMP_BITS DB2LIN_AMP_BITS
54
55// Bits for Pitch and Amp modulator
56#define PM_PG_BITS 8
57#define PM_PG_WIDTH (1<<PM_PG_BITS)
58static const int PM_DP_BITS = 16;
59#define PM_DP_WIDTH (1<<PM_DP_BITS)
60#define AM_PG_BITS 8
61#define AM_PG_WIDTH (1<<AM_PG_BITS)
62static const int AM_DP_BITS = 16;
63#define AM_DP_WIDTH (1<<AM_DP_BITS)
64
65// Bitmask for register 0x04
66/** Timer1 Start. */
67static const int R04_ST1 = 0x01;
68/** Timer2 Start. */
69static const int R04_ST2 = 0x02;
70// not used
71//static const int R04 = 0x04;
72/** Mask 'Buffer Ready'. */
73static const int R04_MASK_BUF_RDY = 0x08;
74/** Mask 'End of sequence'. */
75static const int R04_MASK_EOS = 0x10;
76/** Mask Timer2 flag. */
77static const int R04_MASK_T2 = 0x20;
78/** Mask Timer1 flag. */
79static const int R04_MASK_T1 = 0x40;
80/** IRQ RESET. */
81static const int R04_IRQ_RESET = 0x80;
82
83// Bitmask for status register
84#define STATUS_EOS (R04_MASK_EOS)
85#define STATUS_BUF_RDY (R04_MASK_BUF_RDY)
86#define STATUS_T2 (R04_MASK_T2)
87#define STATUS_T1 (R04_MASK_T1)
88
89// Definition of envelope mode
90enum { ATTACK,DECAY,SUSHOLD,SUSTINE,RELEASE,FINISH };
91
92struct Patch {
93 bool AM, PM, EG;
94 byte KR; // 0-1
95 byte ML; // 0-15
96 byte KL; // 0-3
97 byte TL; // 0-63
98 byte FB; // 0-7
99 byte AR; // 0-15
100 byte DR; // 0-15
101 byte SL; // 0-15
102 byte RR; // 0-15
103};
104
105void patchReset(struct Patch* p);
106
107struct Slot {
108 // OUTPUT
109 int feedback;
110 /** Output value of slot. */
111 int output[5];
112
113 // for Phase Generator (PG)
114 /** Phase. */
115 unsigned int phase;
116 /** Phase increment amount. */
117 unsigned int dphase;
118 /** Output. */
119 int pgout;
120
121 // for Envelope Generator (EG)
122 /** F-Number. */
123 int fnum;
124 /** Block. */
125 int block;
126 /** Total Level + Key scale level. */
127 int tll;
128 /** Key scale offset (Rks). */
129 int rks;
130 /** Current state. */
131 int eg_mode;
132 /** Phase. */
133 unsigned int eg_phase;
134 /** Phase increment amount. */
135 unsigned int eg_dphase;
136 /** Output. */
137 int egout;
138
139 bool slotStatus;
140 struct Patch patch;
141
142 // refer to Y8950->
143 int *plfo_pm;
144 int *plfo_am;
145};
146
147void slotReset(struct Slot* slot);
148
149
150struct OPLChannel {
151 bool alg;
152 struct Slot mod, car;
153};
154
155void channelReset(struct OPLChannel* ch);
156
157
158struct Y8950
159{
160 int adr;
161 int output[2];
162 // Register
163 byte reg[0x100];
164 bool rythm_mode;
165 // Pitch Modulator
166 int pm_mode;
167 unsigned int pm_phase;
168 // Amp Modulator
169 int am_mode;
170 unsigned int am_phase;
171
172 // Noise Generator
173 int noise_seed;
174 int whitenoise;
175 int noiseA;
176 int noiseB;
177 unsigned int noiseA_phase;
178 unsigned int noiseB_phase;
179 unsigned int noiseA_dphase;
180 unsigned int noiseB_dphase;
181
182 // Channel & Slot
183 struct OPLChannel ch[9];
184 struct Slot *slot[18];
185
186 unsigned int pm_dphase;
187 int lfo_pm;
188 unsigned int am_dphase;
189 int lfo_am;
190
191 int maxVolume;
192 bool internalMuted;
193
194 int clockRate;
195
196 /** STATUS Register. */
197 byte status;
198 /** bit=0 -> masked. */
199 byte statusMask;
200 /* MsxAudioIRQHelper irq; */
201
202 // ADPCM
203 struct Y8950Adpcm adpcm;
204
205 /** 13-bit (exponential) DAC. */
206 /* DACSound16S dac13; */
207
208 // DAC stuff
209 int dacSampleVolume;
210 int dacOldSampleVolume;
211 int dacSampleVolumeSum;
212 int dacCtrlVolume;
213 int dacDaVolume;
214 int dacEnabled;
215
216 // Internal buffer
217 int buffer[AUDIO_MONO_BUFFER_SIZE];
218};
219
220void OPL_init(struct Y8950* this_, byte* ramBank, int sampleRam);
221
222void OPL_reset(struct Y8950* this_);
223void OPL_writeReg(struct Y8950* this_, byte reg, byte data);
224byte OPL_readReg(struct Y8950* this_, byte reg);
225byte OPL_readStatus(struct Y8950* this_);
226static inline void OPL_setInternalMute(struct Y8950* this_, bool muted) { this_->internalMuted = muted; }
227static inline bool OPL_isInternalMuted(struct Y8950* this_) { return this_->internalMuted; }
228
229void OPL_setSampleRate(struct Y8950* this_, int sampleRate, int clockRate);
230int* OPL_updateBuffer(struct Y8950* this_, int length);
231
232// SoundDevice
233void OPL_setInternalVolume(struct Y8950* this_, short maxVolume);
234
235void OPL_setStatus(struct Y8950* this_, byte flags);
236void OPL_resetStatus(struct Y8950* this_, byte flags);
237void OPL_changeStatusMask(struct Y8950* this_, byte newMask);
238
239
240// Adjust envelope speed which depends on sampling rate
241static inline unsigned int rate_adjust(int x, int rate, int clk)
242{
243 unsigned int tmp = (long long)x * clk / 72 / rate;
244// assert (tmp <= 4294967295U);
245 return tmp;
246}
247
248#endif