OXYGENHUB
◆ main openmsx / src / sound / DACSound16S.cc
2.0 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#include "DACSound16S.hh"
2
3
#include "DeviceConfig.hh"
4
#include "DynamicClock.hh"
5
#include "MSXMotherBoard.hh"
6
#include "serialize.hh"
7
8
#include "narrow.hh"
9
10
namespace openmsx {
11
12
static constexpr unsigned DUMMY_INPUT_RATE = 44100; // actual rate depends on frequency setting
13
14
DACSound16S::DACSound16S(std::string_view name_, static_string_view desc,
15
                         const DeviceConfig& config)
16
	: SoundDevice(config.getMotherBoard().getMSXMixer(), name_, desc, 1, DUMMY_INPUT_RATE, false)
17
{
18
	registerSound(config);
19
}
20
21
DACSound16S::~DACSound16S()
22
{
23
	unregisterSound();
24
}
25
26
void DACSound16S::setOutputRate(unsigned hostSampleRate, double /*speed*/)
27
{
28
	setInputRate(hostSampleRate);
29
}
30
31
void DACSound16S::reset(EmuTime time)
32
{
33
	writeDAC(0, time);
34
}
35
36
void DACSound16S::writeDAC(int16_t value, EmuTime time)
37
{
38
	int delta = value - lastWrittenValue;
39
	if (delta == 0) return;
40
	lastWrittenValue = value;
41
42
	BlipBuffer::TimeIndex t;
43
	getHostSampleClock().getTicksTill(time, t);
44
	blip.addDelta(t, narrow<float>(delta));
45
}
46
47
void DACSound16S::generateChannels(std::span<float*> bufs, unsigned num)
48
{
49
	// Note: readSamples() replaces the values in the buffer (it doesn't
50
	// add the new values to the existing values in the buffer). That's OK
51
	// because this is a single-channel SoundDevice.
52
	assert(bufs.size() == 1);
53
	if (!blip.readSamples<1>(bufs[0], num)) {
54
		bufs[0] = nullptr;
55
	}
56
}
57
58
bool DACSound16S::updateBuffer(size_t length, float* buffer,
59
                               EmuTime /*time*/)
60
{
61
	return mixChannels(buffer, length);
62
}
63
64
template<typename Archive>
65
void DACSound16S::serialize(Archive& ar, unsigned /*version*/)
66
{
67
	// Note: It's ok to NOT serialize a DAC object if you call the
68
	//       writeDAC() method in some other way during de-serialization.
69
	//       This is for example done in MSXPPI/KeyClick.
70
	int16_t lastValue = lastWrittenValue;
71
	ar.serialize("lastValue", lastValue);
72
	if constexpr (Archive::IS_LOADER) {
73
		writeDAC(lastValue, getHostSampleClock().getTime());
74
	}
75
}
76
INSTANTIATE_SERIALIZE_METHODS(DACSound16S);
77
78
} // namespace openmsx