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