openMSX
YM2413Burczynski.hh
Go to the documentation of this file.
1#ifndef YM2413BURCZYNSKI_HH
2#define YM2413BURCZYNSKI_HH
3
4#include "YM2413Core.hh"
5#include "FixedPoint.hh"
6#include "serialize_meta.hh"
7
8namespace openmsx {
9namespace YM2413Burczynski {
10
11class Channel;
12
16
17class Slot
18{
19public:
20 Slot();
21
22 void resetOperators();
23
27 void updateGenerators(Channel& channel);
28
29 [[nodiscard]] inline int calcOutput(Channel& channel, unsigned eg_cnt, bool carrier,
30 unsigned lfo_am, int phase);
31 [[nodiscard]] inline int calc_slot_mod(Channel& channel, unsigned eg_cnt, bool carrier,
32 unsigned lfo_pm, unsigned lfo_am);
33 [[nodiscard]] inline int calc_envelope(Channel& channel, unsigned eg_cnt, bool carrier);
34 [[nodiscard]] inline int calc_phase(Channel& channel, unsigned lfo_pm);
35
36 enum KeyPart { KEY_MAIN = 1, KEY_RHYTHM = 2 };
37 void setKeyOn(KeyPart part);
38 void setKeyOff(KeyPart part);
39 void setKeyOnOff(KeyPart part, bool enabled);
40
43 [[nodiscard]] bool isActive() const;
44
47 void setFrequencyMultiplier(uint8_t value);
48
51 void setKeyScaleRate(bool value);
52
56 void setEnvelopeSustained(bool value);
57
60 void setVibrato(bool value);
61
64 void setAmplitudeModulation(bool value);
65
68 void setTotalLevel(Channel& channel, uint8_t value);
69
72 void setKeyScaleLevel(Channel& channel, uint8_t value);
73
76 void setWaveform(uint8_t value);
77
80 void setFeedbackShift(uint8_t value);
81
84 void setAttackRate(const Channel& channel, uint8_t value);
85
88 void setDecayRate(const Channel& channel, uint8_t value);
89
92 void setReleaseRate(const Channel& channel, uint8_t value);
93
96 void setSustainLevel(uint8_t value);
97
100 void updateFrequency(Channel& channel);
101
102 template<typename Archive>
103 void serialize(Archive& ar, unsigned version);
104
105public: // public for serialization, otherwise could be private
111 };
112
113private:
116 void setEnvelopeState(EnvelopeState state);
117
118 inline void updateTotalLevel(Channel& channel);
119 inline void updateAttackRate(int kcodeScaled);
120 inline void updateDecayRate(int kcodeScaled);
121 inline void updateReleaseRate(int kcodeScaled);
122
123 const unsigned* wavetable; // waveform select
124
125 // Phase Generator
126 FreqIndex phase; // frequency counter
127 FreqIndex freq; // frequency counter step
128
129 // Envelope Generator
130 int TL; // total level: TL << 2
131 int TLL; // adjusted now TL
132 int egOut; // envelope counter
133 int sl; // sustain level: sl_tab[SL]
134 EnvelopeState state;
135
136 int op1_out[2]; // MOD output for feedback
137 bool eg_sustain; // percussive/nonpercussive mode
138 uint8_t fb_shift; // feedback shift value
139
140 uint8_t key; // 0 = KEY OFF, >0 = KEY ON
141
142 const uint8_t* eg_sel_dp;
143 const uint8_t* eg_sel_ar;
144 const uint8_t* eg_sel_dr;
145 const uint8_t* eg_sel_rr;
146 const uint8_t* eg_sel_rs;
147 unsigned eg_mask_dp; // == (1 << eg_sh_dp) - 1
148 unsigned eg_mask_ar; // == (1 << eg_sh_ar) - 1
149 unsigned eg_mask_dr; // == (1 << eg_sh_dr) - 1
150 unsigned eg_mask_rr; // == (1 << eg_sh_rr) - 1
151 unsigned eg_mask_rs; // == (1 << eg_sh_rs) - 1
152 uint8_t eg_sh_dp; // (dump state)
153 uint8_t eg_sh_ar; // (attack state)
154 uint8_t eg_sh_dr; // (decay state)
155 uint8_t eg_sh_rr; // (release state for non-perc.)
156 uint8_t eg_sh_rs; // (release state for perc.mode)
157
158 uint8_t ar; // attack rate: AR<<2
159 uint8_t dr; // decay rate: DR<<2
160 uint8_t rr; // release rate:RR<<2
161 uint8_t KSR; // key scale rate
162 uint8_t ksl; // keyscale level
163 uint8_t mul; // multiple: mul_tab[ML]
164
165 // LFO
166 uint8_t AMmask; // LFO Amplitude Modulation enable mask
167 uint8_t vib; // LFO Phase Modulation enable flag (active high)
168};
169
171{
172public:
173 Channel();
174
177 [[nodiscard]] inline int calcOutput(unsigned eg_cnt, unsigned lfo_pm, unsigned lfo_am, int fm);
178
181 void setFrequency(int block_fnum);
182
185 void setFrequencyLow(uint8_t value);
186
189 void setFrequencyHigh(uint8_t value);
190
195 void updateInstrumentPart(int part, uint8_t value);
196
200 void updateInstrument(const uint8_t* inst);
201
202 [[nodiscard]] int getBlockFNum() const;
203 [[nodiscard]] FreqIndex getFrequencyIncrement() const;
204 [[nodiscard]] int getKeyScaleLevelBase() const;
205 [[nodiscard]] uint8_t getKeyCode() const;
206 [[nodiscard]] bool isSustained() const;
207 void setSustain(bool sustained);
208
209 template<typename Archive>
210 void serialize(Archive& ar, unsigned version);
211
214
215private:
216 // phase generator state
217 int block_fnum; // block+fnum
218 FreqIndex fc; // Freq. increment base
219 int ksl_base; // KeyScaleLevel Base step
220 bool sus; // sus on/off (release speed in percussive mode)
221};
222
223class YM2413 final : public YM2413Core
224{
225public:
226 YM2413();
227
228 // YM2413Core
229 void reset() override;
230 void writePort(bool port, uint8_t value, int offset) override;
231 void pokeReg(uint8_t reg, uint8_t value) override;
232 [[nodiscard]] uint8_t peekReg(uint8_t reg) const override;
233 void generateChannels(float* bufs[9 + 5], unsigned num) override;
234 [[nodiscard]] float getAmplificationFactor() const override;
235
236 template<typename Archive>
237 void serialize(Archive& ar, unsigned version);
238
239private:
240 void writeReg(uint8_t reg, uint8_t value);
241
244 void resetOperators();
245
246 [[nodiscard]] inline bool isRhythm() const;
247
248 [[nodiscard]] Channel& getChannelForReg(uint8_t reg);
249
254 void updateCustomInstrument(int part, uint8_t value);
255
256 void setRhythmFlags(uint8_t old);
257
258private:
260 Channel channels[9];
261
263 unsigned eg_cnt;
264
266 int noise_rng;
267
269 unsigned idleSamples;
270
273 LFOAMIndex lfo_am_cnt;
274 LFOPMIndex lfo_pm_cnt;
275
282 uint8_t inst_tab[19][8];
283
285 uint8_t reg[0x40];
286 uint8_t registerLatch;
287};
288
289} // namespace YM2413Burczynski
290
294
295} // namespace openmsx
296
297#endif
void updateInstrumentPart(int part, uint8_t value)
Sets some synthesis parameters as specified by the instrument.
void setFrequencyLow(uint8_t value)
Changes the lower 8 bits of the frequency for this channel.
void serialize(Archive &ar, unsigned version)
void setFrequency(int block_fnum)
Sets the frequency for this channel.
void updateInstrument(const uint8_t *inst)
Sets all synthesis parameters as specified by the instrument.
void setFrequencyHigh(uint8_t value)
Changes the higher 4 bits of the frequency for this channel.
int calcOutput(unsigned eg_cnt, unsigned lfo_pm, unsigned lfo_am, int fm)
Calculate the value of the current sample produced by this channel.
void setSustainLevel(uint8_t value)
Sets the sustain level [0..15].
EnvelopeState
Envelope Generator phases Note: These are ordered: phase constants are compared in the code.
void updateFrequency(Channel &channel)
Called by Channel when block_fnum changes.
void setEnvelopeSustained(bool value)
Sets the envelope type of the current instrument.
void setKeyOnOff(KeyPart part, bool enabled)
void setAttackRate(const Channel &channel, uint8_t value)
Sets the attack rate [0..15].
int calcOutput(Channel &channel, unsigned eg_cnt, bool carrier, unsigned lfo_am, int phase)
void setTotalLevel(Channel &channel, uint8_t value)
Sets the total level: [0..63].
void setFrequencyMultiplier(uint8_t value)
Sets the frequency multiplier [0..15].
void setReleaseRate(const Channel &channel, uint8_t value)
Sets the release rate [0..15].
void setWaveform(uint8_t value)
Sets the waveform: 0 = sinus, 1 = half sinus, half silence.
int calc_envelope(Channel &channel, unsigned eg_cnt, bool carrier)
void serialize(Archive &ar, unsigned version)
void setVibrato(bool value)
Enables (true) or disables (false) vibrato.
int calc_phase(Channel &channel, unsigned lfo_pm)
void setAmplitudeModulation(bool value)
Enables (true) or disables (false) amplitude modulation.
void setDecayRate(const Channel &channel, uint8_t value)
Sets the decay rate [0..15].
void setKeyScaleLevel(Channel &channel, uint8_t value)
Sets the key scale level: 0->0 / 1->1.5 / 2->3.0 / 3->6.0 dB/OCT.
void setFeedbackShift(uint8_t value)
Sets the amount of feedback [0..7].
bool isActive() const
Does this slot currently produce an output signal?
int calc_slot_mod(Channel &channel, unsigned eg_cnt, bool carrier, unsigned lfo_pm, unsigned lfo_am)
void setKeyScaleRate(bool value)
Sets the key scale rate: true->0, false->2.
void updateGenerators(Channel &channel)
Update phase increment counter of operator.
void writePort(bool port, uint8_t value, int offset) override
Write to the YM2413 register/data port.
void serialize(Archive &ar, unsigned version)
void reset() override
Reset this YM2413 core.
void pokeReg(uint8_t reg, uint8_t value) override
Write to a YM2413 register (for debug).
float getAmplificationFactor() const override
Returns normalization factor.
void generateChannels(float *bufs[9+5], unsigned num) override
uint8_t peekReg(uint8_t reg) const override
Read from a YM2413 register (for debug).
Abstract interface for the YM2413 core.
Definition: YM2413Core.hh:27
This file implemented 3 utility functions:
Definition: Autofire.cc:9
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)