openMSX
AY8910.hh
Go to the documentation of this file.
1#ifndef AY8910_HH
2#define AY8910_HH
3
5#include "FloatSetting.hh"
6#include "SimpleDebuggable.hh"
7#include "TclCallback.hh"
8#include "openmsx.hh"
9
10namespace openmsx {
11
12class AY8910Periphery;
13class DeviceConfig;
14
19class AY8910 final : public ResampledSoundDevice
20{
21public:
22 AY8910(const std::string& name, AY8910Periphery& periphery,
23 const DeviceConfig& config, EmuTime::param time);
24 ~AY8910();
25
26 [[nodiscard]] byte readRegister(unsigned reg, EmuTime::param time);
27 [[nodiscard]] byte peekRegister(unsigned reg, EmuTime::param time) const;
28 void writeRegister(unsigned reg, byte value, EmuTime::param time);
29 void reset(EmuTime::param time);
30
31 template<typename Archive>
32 void serialize(Archive& ar, unsigned version);
33
34private:
35 class Generator {
36 public:
37 inline void setPeriod(int value);
38 [[nodiscard]] inline unsigned getNextEventTime() const;
39 inline void advanceFast(unsigned duration);
40
41 template<typename Archive>
42 void serialize(Archive& ar, unsigned version);
43
44 protected:
45 Generator() = default;
46 inline void reset();
47
53 int period;
58 int count;
59 };
60
61 class ToneGenerator : public Generator {
62 public:
63 ToneGenerator();
64
65 inline void reset();
66
70 inline void advance(int duration);
71
72 inline void doNextEvent(AY8910& ay8910);
73
76 [[nodiscard]] bool getOutput() const { return output; }
77
78 template<typename Archive>
79 void serialize(Archive& ar, unsigned version);
80
81 private:
82 [[nodiscard]] int getDetune(AY8910& ay8910);
83
84 private:
87 unsigned vibratoCount = 0;
88 unsigned detuneCount = 0;
89
92 bool output;
93 };
94
95 class NoiseGenerator : public Generator {
96 public:
97 NoiseGenerator();
98
99 inline void reset();
103 inline void advance(int duration);
104
105 inline void doNextEvent();
106
109 [[nodiscard]] bool getOutput() const { return random & 1; }
110
111 template<typename Archive>
112 void serialize(Archive& ar, unsigned version);
113
114 private:
115 int random;
116 };
117
118 class Amplitude {
119 public:
120 explicit Amplitude(const DeviceConfig& config);
121 [[nodiscard]] const float* getEnvVolTable() const;
122 [[nodiscard]] inline float getVolume(unsigned chan) const;
123 inline void setChannelVolume(unsigned chan, unsigned value);
124 [[nodiscard]] inline bool followsEnvelope(unsigned chan) const;
125
126 private:
127 const float* envVolTable;
128 float vol[3];
129 bool envChan[3];
130 const bool isAY8910;
131 };
132
133 class Envelope {
134 public:
135 explicit inline Envelope(const float* envVolTable);
136 inline void reset();
137 inline void setPeriod(int value);
138 inline void setShape(unsigned shape);
139 [[nodiscard]] inline bool isChanging() const;
140 inline void advance(int duration);
141 [[nodiscard]] inline float getVolume() const;
142
143 [[nodiscard]] inline unsigned getNextEventTime() const;
144 inline void advanceFast(unsigned duration);
145 inline void doNextEvent();
146
147 template<typename Archive>
148 void serialize(Archive& ar, unsigned version);
149
150 private:
151 inline void doSteps(int steps);
152
153 private:
154 const float* envVolTable;
155 int period;
156 int count;
157 int step;
158 int attack;
159 bool hold, alternate, holding;
160 };
161
162 // SoundDevice
163 void generateChannels(float** bufs, unsigned num) override;
164 [[nodiscard]] float getAmplificationFactorImpl() const override;
165
166 // Observer<Setting>
167 void update(const Setting& setting) noexcept override;
168
169 void wrtReg(unsigned reg, byte value, EmuTime::param time);
170
171private:
172 AY8910Periphery& periphery;
173
174 struct Debuggable final : SimpleDebuggable {
175 Debuggable(MSXMotherBoard& motherBoard, const std::string& name);
176 [[nodiscard]] byte read(unsigned address, EmuTime::param time) override;
177 void write(unsigned address, byte value, EmuTime::param time) override;
178 } debuggable;
179
180 FloatSetting vibratoPercent;
181 FloatSetting vibratoFrequency;
182 FloatSetting detunePercent;
183 FloatSetting detuneFrequency;
184 TclCallback directionsCallback;
185 ToneGenerator tone[3];
186 NoiseGenerator noise;
187 Amplitude amplitude;
188 Envelope envelope;
189 byte regs[16];
190 const bool isAY8910;
191 const bool ignorePortDirections;
192 bool doDetune;
193 bool detuneInitialized;
194};
195
196SERIALIZE_CLASS_VERSION(AY8910::Generator, 2);
197SERIALIZE_CLASS_VERSION(AY8910::ToneGenerator, 2);
198SERIALIZE_CLASS_VERSION(AY8910::NoiseGenerator, 2);
199
200} // namespace openmsx
201
202#endif // AY8910_HH
BaseSetting * setting
Definition: Interpreter.cc:27
Models the general purpose I/O ports of the AY8910.
This class implements the AY-3-8910 sound chip.
Definition: AY8910.hh:20
AY8910(const std::string &name, AY8910Periphery &periphery, const DeviceConfig &config, EmuTime::param time)
Definition: AY8910.cc:478
void reset(EmuTime::param time)
Definition: AY8910.cc:524
byte readRegister(unsigned reg, EmuTime::param time)
Definition: AY8910.cc:537
byte peekRegister(unsigned reg, EmuTime::param time) const
Definition: AY8910.cc:562
void serialize(Archive &ar, unsigned version)
Definition: AY8910.cc:1005
void writeRegister(unsigned reg, byte value, EmuTime::param time)
Definition: AY8910.cc:581
A Setting with a floating point value.
Definition: FloatSetting.hh:11
constexpr auto step
Definition: eeprom.cc:9
ALWAYS_INLINE unsigned count(const uint8_t *pIn, const uint8_t *pMatch, const uint8_t *pInLimit)
Definition: lz4.cc:146
This file implemented 3 utility functions:
Definition: Autofire.cc:9
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
void advance(octet_iterator &it, distance_type n, octet_iterator end)