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 
10 namespace openmsx {
11 
12 class AY8910Periphery;
13 class DeviceConfig;
14 
19 class AY8910 final : public ResampledSoundDevice
20 {
21 public:
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 
34 private:
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) override;
168 
169  void wrtReg(unsigned reg, byte value, EmuTime::param time);
170 
171 private:
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 
196 SERIALIZE_CLASS_VERSION(AY8910::Generator, 2);
197 SERIALIZE_CLASS_VERSION(AY8910::ToneGenerator, 2);
198 SERIALIZE_CLASS_VERSION(AY8910::NoiseGenerator, 2);
199 
200 } // namespace openmsx
201 
202 #endif // AY8910_HH
openmsx::AY8910::peekRegister
byte peekRegister(unsigned reg, EmuTime::param time) const
Definition: AY8910.cc:565
openmsx::AY8910::~AY8910
~AY8910()
Definition: AY8910.cc:519
openmsx.hh
openmsx::ResampledSoundDevice
Definition: ResampledSoundDevice.hh:17
openmsx::FloatSetting
A Setting with a floating point value.
Definition: FloatSetting.hh:11
openmsx::DeviceConfig
Definition: DeviceConfig.hh:20
openmsx::AY8910::readRegister
byte readRegister(unsigned reg, EmuTime::param time)
Definition: AY8910.cc:540
LZ4::count
ALWAYS_INLINE unsigned count(const uint8_t *pIn, const uint8_t *pMatch, const uint8_t *pInLimit)
Definition: lz4.cc:207
openmsx::SimpleDebuggable
Definition: SimpleDebuggable.hh:13
openmsx::AY8910Periphery
Models the general purpose I/O ports of the AY8910.
Definition: AY8910Periphery.hh:15
openmsx::Setting
Definition: Setting.hh:127
step
constexpr auto step
Definition: eeprom.cc:9
openmsx::AY8910::writeRegister
void writeRegister(unsigned reg, byte value, EmuTime::param time)
Definition: AY8910.cc:584
openmsx::SERIALIZE_CLASS_VERSION
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
openmsx::MSXMotherBoard
Definition: MSXMotherBoard.hh:61
openmsx::AY8910::serialize
void serialize(Archive &ar, unsigned version)
Definition: AY8910.cc:1008
SimpleDebuggable.hh
openmsx::AY8910
This class implements the AY-3-8910 sound chip.
Definition: AY8910.hh:20
TclCallback.hh
utf8::advance
void advance(octet_iterator &it, distance_type n, octet_iterator end)
Definition: utf8_checked.hh:187
openmsx::AY8910::AY8910
AY8910(const std::string &name, AY8910Periphery &periphery, const DeviceConfig &config, EmuTime::param time)
Definition: AY8910.cc:480
openmsx
This file implemented 3 utility functions:
Definition: Autofire.cc:5
FloatSetting.hh
openmsx::AY8910::reset
void reset(EmuTime::param time)
Definition: AY8910.cc:527
ResampledSoundDevice.hh
openmsx::TclCallback
Definition: TclCallback.hh:15