openMSX
ResampledSoundDevice.cc
Go to the documentation of this file.
2 #include "ResampleTrivial.hh"
3 #include "ResampleHQ.hh"
4 #include "ResampleLQ.hh"
5 #include "ResampleBlip.hh"
6 #include "MSXMotherBoard.hh"
7 #include "Reactor.hh"
8 #include "GlobalSettings.hh"
9 #include "EnumSetting.hh"
10 #include "unreachable.hh"
11 #include <cassert>
12 #include <memory>
13 
14 namespace openmsx {
15 
17  MSXMotherBoard& motherBoard, string_view name_,
18  string_view description_, unsigned channels,
19  bool stereo_)
20  : SoundDevice(motherBoard.getMSXMixer(), name_, description_, channels, stereo_)
21  , resampleSetting(motherBoard.getReactor().getGlobalSettings().getResampleSetting())
22 {
23  resampleSetting.attach(*this);
24 }
25 
27 {
28  resampleSetting.detach(*this);
29 }
30 
31 
32 void ResampledSoundDevice::setOutputRate(unsigned /*sampleRate*/)
33 {
35 }
36 
37 bool ResampledSoundDevice::updateBuffer(unsigned length, float* buffer,
38  EmuTime::param time)
39 {
40  return algo->generateOutput(buffer, length, time);
41 }
42 
43 bool ResampledSoundDevice::generateInput(float* buffer, unsigned num)
44 {
45  return mixChannels(buffer, num);
46 }
47 
48 
50 {
51  (void)setting;
52  assert(&setting == &resampleSetting);
54 }
55 
57 {
58  const DynamicClock& hostClock = getHostSampleClock();
59  unsigned outputRate = hostClock.getFreq();
60  unsigned inputRate = getInputRate() / getEffectiveSpeed();
61 
62  if (outputRate == inputRate) {
63  algo = std::make_unique<ResampleTrivial>(*this);
64  } else {
65  switch (resampleSetting.getEnum()) {
66  case RESAMPLE_HQ:
67  if (!isStereo()) {
68  algo = std::make_unique<ResampleHQ<1>>(
69  *this, hostClock, inputRate);
70  } else {
71  algo = std::make_unique<ResampleHQ<2>>(
72  *this, hostClock, inputRate);
73  }
74  break;
75  case RESAMPLE_LQ:
76  if (!isStereo()) {
77  algo = ResampleLQ<1>::create(
78  *this, hostClock, inputRate);
79  } else {
80  algo = ResampleLQ<2>::create(
81  *this, hostClock, inputRate);
82  }
83  break;
84  case RESAMPLE_BLIP:
85  if (!isStereo()) {
86  algo = std::make_unique<ResampleBlip<1>>(
87  *this, hostClock, inputRate);
88  } else {
89  algo = std::make_unique<ResampleBlip<2>>(
90  *this, hostClock, inputRate);
91  }
92  break;
93  default:
95  }
96  }
97 }
98 
99 } // namespace openmsx
bool updateBuffer(unsigned length, float *buffer, EmuTime::param time) override
Generate sample data.
T length(const vecN< N, T > &x)
Definition: gl_vec.hh:343
ResampledSoundDevice(MSXMotherBoard &motherBoard, string_view name, string_view description, unsigned channels, bool stereo=false)
bool isStereo() const
Is this a stereo device? This is set in the constructor and cannot be changed anymore.
Definition: SoundDevice.cc:79
void attach(Observer< T > &observer)
Definition: Subject.hh:45
Represents a clock with a variable frequency.
Definition: DynamicClock.hh:15
unsigned getFreq() const
Returns the frequency (in Hz) at which this clock ticks.
static std::unique_ptr< ResampleLQ< CHANNELS > > create(ResampledSoundDevice &input, const DynamicClock &hostClock, unsigned emuSampleRate)
Definition: ResampleLQ.cc:20
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
void setOutputRate(unsigned sampleRate) override
When a SoundDevice registers itself with the Mixer, the Mixer sets the required sampleRate through th...
bool mixChannels(float *dataOut, unsigned samples)
Calls generateChannels() and combines the output to a single channel.
Definition: SoundDevice.cc:187
This class implements a (close approximation) of the std::string_view class.
Definition: string_view.hh:16
void update(const Setting &setting) override
void detach(Observer< T > &observer)
Definition: Subject.hh:51
double getEffectiveSpeed() const
Definition: SoundDevice.cc:342
const DynamicClock & getHostSampleClock() const
See MSXMixer::getHostSampleClock().
Definition: SoundDevice.cc:338
bool generateInput(float *buffer, unsigned num)
Note: To enable various optimizations (like SSE), this method is allowed to generate up to 3 extra sa...
unsigned getInputRate() const
Definition: SoundDevice.hh:109
#define UNREACHABLE
Definition: unreachable.hh:38