2016-12-03 17:41:02 +00:00
|
|
|
//
|
|
|
|
// Speaker.cpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 03/12/2016.
|
2018-05-13 19:19:52 +00:00
|
|
|
// Copyright 2016 Thomas Harte. All rights reserved.
|
2016-12-03 17:41:02 +00:00
|
|
|
//
|
|
|
|
|
2017-12-18 02:26:06 +00:00
|
|
|
#include "SoundGenerator.hpp"
|
2016-12-03 17:41:02 +00:00
|
|
|
|
2017-12-19 02:47:30 +00:00
|
|
|
#include <cstring>
|
|
|
|
|
2016-12-03 17:41:02 +00:00
|
|
|
using namespace Electron;
|
|
|
|
|
2022-07-16 18:41:04 +00:00
|
|
|
SoundGenerator::SoundGenerator(Concurrency::AsyncTaskQueue<false> &audio_queue) :
|
2017-12-18 02:26:06 +00:00
|
|
|
audio_queue_(audio_queue) {}
|
|
|
|
|
2018-03-09 18:23:18 +00:00
|
|
|
void SoundGenerator::set_sample_volume_range(std::int16_t range) {
|
2020-05-10 03:00:39 +00:00
|
|
|
volume_ = unsigned(range / 2);
|
2018-03-09 18:23:18 +00:00
|
|
|
}
|
|
|
|
|
2024-02-12 15:55:52 +00:00
|
|
|
template <Outputs::Speaker::Action action>
|
|
|
|
void SoundGenerator::apply_samples(std::size_t number_of_samples, Outputs::Speaker::MonoSample *target) {
|
|
|
|
if constexpr (action == Outputs::Speaker::Action::Ignore) {
|
|
|
|
counter_ = (counter_ + number_of_samples) % ((divider_+1) * 2);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-03-26 18:34:47 +00:00
|
|
|
if(is_enabled_) {
|
|
|
|
while(number_of_samples--) {
|
2024-02-12 15:55:52 +00:00
|
|
|
Outputs::Speaker::apply<action>(*target, Outputs::Speaker::MonoSample((counter_ / (divider_+1)) * volume_));
|
2016-12-03 17:41:02 +00:00
|
|
|
target++;
|
|
|
|
counter_ = (counter_ + 1) % ((divider_+1) * 2);
|
|
|
|
}
|
2017-03-26 18:34:47 +00:00
|
|
|
} else {
|
2024-02-12 15:55:52 +00:00
|
|
|
Outputs::Speaker::fill<action>(target, target + number_of_samples, Outputs::Speaker::MonoSample(0));
|
2016-12-03 17:41:02 +00:00
|
|
|
}
|
|
|
|
}
|
2024-02-12 15:55:52 +00:00
|
|
|
template void SoundGenerator::apply_samples<Outputs::Speaker::Action::Mix>(std::size_t, Outputs::Speaker::MonoSample *);
|
|
|
|
template void SoundGenerator::apply_samples<Outputs::Speaker::Action::Store>(std::size_t, Outputs::Speaker::MonoSample *);
|
|
|
|
template void SoundGenerator::apply_samples<Outputs::Speaker::Action::Ignore>(std::size_t, Outputs::Speaker::MonoSample *);
|
2016-12-03 17:41:02 +00:00
|
|
|
|
2017-12-18 02:26:06 +00:00
|
|
|
void SoundGenerator::set_divider(uint8_t divider) {
|
2022-07-14 20:39:26 +00:00
|
|
|
audio_queue_.enqueue([this, divider]() {
|
2016-12-03 17:41:02 +00:00
|
|
|
divider_ = divider * 32 / clock_rate_divider;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-12-18 02:26:06 +00:00
|
|
|
void SoundGenerator::set_is_enabled(bool is_enabled) {
|
2022-07-14 20:39:26 +00:00
|
|
|
audio_queue_.enqueue([this, is_enabled]() {
|
2016-12-03 17:41:02 +00:00
|
|
|
is_enabled_ = is_enabled;
|
|
|
|
counter_ = 0;
|
|
|
|
});
|
|
|
|
}
|