ScummVM API documentation
dbopl.h
1/*
2 * Copyright (C) 2002-2011 The DOSBox Team
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19// Last synch with DOSBox SVN trunk r3752
20
21#ifndef AUDIO_SOFTSYNTH_OPL_DBOPL_H
22#define AUDIO_SOFTSYNTH_OPL_DBOPL_H
23
24#include "common/scummsys.h"
25
26#ifndef DISABLE_DOSBOX_OPL
27
28namespace OPL {
29namespace DOSBox {
30
31//Use 8 handlers based on a small logatirmic wavetabe and an exponential table for volume
32#define WAVE_HANDLER 10
33//Use a logarithmic wavetable with an exponential table for volume
34#define WAVE_TABLELOG 11
35//Use a linear wavetable with a multiply table for volume
36#define WAVE_TABLEMUL 12
37
38//Select the type of wave generator routine
39#define DBOPL_WAVE WAVE_TABLEMUL
40
41namespace DBOPL {
42
43// Type aliases for the DBOPL code
44typedef int Bits;
45typedef uint Bitu;
46
47typedef int8 Bit8s;
48typedef uint8 Bit8u;
49
50typedef int16 Bit16s;
51typedef uint16 Bit16u;
52
53typedef int32 Bit32s;
54typedef uint32 Bit32u;
55
56#define DB_FASTCALL
57#define GCC_UNLIKELY(x) (x)
58#define INLINE inline
59// -------------------------------
60
61struct Chip;
62struct Operator;
63struct Channel;
64
65#if (DBOPL_WAVE == WAVE_HANDLER)
66typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume );
67#endif
68
69typedef Bits ( DBOPL::Operator::*VolumeHandler) ( );
70typedef Channel* ( DBOPL::Channel::*SynthHandler) ( Chip* chip, Bit32u samples, Bit32s* output );
71
72//Different synth modes that can generate blocks of data
73typedef enum {
74 sm2AM,
75 sm2FM,
76 sm3AM,
77 sm3FM,
78 sm4Start,
79 sm3FMFM,
80 sm3AMFM,
81 sm3FMAM,
82 sm3AMAM,
83 sm6Start,
84 sm2Percussion,
85 sm3Percussion
86} SynthMode;
87
88//Shifts for the values contained in chandata variable
89enum {
90 SHIFT_KSLBASE = 16,
91 SHIFT_KEYCODE = 24
92};
93
94struct Operator {
95public:
96 //Masks for operator 20 values
97 enum {
98 MASK_KSR = 0x10,
99 MASK_SUSTAIN = 0x20,
100 MASK_VIBRATO = 0x40,
101 MASK_TREMOLO = 0x80
102 };
103
104 typedef enum {
105 OFF,
106 RELEASE,
107 SUSTAIN,
108 DECAY,
109 ATTACK
110 } State;
111
112 VolumeHandler volHandler;
113
114#if (DBOPL_WAVE == WAVE_HANDLER)
115 WaveHandler waveHandler; //Routine that generate a wave
116#else
117 Bit16s* waveBase;
118 Bit32u waveMask;
119 Bit32u waveStart;
120#endif
121 Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index
122 Bit32u waveAdd; //The base frequency without vibrato
123 Bit32u waveCurrent; //waveAdd + vibratao
124
125 Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this
126 Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove?
127 Bit32u vibrato; //Scaled up vibrato strength
128 Bit32s sustainLevel; //When stopping at sustain level stop here
129 Bit32s totalLevel; //totalLevel is added to every generated volume
130 Bit32u currentLevel; //totalLevel + tremolo
131 Bit32s volume; //The currently active volume
132
133 Bit32u attackAdd; //Timers for the different states of the envelope
134 Bit32u decayAdd;
135 Bit32u releaseAdd;
136 Bit32u rateIndex; //Current position of the evenlope
137
138 Bit8u rateZero; //Bits for the different states of the envelope having no changes
139 Bit8u keyOn; //Bitmask of different values that can generate keyon
140 //Registers, also used to check for changes
141 Bit8u reg20, reg40, reg60, reg80, regE0;
142 //Active part of the envelope we're in
143 Bit8u state;
144 //0xff when tremolo is enabled
145 Bit8u tremoloMask;
146 //Strength of the vibrato
147 Bit8u vibStrength;
148 //Keep track of the calculated KSR so we can check for changes
149 Bit8u ksr;
150private:
151 void SetState( Bit8u s );
152 void UpdateAttack( const Chip* chip );
153 void UpdateRelease( const Chip* chip );
154 void UpdateDecay( const Chip* chip );
155public:
156 void UpdateAttenuation();
157 void UpdateRates( const Chip* chip );
158 void UpdateFrequency( );
159
160 void Write20( const Chip* chip, Bit8u val );
161 void Write40( const Chip* chip, Bit8u val );
162 void Write60( const Chip* chip, Bit8u val );
163 void Write80( const Chip* chip, Bit8u val );
164 void WriteE0( const Chip* chip, Bit8u val );
165
166 bool Silent() const;
167 void Prepare( const Chip* chip );
168
169 void KeyOn( Bit8u mask);
170 void KeyOff( Bit8u mask);
171
172 template< State state>
173 Bits TemplateVolume( );
174
175 Bit32s RateForward( Bit32u add );
176 Bitu ForwardWave();
177 Bitu ForwardVolume();
178
179 Bits GetSample( Bits modulation );
180 Bits GetWave( Bitu index, Bitu vol );
181public:
182 Operator();
183};
184
185struct Channel {
186 Operator op[2];
187 inline Operator* Op( Bitu index ) {
188 return &( ( this + (index >> 1) )->op[ index & 1 ]);
189 }
190 SynthHandler synthHandler;
191 Bit32u chanData; //Frequency/octave and derived values
192 Bit32s old[2]; //Old data for feedback
193
194 Bit8u feedback; //Feedback shift
195 Bit8u regB0; //Register values to check for changes
196 Bit8u regC0;
197 //This should correspond with reg104, bit 6 indicates a Percussion channel, bit 7 indicates a silent channel
198 Bit8u fourMask;
199 Bit8s maskLeft; //Sign extended values for both channel's panning
200 Bit8s maskRight;
201
202 //Forward the channel data to the operators of the channel
203 void SetChanData( const Chip* chip, Bit32u data );
204 //Change in the chandata, check for new values and if we have to forward to operators
205 void UpdateFrequency( const Chip* chip, Bit8u fourOp );
206 void WriteA0( const Chip* chip, Bit8u val );
207 void WriteB0( const Chip* chip, Bit8u val );
208 void WriteC0( const Chip* chip, Bit8u val );
209 void ResetC0( const Chip* chip );
210
211 //call this for the first channel
212 template< bool opl3Mode >
213 void GeneratePercussion( Chip* chip, Bit32s* output );
214
215 //Generate blocks of data in specific modes
216 template<SynthMode mode>
217 Channel* BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output );
218 Channel();
219};
220
221struct Chip {
222 //This is used as the base counter for vibrato and tremolo
223 Bit32u lfoCounter;
224 Bit32u lfoAdd;
225
226
227 Bit32u noiseCounter;
228 Bit32u noiseAdd;
229 Bit32u noiseValue;
230
231 //Frequency scales for the different multiplications
232 Bit32u freqMul[16];
233 //Rates for decay and release for rate of this chip
234 Bit32u linearRates[76];
235 //Best match attack rates for the rate of this chip
236 Bit32u attackRates[76];
237
238 //18 channels with 2 operators each
239 Channel chan[18];
240
241 Bit8u reg104;
242 Bit8u reg08;
243 Bit8u reg04;
244 Bit8u regBD;
245 Bit8u vibratoIndex;
246 Bit8u tremoloIndex;
247 Bit8s vibratoSign;
248 Bit8u vibratoShift;
249 Bit8u tremoloValue;
250 Bit8u vibratoStrength;
251 Bit8u tremoloStrength;
252 //Mask for allowed wave forms
253 Bit8u waveFormMask;
254 //0 or -1 when enabled
255 Bit8s opl3Active;
256
257 //Return the maximum amount of samples before and LFO change
258 Bit32u ForwardLFO( Bit32u samples );
259 Bit32u ForwardNoise();
260
261 void WriteBD( Bit8u val );
262 void WriteReg(Bit32u reg, Bit8u val );
263
264 Bit32u WriteAddr( Bit32u port, Bit8u val );
265
266 void GenerateBlock2( Bitu samples, Bit32s* output );
267 void GenerateBlock3( Bitu samples, Bit32s* output );
268
269 void Generate( Bit32u samples );
270 void Setup( Bit32u r );
271
272 Chip();
273};
274
275void InitTables();
276
277} //Namespace
278} // End of namespace DOSBox
279} // End of namespace OPL
280
281#endif // !DISABLE_DOSBOX_OPL
282
283#endif
Definition: dbopl.h:185
Definition: dbopl.h:221
Definition: dbopl.h:94