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 "memory.hh"
12 #include <cassert>
13 
14 namespace openmsx {
15 
17  MSXMotherBoard& motherBoard, string_ref name,
18  string_ref 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, int* buffer,
38  EmuTime::param time)
39 {
40  return algo->generateOutput(buffer, length, time);
41 }
42 
43 bool ResampledSoundDevice::generateInput(int* 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 = make_unique<ResampleTrivial>(*this);
64  } else {
65  switch (resampleSetting.getValue()) {
66  case RESAMPLE_HQ:
67  if (!isStereo()) {
68  algo = make_unique<ResampleHQ<1>>(
69  *this, hostClock, inputRate);
70  } else {
71  algo = 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 = make_unique<ResampleBlip<1>>(
87  *this, hostClock, inputRate);
88  } else {
89  algo = make_unique<ResampleBlip<2>>(
90  *this, hostClock, inputRate);
91  }
92  break;
93  default:
95  }
96  }
97 }
98 
99 } // namespace openmsx