openMSX
ResampledSoundDevice.cc
Go to the documentation of this file.
2
3#include "ResampleTrivial.hh"
4#include "ResampleHQ.hh"
5#include "ResampleBlip.hh"
6
7#include "EnumSetting.hh"
8#include "GlobalSettings.hh"
9#include "MSXMotherBoard.hh"
10#include "Reactor.hh"
11
12#include "unreachable.hh"
13
14#include <cassert>
15#include <memory>
16
17namespace openmsx {
18
20 MSXMotherBoard& motherBoard, std::string_view name_,
21 static_string_view description_, unsigned channels,
22 unsigned inputSampleRate_, bool stereo_)
23 : SoundDevice(motherBoard.getMSXMixer(), name_, description_,
24 channels, inputSampleRate_, stereo_)
25 , resampleSetting(motherBoard.getReactor().getGlobalSettings().getResampleSetting())
26{
27 resampleSetting.attach(*this);
28}
29
31{
32 resampleSetting.detach(*this);
33}
34
35void ResampledSoundDevice::setOutputRate(unsigned /*hostSampleRate*/, double /*speed*/)
36{
38}
39
40bool ResampledSoundDevice::updateBuffer(size_t length, float* buffer,
41 EmuTime::param time)
42{
43 return algo->generateOutput(buffer, length, time);
44}
45
46bool ResampledSoundDevice::generateInput(float* buffer, size_t num)
47{
48 return mixChannels(buffer, num);
49}
50
52{
53 (void)setting;
54 assert(&setting == &resampleSetting);
55 createResampler();
56}
57
59{
60 const DynamicClock& hostClock = getHostSampleClock();
61 EmuDuration outputPeriod = hostClock.getPeriod();
62 EmuDuration inputPeriod(getEffectiveSpeed() / double(getInputRate()));
63 emuClock.reset(hostClock.getTime());
64 emuClock.setPeriod(inputPeriod);
65
66 if (outputPeriod == inputPeriod) {
67 algo = std::make_unique<ResampleTrivial>(*this);
68 } else {
69 switch (resampleSetting.getEnum()) {
71 if (!isStereo()) {
72 algo = std::make_unique<ResampleHQ<1>>(*this, hostClock);
73 } else {
74 algo = std::make_unique<ResampleHQ<2>>(*this, hostClock);
75 }
76 break;
78 if (!isStereo()) {
79 algo = std::make_unique<ResampleBlip<1>>(*this, hostClock);
80 } else {
81 algo = std::make_unique<ResampleBlip<2>>(*this, hostClock);
82 }
83 break;
84 default:
86 }
87 }
88}
89
90} // 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
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 the full output of this device stereo?
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