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 "Schedulable.hh"
9
10#include "Observer.hh"
11#include "dynarray.hh"
12
13#include <memory>
14#include <span>
15#include <vector>
16
17namespace openmsx {
18
19class SoundDevice;
20class Mixer;
21class MSXMotherBoard;
22class MSXCommandController;
23class GlobalSettings;
24class SpeedManager;
25class ThrottleManager;
26class IntegerSetting;
27class StringSetting;
28class BooleanSetting;
29class Setting;
30class AviRecorder;
31
32class MSXMixer final : private Schedulable, private Observer<Setting>
33 , private Observer<SpeedManager>
34 , private Observer<ThrottleManager>
35{
36public:
37 // See SoundDevice::getAmplificationFactor()
38 // and MSXMixer::updateVolumeParams()
39 static constexpr int AMP_BITS = 9;
40
42 explicit SoundDeviceInfo(unsigned numChannels);
43
44 SoundDevice* device = nullptr;
45 std::unique_ptr<IntegerSetting> volumeSetting;
46 std::unique_ptr<IntegerSetting> balanceSetting;
48 std::unique_ptr<StringSetting> record;
49 std::unique_ptr<BooleanSetting> mute;
50 };
52 float defaultVolume = 0.f;
53 float left1 = 0.f, right1 = 0.f, left2 = 0.f, right2 = 0.f;
54 };
55
56public:
57 MSXMixer(Mixer& mixer, MSXMotherBoard& motherBoard,
58 GlobalSettings& globalSettings);
59 MSXMixer(const MSXMixer&) = delete;
60 MSXMixer(MSXMixer&&) = delete;
61 MSXMixer& operator=(const MSXMixer&) = delete;
63 ~MSXMixer();
64
73 void registerSound(SoundDevice& device, float volume,
74 int balance, unsigned numChannels);
75
79 void unregisterSound(SoundDevice& device);
80
85 void updateStream(EmuTime::param time);
86
91
98 [[nodiscard]] double getEffectiveSpeed() const;
99
103 void setSynchronousMode(bool synchronous);
104 [[nodiscard]] bool isSynchronousMode() const { return synchronousCounter != 0; }
105
111 void mute();
112 void unmute();
113
114 // Called by Mixer or SoundDriver
115
119 void setMixerParams(unsigned fragmentSize, unsigned sampleRate);
120
130 [[nodiscard]] const DynamicClock& getHostSampleClock() const { return prevTime; }
131
132 // Called by AviRecorder
133 [[nodiscard]] bool needStereoRecording() const;
134 void setRecorder(AviRecorder* recorder);
135
136 // Returns the nominal host sample rate (not adjusted for speed setting)
137 [[nodiscard]] unsigned getSampleRate() const { return hostSampleRate; }
138
139 [[nodiscard]] SoundDevice* findDevice(std::string_view name) const;
140 [[nodiscard]] const SoundDeviceInfo* findDeviceInfo(std::string_view name) const;
141 [[nodiscard]] const auto& getDeviceInfos() const { return infos; }
142
143 void reInit();
144
145private:
146 void updateVolumeParams(SoundDeviceInfo& info) const;
147 void updateMasterVolume();
148 void reschedule();
149 void reschedule2();
150 void generate(std::span<StereoFloat> output, EmuTime::param time);
151
152 // Schedulable
153 void executeUntil(EmuTime::param time) override;
154
155 // Observer<Setting>
156 void update(const Setting& setting) noexcept override;
157 // Observer<SpeedManager>
158 void update(const SpeedManager& speedManager) noexcept override;
159 // Observer<ThrottleManager>
160 void update(const ThrottleManager& throttleManager) noexcept override;
161
162 void changeRecordSetting(const Setting& setting);
163 void changeMuteSetting(const Setting& setting);
164
165private:
166 unsigned fragmentSize = 0;
167 unsigned hostSampleRate = 44100; // requested freq by sound driver,
168 // not compensated for speed
169
170 std::vector<SoundDeviceInfo> infos;
171
172 Mixer& mixer;
173 MSXMotherBoard& motherBoard;
174 MSXCommandController& commandController;
175
176 IntegerSetting& masterVolume;
177 SpeedManager& speedManager;
178 ThrottleManager& throttleManager;
179
180 DynamicClock prevTime;
181
182 struct SoundDeviceInfoTopic final : InfoTopic {
183 explicit SoundDeviceInfoTopic(InfoCommand& machineInfoCommand);
184 void execute(std::span<const TclObject> tokens,
185 TclObject& result) const override;
186 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
187 void tabCompletion(std::vector<std::string>& tokens) const override;
188 } soundDeviceInfo;
189
190 AviRecorder* recorder = nullptr;
191 unsigned synchronousCounter = 0;
192
193 unsigned muteCount;
194 float tl0, tr0; // internal DC-filter state
195};
196
197} // namespace openmsx
198
199#endif
BaseSetting * setting
Represents a clock with a variable frequency.
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:130
void mute()
TODO This methods (un)mute the sound.
Definition MSXMixer.cc:608
const SoundDeviceInfo * findDeviceInfo(std::string_view name) const
Definition MSXMixer.cc:808
void setRecorder(AviRecorder *recorder)
Definition MSXMixer.cc:656
void registerSound(SoundDevice &device, float volume, int balance, unsigned numChannels)
Use this method to register a given SoundDevice.
Definition MSXMixer.cc:82
MSXMixer & operator=(MSXMixer &&)=delete
void setSynchronousMode(bool synchronous)
If we're recording, we want to emulate sound at 100% EmuTime speed.
Definition MSXMixer.cc:136
MSXMixer(const MSXMixer &)=delete
void updateSoftwareVolume(SoundDevice &device)
Used by SoundDevice::setSoftwareVolume()
Definition MSXMixer.cc:784
MSXMixer & operator=(const MSXMixer &)=delete
unsigned getSampleRate() const
Definition MSXMixer.hh:137
double getEffectiveSpeed() const
Returns the ratio of EmuTime-speed per realtime-speed.
Definition MSXMixer.cc:153
const auto & getDeviceInfos() const
Definition MSXMixer.hh:141
SoundDevice * findDevice(std::string_view name) const
Definition MSXMixer.cc:815
bool needStereoRecording() const
Definition MSXMixer.cc:600
void updateStream(EmuTime::param time)
Use this method to force an 'early' call to all updateBuffer() methods.
Definition MSXMixer.cc:158
static constexpr int AMP_BITS
Definition MSXMixer.hh:39
MSXMixer(MSXMixer &&)=delete
bool isSynchronousMode() const
Definition MSXMixer.hh:104
void setMixerParams(unsigned fragmentSize, unsigned sampleRate)
Set new fragment size and sample frequency.
Definition MSXMixer.cc:642
void unregisterSound(SoundDevice &device)
Every SoundDevice must unregister before it is destructed.
Definition MSXMixer.cc:123
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.
Manages the desired ratio between EmuTime and real time.
Manages the throttle state of openMSX.
This file implemented 3 utility functions:
Definition Autofire.cc:11
std::unique_ptr< StringSetting > record
Definition MSXMixer.hh:48
std::unique_ptr< BooleanSetting > mute
Definition MSXMixer.hh:49
dynarray< ChannelSettings > channelSettings
Definition MSXMixer.hh:51
std::unique_ptr< IntegerSetting > balanceSetting
Definition MSXMixer.hh:46
std::unique_ptr< IntegerSetting > volumeSetting
Definition MSXMixer.hh:45