openMSX
MSXMixer.hh
Go to the documentation of this file.
1#ifndef MSXMIXER_HH
2#define MSXMIXER_HH
3
4#include "DynamicClock.hh"
5#include "EmuTime.hh"
6#include "InfoTopic.hh"
7#include "Mixer.hh"
8#include "Observer.hh"
9#include "Schedulable.hh"
10#include "dynarray.hh"
11#include <memory>
12#include <span>
13#include <vector>
14
15namespace openmsx {
16
17class SoundDevice;
18class Mixer;
19class MSXMotherBoard;
20class MSXCommandController;
21class GlobalSettings;
22class SpeedManager;
23class ThrottleManager;
24class IntegerSetting;
25class StringSetting;
26class BooleanSetting;
27class Setting;
28class AviRecorder;
29
30class MSXMixer final : private Schedulable, private Observer<Setting>
31 , private Observer<SpeedManager>
32 , private Observer<ThrottleManager>
33{
34public:
35 // See SoundDevice::getAmplificationFactor()
36 // and MSXMixer::updateVolumeParams()
37 static constexpr int AMP_BITS = 9;
38
39public:
40 MSXMixer(const MSXMixer&) = delete;
41 MSXMixer& operator=(const MSXMixer&) = delete;
42
43 MSXMixer(Mixer& mixer, MSXMotherBoard& motherBoard,
44 GlobalSettings& globalSettings);
45 ~MSXMixer();
46
55 void registerSound(SoundDevice& device, float volume,
56 int balance, unsigned numChannels);
57
61 void unregisterSound(SoundDevice& device);
62
67 void updateStream(EmuTime::param time);
68
73
80 [[nodiscard]] double getEffectiveSpeed() const;
81
85 void setSynchronousMode(bool synchronous);
86 [[nodiscard]] bool isSynchronousMode() const { return synchronousCounter != 0; }
87
93 void mute();
94 void unmute();
95
96 // Called by Mixer or SoundDriver
97
101 void setMixerParams(unsigned fragmentSize, unsigned sampleRate);
102
112 [[nodiscard]] const DynamicClock& getHostSampleClock() const { return prevTime; }
113
114 // Called by AviRecorder
115 [[nodiscard]] bool needStereoRecording() const;
116 void setRecorder(AviRecorder* recorder);
117
118 // Returns the nominal host sample rate (not adjusted for speed setting)
119 [[nodiscard]] unsigned getSampleRate() const { return hostSampleRate; }
120
121 [[nodiscard]] SoundDevice* findDevice(std::string_view name) const;
122
123 void reInit();
124
125private:
126 struct SoundDeviceInfo {
127 SoundDeviceInfo(unsigned numChannels);
128
129 SoundDevice* device = nullptr;
130 std::unique_ptr<IntegerSetting> volumeSetting;
131 std::unique_ptr<IntegerSetting> balanceSetting;
133 std::unique_ptr<StringSetting> record;
134 std::unique_ptr<BooleanSetting> mute;
135 };
136 dynarray<ChannelSettings> channelSettings;
137 float defaultVolume = 0.f;
138 float left1 = 0.f, right1 = 0.f, left2 = 0.f, right2 = 0.f;
139 };
140
141 void updateVolumeParams(SoundDeviceInfo& info);
142 void updateMasterVolume();
143 void reschedule();
144 void reschedule2();
145 void generate(std::span<StereoFloat> output, EmuTime::param time);
146
147 // Schedulable
148 void executeUntil(EmuTime::param time) override;
149
150 // Observer<Setting>
151 void update(const Setting& setting) noexcept override;
152 // Observer<SpeedManager>
153 void update(const SpeedManager& speedManager) noexcept override;
154 // Observer<ThrottleManager>
155 void update(const ThrottleManager& throttleManager) noexcept override;
156
157 void changeRecordSetting(const Setting& setting);
158 void changeMuteSetting(const Setting& setting);
159
160private:
161 unsigned fragmentSize;
162 unsigned hostSampleRate; // requested freq by sound driver,
163 // not compensated for speed
164
165 std::vector<SoundDeviceInfo> infos;
166
167 Mixer& mixer;
168 MSXMotherBoard& motherBoard;
169 MSXCommandController& commandController;
170
171 IntegerSetting& masterVolume;
172 SpeedManager& speedManager;
173 ThrottleManager& throttleManager;
174
175 DynamicClock prevTime;
176
177 struct SoundDeviceInfoTopic final : InfoTopic {
178 explicit SoundDeviceInfoTopic(InfoCommand& machineInfoCommand);
179 void execute(std::span<const TclObject> tokens,
180 TclObject& result) const override;
181 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
182 void tabCompletion(std::vector<std::string>& tokens) const override;
183 } soundDeviceInfo;
184
185 AviRecorder* recorder = nullptr;
186 unsigned synchronousCounter = 0;
187
188 unsigned muteCount;
189 float tl0, tr0; // internal DC-filter state
190};
191
192} // namespace openmsx
193
194#endif
BaseSetting * setting
Definition: Interpreter.cc:28
Represents a clock with a variable frequency.
Definition: DynamicClock.hh:16
This class contains settings that are used by several other class (including some singletons).
A Setting with an integer value.
const DynamicClock & getHostSampleClock() const
Clock that ticks at the exact moment(s) in time that a host sample should be generated.
Definition: MSXMixer.hh:112
void mute()
TODO This methods (un)mute the sound.
Definition: MSXMixer.cc:609
void setRecorder(AviRecorder *recorder)
Definition: MSXMixer.cc:657
void registerSound(SoundDevice &device, float volume, int balance, unsigned numChannels)
Use this method to register a given SoundDevice.
Definition: MSXMixer.cc:83
void setSynchronousMode(bool synchronous)
If we're recording, we want to emulate sound at 100% EmuTime speed.
Definition: MSXMixer.cc:137
MSXMixer(const MSXMixer &)=delete
void updateSoftwareVolume(SoundDevice &device)
Used by SoundDevice::setSoftwareVolume()
Definition: MSXMixer.cc:785
MSXMixer & operator=(const MSXMixer &)=delete
unsigned getSampleRate() const
Definition: MSXMixer.hh:119
double getEffectiveSpeed() const
Returns the ratio of EmuTime-speed per realtime-speed.
Definition: MSXMixer.cc:154
SoundDevice * findDevice(std::string_view name) const
Definition: MSXMixer.cc:809
bool needStereoRecording() const
Definition: MSXMixer.cc:601
void updateStream(EmuTime::param time)
Use this method to force an 'early' call to all updateBuffer() methods.
Definition: MSXMixer.cc:159
static constexpr int AMP_BITS
Definition: MSXMixer.hh:37
bool isSynchronousMode() const
Definition: MSXMixer.hh:86
void setMixerParams(unsigned fragmentSize, unsigned sampleRate)
Set new fragment size and sample frequency.
Definition: MSXMixer.cc:643
void unregisterSound(SoundDevice &device)
Every SoundDevice must unregister before it is destructed.
Definition: MSXMixer.cc:124
Generic Gang-of-Four Observer class, templatized edition.
Definition: Observer.hh:10
Every class that wants to get scheduled at some point must inherit from this class.
Definition: Schedulable.hh:34
Manages the desired ratio between EmuTime and real time.
Definition: SpeedManager.hh:18
Manages the throttle state of openMSX.
This file implemented 3 utility functions:
Definition: Autofire.cc:9
std::unique_ptr< StringSetting > record
Definition: MSXMixer.hh:133
std::unique_ptr< BooleanSetting > mute
Definition: MSXMixer.hh:134