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
40 SoundDeviceInfo(unsigned numChannels);
41
42 SoundDevice* device = nullptr;
43 std::unique_ptr<IntegerSetting> volumeSetting;
44 std::unique_ptr<IntegerSetting> balanceSetting;
46 std::unique_ptr<StringSetting> record;
47 std::unique_ptr<BooleanSetting> mute;
48 };
50 float defaultVolume = 0.f;
51 float left1 = 0.f, right1 = 0.f, left2 = 0.f, right2 = 0.f;
52 };
53
54public:
55 MSXMixer(const MSXMixer&) = delete;
56 MSXMixer& operator=(const MSXMixer&) = delete;
57
58 MSXMixer(Mixer& mixer, MSXMotherBoard& motherBoard,
59 GlobalSettings& globalSettings);
60 ~MSXMixer();
61
70 void registerSound(SoundDevice& device, float volume,
71 int balance, unsigned numChannels);
72
76 void unregisterSound(SoundDevice& device);
77
82 void updateStream(EmuTime::param time);
83
88
95 [[nodiscard]] double getEffectiveSpeed() const;
96
100 void setSynchronousMode(bool synchronous);
101 [[nodiscard]] bool isSynchronousMode() const { return synchronousCounter != 0; }
102
108 void mute();
109 void unmute();
110
111 // Called by Mixer or SoundDriver
112
116 void setMixerParams(unsigned fragmentSize, unsigned sampleRate);
117
127 [[nodiscard]] const DynamicClock& getHostSampleClock() const { return prevTime; }
128
129 // Called by AviRecorder
130 [[nodiscard]] bool needStereoRecording() const;
131 void setRecorder(AviRecorder* recorder);
132
133 // Returns the nominal host sample rate (not adjusted for speed setting)
134 [[nodiscard]] unsigned getSampleRate() const { return hostSampleRate; }
135
136 [[nodiscard]] SoundDevice* findDevice(std::string_view name) const;
137 [[nodiscard]] const SoundDeviceInfo* findDeviceInfo(std::string_view name) const;
138 [[nodiscard]] const auto& getDeviceInfos() const { return infos; }
139
140 void reInit();
141
142private:
143 void updateVolumeParams(SoundDeviceInfo& info);
144 void updateMasterVolume();
145 void reschedule();
146 void reschedule2();
147 void generate(std::span<StereoFloat> output, EmuTime::param time);
148
149 // Schedulable
150 void executeUntil(EmuTime::param time) override;
151
152 // Observer<Setting>
153 void update(const Setting& setting) noexcept override;
154 // Observer<SpeedManager>
155 void update(const SpeedManager& speedManager) noexcept override;
156 // Observer<ThrottleManager>
157 void update(const ThrottleManager& throttleManager) noexcept override;
158
159 void changeRecordSetting(const Setting& setting);
160 void changeMuteSetting(const Setting& setting);
161
162private:
163 unsigned fragmentSize;
164 unsigned hostSampleRate; // requested freq by sound driver,
165 // not compensated for speed
166
167 std::vector<SoundDeviceInfo> infos;
168
169 Mixer& mixer;
170 MSXMotherBoard& motherBoard;
171 MSXCommandController& commandController;
172
173 IntegerSetting& masterVolume;
174 SpeedManager& speedManager;
175 ThrottleManager& throttleManager;
176
177 DynamicClock prevTime;
178
179 struct SoundDeviceInfoTopic final : InfoTopic {
180 explicit SoundDeviceInfoTopic(InfoCommand& machineInfoCommand);
181 void execute(std::span<const TclObject> tokens,
182 TclObject& result) const override;
183 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
184 void tabCompletion(std::vector<std::string>& tokens) const override;
185 } soundDeviceInfo;
186
187 AviRecorder* recorder = nullptr;
188 unsigned synchronousCounter = 0;
189
190 unsigned muteCount;
191 float tl0, tr0; // internal DC-filter state
192};
193
194} // namespace openmsx
195
196#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:127
void mute()
TODO This methods (un)mute the sound.
Definition MSXMixer.cc:609
const SoundDeviceInfo * findDeviceInfo(std::string_view name) const
Definition MSXMixer.cc:809
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:134
double getEffectiveSpeed() const
Returns the ratio of EmuTime-speed per realtime-speed.
Definition MSXMixer.cc:154
const auto & getDeviceInfos() const
Definition MSXMixer.hh:138
SoundDevice * findDevice(std::string_view name) const
Definition MSXMixer.cc:816
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:101
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.
Manages the desired ratio between EmuTime and real time.
Manages the throttle state of openMSX.
This file implemented 3 utility functions:
Definition Autofire.cc:9
std::unique_ptr< StringSetting > record
Definition MSXMixer.hh:46
std::unique_ptr< BooleanSetting > mute
Definition MSXMixer.hh:47
dynarray< ChannelSettings > channelSettings
Definition MSXMixer.hh:49
std::unique_ptr< IntegerSetting > balanceSetting
Definition MSXMixer.hh:44
std::unique_ptr< IntegerSetting > volumeSetting
Definition MSXMixer.hh:43