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 
8 namespace openmsx {
9 namespace YM2413Burczynski {
10 
11 class Channel;
12 
16 
17 class Slot
18 {
19 public:
20  Slot();
21 
22  void resetOperators();
23 
27  void updateGenerators(Channel& channel);
28 
29  inline int calcOutput(Channel& channel, unsigned eg_cnt, bool carrier,
30  unsigned lfo_am, int phase);
31  inline int calc_slot_mod(Channel& channel, unsigned eg_cnt, bool carrier,
32  unsigned lfo_pm, unsigned lfo_am);
33  inline int calc_envelope(Channel& channel, unsigned eg_cnt, bool carrier);
34  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  bool isActive() const;
44 
47  void setFrequencyMultiplier(byte 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, byte value);
69 
72  void setKeyScaleLevel(Channel& channel, byte value);
73 
76  void setWaveform(byte value);
77 
80  void setFeedbackShift(byte value);
81 
84  void setAttackRate(const Channel& channel, byte value);
85 
88  void setDecayRate(const Channel& channel, byte value);
89 
92  void setReleaseRate(const Channel& channel, byte value);
93 
96  void setSustainLevel(byte value);
97 
100  void updateFrequency(Channel& channel);
101 
102  template<typename Archive>
103  void serialize(Archive& ar, unsigned version);
104 
105 public: // public for serialization, otherwise could be private
111  };
112 
113 private:
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  byte fb_shift; // feedback shift value
139 
140  byte key; // 0 = KEY OFF, >0 = KEY ON
141 
142  const byte* eg_sel_dp;
143  const byte* eg_sel_ar;
144  const byte* eg_sel_dr;
145  const byte* eg_sel_rr;
146  const byte* 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  byte eg_sh_dp; // (dump state)
153  byte eg_sh_ar; // (attack state)
154  byte eg_sh_dr; // (decay state)
155  byte eg_sh_rr; // (release state for non-perc.)
156  byte eg_sh_rs; // (release state for perc.mode)
157 
158  byte ar; // attack rate: AR<<2
159  byte dr; // decay rate: DR<<2
160  byte rr; // release rate:RR<<2
161  byte KSR; // key scale rate
162  byte ksl; // keyscale level
163  byte mul; // multiple: mul_tab[ML]
164 
165  // LFO
166  byte AMmask; // LFO Amplitude Modulation enable mask
167  byte vib; // LFO Phase Modulation enable flag (active high)
168 };
169 
170 class Channel
171 {
172 public:
173  Channel();
174 
177  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(byte value);
186 
189  void setFrequencyHigh(byte value);
190 
195  void updateInstrumentPart(int part, byte value);
196 
200  void updateInstrument(const byte* inst);
201 
202  int getBlockFNum() const;
203  FreqIndex getFrequencyIncrement() const;
204  int getKeyScaleLevelBase() const;
205  byte getKeyCode() const;
206  bool isSustained() const;
207  void setSustain(bool sustained);
208 
209  template<typename Archive>
210  void serialize(Archive& ar, unsigned version);
211 
214 
215 private:
216  // phase generator state
217  int block_fnum; // block+fnum
218  FreqIndex fc; // Freq. freqement base
219  int ksl_base; // KeyScaleLevel Base step
220  bool sus; // sus on/off (release speed in percussive mode)
221 };
222 
223 class YM2413 final : public YM2413Core
224 {
225 public:
226  YM2413();
227 
228  template<typename Archive>
229  void serialize(Archive& ar, unsigned version);
230 
231 private:
232  // YM2413Core
233  void reset() override;
234  void writeReg(byte reg, byte value) override;
235  byte peekReg(byte reg) const override;
236  void generateChannels(float* bufs[9 + 5], unsigned num) override;
237  float getAmplificationFactor() const override;
238 
241  void resetOperators();
242 
243  inline bool isRhythm() const;
244 
245  Channel& getChannelForReg(byte reg);
246 
251  void updateCustomInstrument(int part, byte value);
252 
253  void setRhythmFlags(byte old);
254 
256  Channel channels[9];
257 
259  unsigned eg_cnt;
260 
262  int noise_rng;
263 
265  unsigned idleSamples;
266 
267  using LFOAMIndex = FixedPoint< 6>;
268  using LFOPMIndex = FixedPoint<10>;
269  LFOAMIndex lfo_am_cnt;
270  LFOPMIndex lfo_pm_cnt;
271 
278  byte inst_tab[19][8];
279 
281  byte reg[0x40];
282 };
283 
284 } // namespace YM2413Burczynski
285 
289 
290 } // namespace openmsx
291 
292 #endif
void setTotalLevel(Channel &channel, byte value)
Sets the total level: [0..63].
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
Abstract interface for the YM2413 core.
Definition: YM2413Core.hh:26
int calcOutput(Channel &channel, unsigned eg_cnt, bool carrier, unsigned lfo_am, int phase)
void setFeedbackShift(byte value)
Sets the amount of feedback [0..7].
void setWaveform(byte value)
Sets the waveform: 0 = sinus, 1 = half sinus, half silence.
int calc_envelope(Channel &channel, unsigned eg_cnt, bool carrier)
void setKeyScaleRate(bool value)
Sets the key scale rate: true->0, false->2.
void setVibrato(bool value)
Enables (true) or disables (false) vibrato.
void setEnvelopeSustained(bool value)
Sets the envelope type of the current instrument.
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
void setKeyScaleLevel(Channel &channel, byte value)
Sets the key scale level: 0->0 / 1->1.5 / 2->3.0 / 3->6.0 dB/OCT.
void setKeyOnOff(KeyPart part, bool enabled)
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
void setAmplitudeModulation(bool value)
Enables (true) or disables (false) amplitude modulation.
void setDecayRate(const Channel &channel, byte value)
Sets the decay rate [0..15].
void setReleaseRate(const Channel &channel, byte value)
Sets the release rate [0..15].
void updateFrequency(Channel &channel)
Called by Channel when block_fnum changes.
int calc_slot_mod(Channel &channel, unsigned eg_cnt, bool carrier, unsigned lfo_pm, unsigned lfo_am)
void setFrequencyMultiplier(byte value)
Sets the frequency multiplier [0..15].
YM2413
Definition: YM2413.cc:88
EnvelopeState
Envelope Generator phases Note: These are ordered: phase constants are compared in the code...
bool isActive() const
Does this slot currently produce an output signal?
int calc_phase(Channel &channel, unsigned lfo_pm)
void setAttackRate(const Channel &channel, byte value)
Sets the attack rate [0..15].
void serialize(Archive &ar, unsigned version)
void updateGenerators(Channel &channel)
Update phase increment counter of operator.
void setSustainLevel(byte value)
Sets the sustain level [0..15].