OXYGENHUB
◆ main openmsx / src / sound / ResampledSoundDevice.cc
2.2 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#include "ResampledSoundDevice.hh"
2
3
#include "ResampleBlip.hh"
4
#include "ResampleHQ.hh"
5
#include "ResampleTrivial.hh"
6
7
#include "EnumSetting.hh"
8
#include "GlobalSettings.hh"
9
#include "MSXMotherBoard.hh"
10
#include "Reactor.hh"
11
12
#include "unreachable.hh"
13
14
#include <cassert>
15
#include <memory>
16
17
namespace openmsx {
18
19
ResampledSoundDevice::ResampledSoundDevice(
20
		MSXMotherBoard& motherBoard, std::string_view name_,
21
		static_string_view description_, unsigned channels,
22
		unsigned inputSampleRate_, bool stereo_)
23
	: SoundDevice(motherBoard.getMSXMixer(), name_, description_,
24
	              channels, inputSampleRate_, stereo_)
25
	, resampleSetting(motherBoard.getReactor().getGlobalSettings().getResampleSetting())
26
{
27
	resampleSetting.attach(*this);
28
}
29
30
ResampledSoundDevice::~ResampledSoundDevice()
31
{
32
	resampleSetting.detach(*this);
33
}
34
35
void ResampledSoundDevice::setOutputRate(unsigned /*hostSampleRate*/, double /*speed*/)
36
{
37
	createResampler();
38
}
39
40
bool ResampledSoundDevice::updateBuffer(size_t length, float* buffer,
41
                                        EmuTime time)
42
{
43
	return algo->generateOutput(buffer, length, time);
44
}
45
46
bool ResampledSoundDevice::generateInput(float* buffer, size_t num)
47
{
48
	return mixChannels(buffer, num);
49
}
50
51
void ResampledSoundDevice::update(const Setting& setting) noexcept
52
{
53
	(void)setting;
54
	assert(&setting == &resampleSetting);
55
	createResampler();
56
}
57
58
void ResampledSoundDevice::createResampler()
59
{
60
	const DynamicClock& hostClock = getHostSampleClock();
61
	EmuDuration outputPeriod = hostClock.getPeriod();
62
	EmuDuration inputPeriod = EmuDuration::sec(getEffectiveSpeed() / double(getInputRate()));
63
	emuClock.reset(hostClock.getTime());
64
	emuClock.setPeriod(inputPeriod);
65
66
	if (outputPeriod == inputPeriod) {
67
		algo = std::make_unique<ResampleTrivial>(*this);
68
	} else {
69
		switch (resampleSetting.getEnum()) {
70
		case ResampleType::HQ:
71
			if (!isStereo()) {
72
				algo = std::make_unique<ResampleHQ<1>>(*this, hostClock);
73
			} else {
74
				algo = std::make_unique<ResampleHQ<2>>(*this, hostClock);
75
			}
76
			break;
77
		case ResampleType::BLIP:
78
			if (!isStereo()) {
79
				algo = std::make_unique<ResampleBlip<1>>(*this, hostClock);
80
			} else {
81
				algo = std::make_unique<ResampleBlip<2>>(*this, hostClock);
82
			}
83
			break;
84
		default:
85
			UNREACHABLE;
86
		}
87
	}
88
}
89
90
} // namespace openmsx