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
7namespace openmsx {
8
9constexpr unsigned DUMMY_INPUT_RATE = 44100; // actual rate depends on frequency setting
10
11DACSound16S::DACSound16S(std::string_view name_, static_string_view desc,
12 const DeviceConfig& config)
13 : SoundDevice(config.getMotherBoard().getMSXMixer(), name_, desc, 1, DUMMY_INPUT_RATE, false)
14 , lastWrittenValue(0)
15{
16 registerSound(config);
17}
18
20{
22}
23
24void DACSound16S::setOutputRate(unsigned hostSampleRate, double /*speed*/)
25{
26 setInputRate(hostSampleRate);
27}
28
29void DACSound16S::reset(EmuTime::param time)
30{
31 writeDAC(0, time);
32}
33
34void DACSound16S::writeDAC(int16_t value, EmuTime::param time)
35{
36 int delta = value - lastWrittenValue;
37 if (delta == 0) return;
38 lastWrittenValue = value;
39
42 blip.addDelta(t, delta);
43}
44
45void DACSound16S::generateChannels(float** bufs, unsigned num)
46{
47 // Note: readSamples() replaces the values in the buffer (it doesn't
48 // add the new values to the existing values in the buffer). That's OK
49 // because this is a single-channel SoundDevice.
50 if (!blip.readSamples<1>(bufs[0], num)) {
51 bufs[0] = nullptr;
52 }
53}
54
55bool DACSound16S::updateBuffer(unsigned length, float* buffer,
56 EmuTime::param /*time*/)
57{
58 return mixChannels(buffer, length);
59}
60
61template<typename Archive>
62void DACSound16S::serialize(Archive& ar, unsigned /*version*/)
63{
64 // Note: It's ok to NOT serialize a DAC object if you call the
65 // writeDAC() method in some other way during de-serialization.
66 // This is for example done in MSXPPI/KeyClick.
67 int16_t lastValue = lastWrittenValue;
68 ar.serialize("lastValue", lastValue);
69 if constexpr (Archive::IS_LOADER) {
70 writeDAC(lastValue, getHostSampleClock().getTime());
71 }
72}
74
75} // namespace openmsx
TclObject t
bool readSamples(float *out, unsigned samples)
Definition: BlipBuffer.cc:153
void addDelta(TimeIndex time, float delta)
Definition: BlipBuffer.cc:100
DACSound16S(std::string_view name, static_string_view desc, const DeviceConfig &config)
Definition: DACSound16S.cc:11
void reset(EmuTime::param time)
Definition: DACSound16S.cc:29
void serialize(Archive &ar, unsigned version)
Definition: DACSound16S.cc:62
virtual ~DACSound16S()
Definition: DACSound16S.cc:19
void writeDAC(int16_t value, EmuTime::param time)
Definition: DACSound16S.cc:34
unsigned getTicksTill(EmuTime::param e) const
Calculate the number of ticks for this clock until the given time.
Definition: DynamicClock.hh:51
A fixed point number, implemented by a 32-bit signed integer.
Definition: FixedPoint.hh:15
bool mixChannels(float *dataOut, unsigned samples)
Calls generateChannels() and combines the output to a single channel.
Definition: SoundDevice.cc:190
const DynamicClock & getHostSampleClock() const
See MSXMixer::getHostSampleClock().
Definition: SoundDevice.cc:341
void setInputRate(unsigned sampleRate)
Definition: SoundDevice.hh:118
void unregisterSound()
Unregisters this sound device with the Mixer.
Definition: SoundDevice.cc:133
void registerSound(const DeviceConfig &config)
Registers this sound device with the Mixer.
Definition: SoundDevice.cc:88
static_string_view
T length(const vecN< N, T > &x)
Definition: gl_vec.hh:339
This file implemented 3 utility functions:
Definition: Autofire.cc:9
constexpr unsigned DUMMY_INPUT_RATE
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1009