openMSX
ResampledSoundDevice.cc
Go to the documentation of this file.
2
3#include "ResampleTrivial.hh"
4#include "ResampleHQ.hh"
5#include "ResampleLQ.hh"
6#include "ResampleBlip.hh"
7
8#include "EnumSetting.hh"
9#include "GlobalSettings.hh"
10#include "MSXMotherBoard.hh"
11#include "Reactor.hh"
12
13#include "unreachable.hh"
14
15#include <cassert>
16#include <memory>
17
18namespace openmsx {
19
21 MSXMotherBoard& motherBoard, std::string_view name_,
22 static_string_view description_, unsigned channels,
23 unsigned inputSampleRate_, bool stereo_)
24 : SoundDevice(motherBoard.getMSXMixer(), name_, description_,
25 channels, inputSampleRate_, stereo_)
26 , resampleSetting(motherBoard.getReactor().getGlobalSettings().getResampleSetting())
27{
28 resampleSetting.attach(*this);
29}
30
32{
33 resampleSetting.detach(*this);
34}
35
36void ResampledSoundDevice::setOutputRate(unsigned /*hostSampleRate*/, double /*speed*/)
37{
39}
40
41bool ResampledSoundDevice::updateBuffer(size_t length, float* buffer,
42 EmuTime::param time)
43{
44 return algo->generateOutput(buffer, length, time);
45}
46
47bool ResampledSoundDevice::generateInput(float* buffer, size_t num)
48{
49 return mixChannels(buffer, num);
50}
51
53{
54 (void)setting;
55 assert(&setting == &resampleSetting);
56 createResampler();
57}
58
60{
61 const DynamicClock& hostClock = getHostSampleClock();
62 EmuDuration outputPeriod = hostClock.getPeriod();
63 EmuDuration inputPeriod(getEffectiveSpeed() / double(getInputRate()));
64 emuClock.reset(hostClock.getTime());
65 emuClock.setPeriod(inputPeriod);
66
67 if (outputPeriod == inputPeriod) {
68 algo = std::make_unique<ResampleTrivial>(*this);
69 } else {
70 switch (resampleSetting.getEnum()) {
72 if (!isStereo()) {
73 algo = std::make_unique<ResampleHQ<1>>(*this, hostClock);
74 } else {
75 algo = std::make_unique<ResampleHQ<2>>(*this, hostClock);
76 }
77 break;
79 if (!isStereo()) {
80 algo = ResampleLQ<1>::create(*this, hostClock);
81 } else {
82 algo = ResampleLQ<2>::create(*this, hostClock);
83 }
84 break;
86 if (!isStereo()) {
87 algo = std::make_unique<ResampleBlip<1>>(*this, hostClock);
88 } else {
89 algo = std::make_unique<ResampleBlip<2>>(*this, hostClock);
90 }
91 break;
92 default:
94 }
95 }
96}
97
98} // namespace openmsx
BaseSetting * setting
Represents a clock with a variable frequency.
EmuDuration getPeriod() const
Returns the length of one clock-cycle.
void setPeriod(EmuDuration period)
Set the duration of a clock tick.
void reset(EmuTime::param e)
Reset the clock to start ticking at the given time.
EmuTime::param getTime() const
Gets the time at which the last clock tick occurred.
T getEnum() const noexcept
static std::unique_ptr< ResampleLQ< CHANNELS > > create(ResampledSoundDevice &input, const DynamicClock &hostClock)
Definition ResampleLQ.cc:24
bool generateInput(float *buffer, size_t num)
Note: To enable various optimizations (like SSE), this method is allowed to generate up to 3 extra sa...
ResampledSoundDevice(MSXMotherBoard &motherBoard, std::string_view name, static_string_view description, unsigned channels, unsigned inputSampleRate, bool stereo)
void update(const Setting &setting) noexcept override
void setOutputRate(unsigned hostSampleRate, double speed) override
When a SoundDevice registers itself with the Mixer, the Mixer sets the required sampleRate through th...
bool updateBuffer(size_t length, float *buffer, EmuTime::param time) override
Generate sample data.
double getEffectiveSpeed() const
unsigned getInputRate() const
const DynamicClock & getHostSampleClock() const
See MSXMixer::getHostSampleClock().
bool mixChannels(float *dataOut, size_t samples)
Calls generateChannels() and combines the output to a single channel.
bool isStereo() const
Is this a stereo device? This is set in the constructor and cannot be changed anymore.
void detach(Observer< T > &observer)
Definition Subject.hh:60
void attach(Observer< T > &observer)
Definition Subject.hh:54
static_string_view
This file implemented 3 utility functions:
Definition Autofire.cc:11
#define UNREACHABLE