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 
86  void mute();
87  void unmute();
88 
89  // Called by Mixer or SoundDriver
90 
94  void setMixerParams(unsigned fragmentSize, unsigned sampleRate);
95 
105  const DynamicClock& getHostSampleClock() const { return prevTime; }
106 
107  // Called by AviRecorder
108  bool needStereoRecording() const;
109  void setRecorder(AviRecorder* recorder);
110 
111  // Returns the nominal host sample rate (not adjusted for speed setting)
112  unsigned getSampleRate() const { return hostSampleRate; }
113 
114  SoundDevice* findDevice(std::string_view name) const;
115 
116  void reInit();
117 
118 private:
119  struct SoundDeviceInfo {
120  SoundDevice* device;
121  float defaultVolume;
122  std::unique_ptr<IntegerSetting> volumeSetting;
123  std::unique_ptr<IntegerSetting> balanceSetting;
125  std::unique_ptr<StringSetting> recordSetting;
126  std::unique_ptr<BooleanSetting> muteSetting;
127  };
128  std::vector<ChannelSettings> channelSettings;
129  float left1, right1, left2, right2;
130  };
131 
132  void updateVolumeParams(SoundDeviceInfo& info);
133  void updateMasterVolume();
134  void reschedule();
135  void reschedule2();
136  void generate(float* output, EmuTime::param time, unsigned samples);
137 
138  // Schedulable
139  void executeUntil(EmuTime::param time) override;
140 
141  // Observer<Setting>
142  void update(const Setting& setting) override;
143  // Observer<SpeedManager>
144  void update(const SpeedManager& speedManager) override;
145  // Observer<ThrottleManager>
146  void update(const ThrottleManager& throttleManager) override;
147 
148  void changeRecordSetting(const Setting& setting);
149  void changeMuteSetting(const Setting& setting);
150 
151  unsigned fragmentSize;
152  unsigned hostSampleRate; // requested freq by sound driver,
153  // not compensated for speed
154 
155  std::vector<SoundDeviceInfo> infos;
156 
157  Mixer& mixer;
158  MSXMotherBoard& motherBoard;
159  MSXCommandController& commandController;
160 
161  IntegerSetting& masterVolume;
162  SpeedManager& speedManager;
163  ThrottleManager& throttleManager;
164 
165  DynamicClock prevTime;
166 
167  struct SoundDeviceInfoTopic final : InfoTopic {
168  explicit SoundDeviceInfoTopic(InfoCommand& machineInfoCommand);
169  void execute(span<const TclObject> tokens,
170  TclObject& result) const override;
171  std::string help(const std::vector<std::string>& tokens) const override;
172  void tabCompletion(std::vector<std::string>& tokens) const override;
173  } soundDeviceInfo;
174 
175  AviRecorder* recorder;
176  unsigned synchronousCounter;
177 
178  unsigned muteCount;
179  float tl0, tr0; // internal DC-filter state
180 };
181 
182 } // namespace openmsx
183 
184 #endif
openmsx::MSXMixer
Definition: MSXMixer.hh:27
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:126
openmsx::InfoTopic
Definition: InfoTopic.hh:15
openmsx::MSXMixer::setRecorder
void setRecorder(AviRecorder *recorder)
Definition: MSXMixer.cc:594
openmsx::AviRecorder
Definition: AviRecorder.hh:23
openmsx::Schedulable
Every class that wants to get scheduled at some point must inherit from this class.
Definition: Schedulable.hh:33
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:119
openmsx::MSXMixer::updateSoftwareVolume
void updateSoftwareVolume(SoundDevice &device)
Used by SoundDevice::setSoftwareVolume()
Definition: MSXMixer.cc:718
span
Definition: span.hh:34
openmsx::DynamicClock
Represents a clock with a variable frequency.
Definition: DynamicClock.hh:16
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:11
openmsx::SoundDevice
Definition: SoundDevice.hh:16
openmsx::MSXMotherBoard
Definition: MSXMotherBoard.hh:59
openmsx::Mixer
Definition: Mixer.hh:18
openmsx::SpeedManager
Manages the desired ratio between emutime and real time.
Definition: SpeedManager.hh:16
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:125
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:24
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:105
openmsx::IntegerSetting
A Setting with an integer value.
Definition: IntegerSetting.hh:10
openmsx::MSXMixer::SoundDeviceInfo::ChannelSettings
Definition: MSXMixer.hh:124
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:112
openmsx::TclObject
Definition: TclObject.hh:21
openmsx::MSXCommandController
Definition: MSXCommandController.hh:20
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
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
openmsx::ThrottleManager
Manages the throttle state of openMSX.
Definition: ThrottleManager.hh:17
openmsx::Observer
Generic Gang-of-Four Observer class, templatized edition.
Definition: Observer.hh:9