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(const MSXMixer&) = delete;
58 MSXMixer& operator=(const MSXMixer&) = delete;
59
60 MSXMixer(Mixer& mixer, MSXMotherBoard& motherBoard,
61 GlobalSettings& globalSettings);
62 ~MSXMixer();
63
72 void registerSound(SoundDevice& device, float volume,
73 int balance, unsigned numChannels);
74
78 void unregisterSound(SoundDevice& device);
79
84 void updateStream(EmuTime::param time);
85
90
97 [[nodiscard]] double getEffectiveSpeed() const;
98
102 void setSynchronousMode(bool synchronous);
103 [[nodiscard]] bool isSynchronousMode() const { return synchronousCounter != 0; }
104
110 void mute();
111 void unmute();
112
113 // Called by Mixer or SoundDriver
114
118 void setMixerParams(unsigned fragmentSize, unsigned sampleRate);
119
129 [[nodiscard]] const DynamicClock& getHostSampleClock() const { return prevTime; }
130
131 // Called by AviRecorder
132 [[nodiscard]] bool needStereoRecording() const;
133 void setRecorder(AviRecorder* recorder);
134
135 // Returns the nominal host sample rate (not adjusted for speed setting)
136 [[nodiscard]] unsigned getSampleRate() const { return hostSampleRate; }
137
138 [[nodiscard]] SoundDevice* findDevice(std::string_view name) const;
139 [[nodiscard]] const SoundDeviceInfo* findDeviceInfo(std::string_view name) const;
140 [[nodiscard]] const auto& getDeviceInfos() const { return infos; }
141
142 void reInit();
143
144private:
145 void updateVolumeParams(SoundDeviceInfo& info) const;
146 void updateMasterVolume();
147 void reschedule();
148 void reschedule2();
149 void generate(std::span<StereoFloat> output, EmuTime::param time);
150
151 // Schedulable
152 void executeUntil(EmuTime::param time) override;
153
154 // Observer<Setting>
155 void update(const Setting& setting) noexcept override;
156 // Observer<SpeedManager>
157 void update(const SpeedManager& speedManager) noexcept override;
158 // Observer<ThrottleManager>
159 void update(const ThrottleManager& throttleManager) noexcept override;
160
161 void changeRecordSetting(const Setting& setting);
162 void changeMuteSetting(const Setting& setting);
163
164private:
165 unsigned fragmentSize;
166 unsigned hostSampleRate; // requested freq by sound driver,
167 // not compensated for speed
168
169 std::vector<SoundDeviceInfo> infos;
170
171 Mixer& mixer;
172 MSXMotherBoard& motherBoard;
173 MSXCommandController& commandController;
174
175 IntegerSetting& masterVolume;
176 SpeedManager& speedManager;
177 ThrottleManager& throttleManager;
178
179 DynamicClock prevTime;
180
181 struct SoundDeviceInfoTopic final : InfoTopic {
182 explicit SoundDeviceInfoTopic(InfoCommand& machineInfoCommand);
183 void execute(std::span<const TclObject> tokens,
184 TclObject& result) const override;
185 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
186 void tabCompletion(std::vector<std::string>& tokens) const override;
187 } soundDeviceInfo;
188
189 AviRecorder* recorder = nullptr;
190 unsigned synchronousCounter = 0;
191
192 unsigned muteCount;
193 float tl0, tr0; // internal DC-filter state
194};
195
196} // namespace openmsx
197
198#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:129
void mute()
TODO This methods (un)mute the sound.
Definition MSXMixer.cc:611
const SoundDeviceInfo * findDeviceInfo(std::string_view name) const
Definition MSXMixer.cc:811
void setRecorder(AviRecorder *recorder)
Definition MSXMixer.cc:659
void registerSound(SoundDevice &device, float volume, int balance, unsigned numChannels)
Use this method to register a given SoundDevice.
Definition MSXMixer.cc:85
void setSynchronousMode(bool synchronous)
If we're recording, we want to emulate sound at 100% EmuTime speed.
Definition MSXMixer.cc:139
MSXMixer(const MSXMixer &)=delete
void updateSoftwareVolume(SoundDevice &device)
Used by SoundDevice::setSoftwareVolume()
Definition MSXMixer.cc:787
MSXMixer & operator=(const MSXMixer &)=delete
unsigned getSampleRate() const
Definition MSXMixer.hh:136
double getEffectiveSpeed() const
Returns the ratio of EmuTime-speed per realtime-speed.
Definition MSXMixer.cc:156
const auto & getDeviceInfos() const
Definition MSXMixer.hh:140
SoundDevice * findDevice(std::string_view name) const
Definition MSXMixer.cc:818
bool needStereoRecording() const
Definition MSXMixer.cc:603
void updateStream(EmuTime::param time)
Use this method to force an 'early' call to all updateBuffer() methods.
Definition MSXMixer.cc:161
static constexpr int AMP_BITS
Definition MSXMixer.hh:39
bool isSynchronousMode() const
Definition MSXMixer.hh:103
void setMixerParams(unsigned fragmentSize, unsigned sampleRate)
Set new fragment size and sample frequency.
Definition MSXMixer.cc:645
void unregisterSound(SoundDevice &device)
Every SoundDevice must unregister before it is destructed.
Definition MSXMixer.cc:126
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