openMSX
MSXMixer.hh
Go to the documentation of this file.
1 #ifndef MSXMIXER_HH
2 #define MSXMIXER_HH
3 
4 #include "Schedulable.hh"
5 #include "Observer.hh"
6 #include "InfoTopic.hh"
7 #include "EmuTime.hh"
8 #include "DynamicClock.hh"
9 #include <cstdint>
10 #include <vector>
11 #include <memory>
12 
13 namespace openmsx {
14 
15 class SoundDevice;
16 class Mixer;
17 class MSXMotherBoard;
18 class MSXCommandController;
19 class GlobalSettings;
20 class ThrottleManager;
21 class IntegerSetting;
22 class StringSetting;
23 class BooleanSetting;
24 class Setting;
25 class AviRecorder;
26 
27 class MSXMixer final : private Schedulable, private Observer<Setting>
28  , private Observer<ThrottleManager>
29 {
30 public:
31  // See SoundDevice::getAmplificationFactor()
32  // and MSXMixer::updateVolumeParams()
33  static constexpr int AMP_BITS = 9;
34 
35 public:
36  MSXMixer(Mixer& mixer, MSXMotherBoard& motherBoard,
37  GlobalSettings& globalSettings);
38  ~MSXMixer();
39 
48  void registerSound(SoundDevice& device, float volume,
49  int balance, unsigned numChannels);
50 
54  void unregisterSound(SoundDevice& device);
55 
60  void updateStream(EmuTime::param time);
61 
65  void updateSoftwareVolume(SoundDevice& device);
66 
73  double getEffectiveSpeed() const;
74 
78  void setSynchronousMode(bool synchronous);
79 
85  void mute();
86  void unmute();
87 
88  // Called by Mixer or SoundDriver
89 
93  void setMixerParams(unsigned fragmentSize, unsigned sampleRate);
94 
104  const DynamicClock& getHostSampleClock() const { return prevTime; }
105 
106  // Called by AviRecorder
107  bool needStereoRecording() const;
108  void setRecorder(AviRecorder* recorder);
109 
110  // Returns the nominal host sample rate (not adjusted for speed setting)
111  unsigned getSampleRate() const { return hostSampleRate; }
112 
113  SoundDevice* findDevice(string_view name) const;
114 
115  void reInit();
116 
117 private:
118  struct SoundDeviceInfo {
119  SoundDevice* device;
120  float defaultVolume;
121  std::unique_ptr<IntegerSetting> volumeSetting;
122  std::unique_ptr<IntegerSetting> balanceSetting;
124  std::unique_ptr<StringSetting> recordSetting;
125  std::unique_ptr<BooleanSetting> muteSetting;
126  };
127  std::vector<ChannelSettings> channelSettings;
128  int left1, right1, left2, right2;
129  };
130 
131  void updateVolumeParams(SoundDeviceInfo& info);
132  void updateMasterVolume();
133  void reschedule();
134  void reschedule2();
135  void generate(int16_t* output, EmuTime::param time, unsigned samples);
136 
137  // Schedulable
138  void executeUntil(EmuTime::param time) override;
139 
140  // Observer<Setting>
141  void update(const Setting& setting) override;
142  // Observer<ThrottleManager>
143  void update(const ThrottleManager& throttleManager) override;
144 
145  void changeRecordSetting(const Setting& setting);
146  void changeMuteSetting(const Setting& setting);
147 
148  unsigned fragmentSize;
149  unsigned hostSampleRate; // requested freq by sound driver,
150  // not compensated for speed
151 
152  std::vector<SoundDeviceInfo> infos;
153 
154  Mixer& mixer;
155  MSXMotherBoard& motherBoard;
156  MSXCommandController& commandController;
157 
158  IntegerSetting& masterVolume;
159  IntegerSetting& speedSetting;
160  ThrottleManager& throttleManager;
161 
162  DynamicClock prevTime;
163 
164  struct SoundDeviceInfoTopic final : InfoTopic {
165  explicit SoundDeviceInfoTopic(InfoCommand& machineInfoCommand);
166  void execute(span<const TclObject> tokens,
167  TclObject& result) const override;
168  std::string help(const std::vector<std::string>& tokens) const override;
169  void tabCompletion(std::vector<std::string>& tokens) const override;
170  } soundDeviceInfo;
171 
172  AviRecorder* recorder;
173  unsigned synchronousCounter;
174 
175  unsigned muteCount;
176  int32_t tl0, tr0; // internal DC-filter state
177 };
178 
179 } // namespace openmsx
180 
181 #endif
void mute()
TODO This methods (un)mute the sound.
Definition: MSXMixer.cc:550
void unregisterSound(SoundDevice &device)
Every sounddevice must unregister before it is destructed.
Definition: MSXMixer.cc:124
SoundDevice * findDevice(string_view name) const
Definition: MSXMixer.cc:748
void updateSoftwareVolume(SoundDevice &device)
Used by SoundDevice::setSoftwareVolume()
Definition: MSXMixer.cc:723
Definition: span.hh:34
void setSynchronousMode(bool synchronous)
If we&#39;re recording, we want to emulate sound at 100% emutime speed.
Definition: MSXMixer.cc:138
void updateStream(EmuTime::param time)
Use this method to force an &#39;early&#39; call to all updateBuffer() methods.
Definition: MSXMixer.cc:162
void setMixerParams(unsigned fragmentSize, unsigned sampleRate)
Set new fragment size and sample frequency.
Definition: MSXMixer.cc:584
std::unique_ptr< StringSetting > recordSetting
Definition: MSXMixer.hh:124
std::unique_ptr< BooleanSetting > muteSetting
Definition: MSXMixer.hh:125
Every class that wants to get scheduled at some point must inherit from this class.
Definition: Schedulable.hh:33
void registerSound(SoundDevice &device, float volume, int balance, unsigned numChannels)
Use this method to register a given sounddevice.
Definition: MSXMixer.cc:80
A Setting with an integer value.
Represents a clock with a variable frequency.
Definition: DynamicClock.hh:15
MSXMixer(Mixer &mixer, MSXMotherBoard &motherBoard, GlobalSettings &globalSettings)
Definition: MSXMixer.cc:39
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
void setRecorder(AviRecorder *recorder)
Definition: MSXMixer.cc:598
This class implements a (close approximation) of the std::string_view class.
Definition: string_view.hh:16
static constexpr int AMP_BITS
Definition: MSXMixer.hh:33
bool needStereoRecording() const
Definition: MSXMixer.cc:542
unsigned getSampleRate() const
Definition: MSXMixer.hh:111
Manages the throttle state of openMSX.
double getEffectiveSpeed() const
Returns the ratio of emutime-speed per realtime-speed.
Definition: MSXMixer.cc:155
Generic Gang-of-Four Observer class, templatized edition.
Definition: Observer.hh:9
This class contains settings that are used by several other class (including some singletons)...
const DynamicClock & getHostSampleClock() const
Clock that ticks at the exact moment(s) in time that a host sample should be generated.
Definition: MSXMixer.hh:104