openMSX
YM2413Okazaki.hh
Go to the documentation of this file.
1#ifndef YM2413OKAZAKI_HH
2#define YM2413OKAZAKI_HH
3
4#include "YM2413Core.hh"
5#include "FixedPoint.hh"
6#include "serialize_meta.hh"
7
8namespace openmsx {
9namespace YM2413Okazaki {
10
11class YM2413;
12
13constexpr int EP_FP_BITS = 15;
15
18};
19
20class Patch {
21public:
25 Patch();
26
27 void initModulator(const uint8_t* data);
28 void initCarrier (const uint8_t* data);
29
31 inline void setKR(uint8_t value);
33 inline void setML(uint8_t value);
35 inline void setKL(uint8_t value);
37 inline void setTL(uint8_t value);
39 inline void setWF(uint8_t value);
41 inline void setFB(uint8_t value);
43 inline void setSL(uint8_t value);
44
45 const unsigned* WF; // 0-1 transformed to waveform[0-1]
46 const uint8_t* KL; // 0-3 transformed to tllTable[0-3]
47 unsigned SL; // 0-15 transformed to slTable[0-15]
48 uint8_t AMPM; // 0-3 2 packed booleans
49 bool EG; // 0-1
50 uint8_t KR; // 0-1 transformed to 10,8
51 uint8_t ML; // 0-15 transformed to mlTable[0-15]
52 uint8_t TL; // 0-63 transformed to TL2EG(0..63) == [0..252]
53 uint8_t FB; // 0,1-7 transformed to 0,7-1
54 uint8_t AR; // 0-15
55 uint8_t DR; // 0-15
56 uint8_t RR; // 0-15
57};
58
59class Slot {
60public:
61 void reset();
62
64 [[nodiscard]] inline bool isActive() const;
65
66 inline void slotOn();
67 inline void slotOn2();
68 inline void slotOff();
69 inline void setPatch(const Patch& patch);
70 inline void setVolume(unsigned value);
71
72 [[nodiscard]] inline unsigned calc_phase(unsigned lfo_pm);
73 template<bool HAS_AM, bool FIXED_ENV>
74 [[nodiscard]] inline unsigned calc_envelope(int lfo_am, unsigned fixed_env);
75 template<bool HAS_AM> [[nodiscard]] unsigned calc_fixed_env() const;
76 void calc_envelope_outline(unsigned& out);
77 template<bool HAS_AM, bool FIXED_ENV>
78 [[nodiscard]] inline int calc_slot_car(unsigned lfo_pm, int lfo_am, int fm, unsigned fixed_env);
79 template<bool HAS_AM, bool HAS_FB, bool FIXED_ENV>
80 [[nodiscard]] inline int calc_slot_mod(unsigned lfo_pm, int lfo_am, unsigned fixed_env);
81
82 [[nodiscard]] inline int calc_slot_tom();
83 [[nodiscard]] inline int calc_slot_snare(bool noise);
84 [[nodiscard]] inline int calc_slot_cym(unsigned phase7, unsigned phase8);
85 [[nodiscard]] inline int calc_slot_hat(unsigned phase7, unsigned phase8, bool noise);
86 inline void updatePG(unsigned freq);
87 inline void updateTLL(unsigned freq, bool actAsCarrier);
88 inline void updateRKS(unsigned freq);
89 inline void updateEG();
90 inline void updateAll(unsigned freq, bool actAsCarrier);
91
92 template<typename Archive>
93 void serialize(Archive& ar, unsigned version);
94
95 // OUTPUT
97 int output; // Output value of slot
98
99 // for Phase Generator (PG)
100 unsigned cPhase; // Phase counter
101 unsigned dPhase[8]; // Phase increment
102
103 // for Envelope Generator (EG)
104 unsigned volume; // Current volume
105 unsigned tll; // Total Level + Key scale level
106 const int* dPhaseDRTableRks; // (converted to EnvPhaseIndex)
107 EnvelopeState state; // Current state
109 EnvPhaseIndex eg_dPhase; // Phase increment amount
112 bool sustain; // Sustain
113
115 Slot* sibling; // pointer to sibling slot (only valid for car -> mod)
116};
117
118class Channel {
119public:
120 Channel();
121 void reset(YM2413& ym2413);
122 inline void setPatch(unsigned num, YM2413& ym2413);
123 inline void setSustain(bool sustain, bool modActAsCarrier);
124 inline void keyOn();
125 inline void keyOff();
126
128
129 template<typename Archive>
130 void serialize(Archive& ar, unsigned version);
131};
132
133class YM2413 final : public YM2413Core
134{
135public:
136 YM2413();
137
138 // YM2413Core
139 void reset() override;
140 void writePort(bool port, uint8_t value, int offset) override;
141 void pokeReg(uint8_t reg, uint8_t data) override;
142 [[nodiscard]] uint8_t peekReg(uint8_t reg) const override;
143 void generateChannels(float* bufs[9 + 5], unsigned num) override;
144 [[nodiscard]] float getAmplificationFactor() const override;
145
146 [[nodiscard]] Patch& getPatch(unsigned instrument, bool carrier);
147
148 template<typename Archive>
149 void serialize(Archive& ar, unsigned version);
150
151private:
152 void writeReg(uint8_t r, uint8_t data);
153
154 inline void keyOn_BD();
155 inline void keyOn_SD();
156 inline void keyOn_TOM();
157 inline void keyOn_HH();
158 inline void keyOn_CYM();
159 inline void keyOff_BD();
160 inline void keyOff_SD();
161 inline void keyOff_TOM();
162 inline void keyOff_HH();
163 inline void keyOff_CYM();
164 inline void setRhythmFlags(uint8_t old);
165 inline void update_key_status();
166 [[nodiscard]] inline bool isRhythm() const;
167 [[nodiscard]] inline unsigned getFreq(unsigned channel) const;
168
169 template<unsigned FLAGS>
170 inline void calcChannel(Channel& ch, float* buf, unsigned num);
171
172private:
174 Channel channels[9];
175
177 unsigned pm_phase;
178
180 unsigned am_phase;
181
183 unsigned noise_seed;
184
186 Patch patches[19][2];
187
189 uint8_t reg[0x40];
190 uint8_t registerLatch;
191};
192
193} // namespace YM2413Okazaki
194
198
199} // namespace openmsx
200
201#endif
Abstract interface for the YM2413 core.
Definition: YM2413Core.hh:27
void serialize(Archive &ar, unsigned version)
void setSustain(bool sustain, bool modActAsCarrier)
void setPatch(unsigned num, YM2413 &ym2413)
void setSL(uint8_t value)
Sets sustain level [0..15].
void setFB(uint8_t value)
Sets the amount of feedback [0..7].
Patch()
Creates an uninitialized Patch object; call initXXX() before use.
void initCarrier(const uint8_t *data)
void setTL(uint8_t value)
Set volume (total level) [0..63].
void initModulator(const uint8_t *data)
void setKL(uint8_t value)
Sets Key scale level [0..3].
void setML(uint8_t value)
Sets the frequency multiplier factor [0..15].
void setWF(uint8_t value)
Set waveform [0..1].
void setKR(uint8_t value)
Sets the Key Scale of Rate (0 or 1).
void serialize(Archive &ar, unsigned version)
void setVolume(unsigned value)
int calc_slot_mod(unsigned lfo_pm, int lfo_am, unsigned fixed_env)
void setPatch(const Patch &patch)
void updateTLL(unsigned freq, bool actAsCarrier)
void calc_envelope_outline(unsigned &out)
void updatePG(unsigned freq)
void updateRKS(unsigned freq)
void setEnvelopeState(EnvelopeState state)
unsigned calc_envelope(int lfo_am, unsigned fixed_env)
unsigned calc_phase(unsigned lfo_pm)
unsigned calc_fixed_env() const
int calc_slot_hat(unsigned phase7, unsigned phase8, bool noise)
int calc_slot_cym(unsigned phase7, unsigned phase8)
int calc_slot_car(unsigned lfo_pm, int lfo_am, int fm, unsigned fixed_env)
void updateAll(unsigned freq, bool actAsCarrier)
void generateChannels(float *bufs[9+5], unsigned num) override
uint8_t peekReg(uint8_t reg) const override
Read from a YM2413 register (for debug).
void serialize(Archive &ar, unsigned version)
void writePort(bool port, uint8_t value, int offset) override
Write to the YM2413 register/data port.
void pokeReg(uint8_t reg, uint8_t data) override
Write to a YM2413 register (for debug).
float getAmplificationFactor() const override
Returns normalization factor.
void reset() override
Reset this YM2413 core.
Patch & getPatch(unsigned instrument, bool carrier)
constexpr int EP_FP_BITS
This file implemented 3 utility functions:
Definition: Autofire.cc:9
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)