openMSX
DACSound16S.cc
Go to the documentation of this file.
1 #include "DACSound16S.hh"
2 #include "DeviceConfig.hh"
3 #include "MSXMotherBoard.hh"
4 #include "DynamicClock.hh"
5 #include "serialize.hh"
6 
7 namespace openmsx {
8 
10  const DeviceConfig& config)
11  : SoundDevice(config.getMotherBoard().getMSXMixer(), name, desc, 1)
12  , lastWrittenValue(0)
13 {
14  registerSound(config);
15 }
16 
18 {
20 }
21 
22 void DACSound16S::setOutputRate(unsigned sampleRate)
23 {
24  setInputRate(sampleRate);
25 }
26 
28 {
29  writeDAC(0, time);
30 }
31 
32 void DACSound16S::writeDAC(short value, EmuTime::param time)
33 {
34  int delta = value - lastWrittenValue;
35  if (delta == 0) return;
36  lastWrittenValue = value;
37 
40  blip.addDelta(t, delta);
41 }
42 
43 void DACSound16S::generateChannels(int** bufs, unsigned num)
44 {
45  // Note: readSamples() replaces the values in the buffer. It should add
46  // to the existing values in the buffer. But because there is only
47  // one channel this doesn't matter (buffer contains all zeros).
48  if (!blip.readSamples<1>(bufs[0], num)) {
49  bufs[0] = nullptr;
50  }
51 }
52 
53 bool DACSound16S::updateBuffer(unsigned length, int* buffer,
54  EmuTime::param /*time*/)
55 {
56  return mixChannels(buffer, length);
57 }
58 
59 
60 template<typename Archive>
61 void DACSound16S::serialize(Archive& ar, unsigned /*version*/)
62 {
63  // Note: It's ok to NOT serialize a DAC object if you call the
64  // writeDAC() method in some other way during de-serialization.
65  // This is for example done in MSXPPI/KeyClick.
66  short lastValue = lastWrittenValue;
67  ar.serialize("lastValue", lastValue);
68  if (ar.isLoader()) {
69  writeDAC(lastValue, getHostSampleClock().getTime());
70  }
71 }
73 
74 } // namespace openmsx