mirror of
https://github.com/TomHarte/CLK.git
synced 2026-04-24 05:18:36 +00:00
Block and synchronise threads for voice 3 readback.
This commit is contained in:
+16
-3
@@ -133,8 +133,18 @@ void SID::update_filter() {
|
||||
}
|
||||
|
||||
uint8_t SID::read(const Numeric::SizedInt<5> address) {
|
||||
(void)address;
|
||||
return last_write_;
|
||||
switch(address.get()) {
|
||||
default: return last_write_;
|
||||
|
||||
case 0x19: return 0x00; // TODO: potentometer x.
|
||||
case 0x1a: return 0x00; // TODO: potentometer y.
|
||||
|
||||
case 0x1b:
|
||||
case 0x1c:
|
||||
// Ensure all channels are entirely up to date.
|
||||
audio_queue_.flush();
|
||||
return (address == 0x1c) ? voices_[2].adsr.envelope : uint8_t(voices_[2].output(voices_[1]) >> 4);
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Oscillators.
|
||||
@@ -160,7 +170,7 @@ uint16_t Voice::Oscillator::sawtooth_output() const {
|
||||
|
||||
uint16_t Voice::NoiseGenerator::output() const {
|
||||
// Uses bits: 20, 18, 14, 11, 9, 5, 2 and 0, plus four more zero bits.
|
||||
return
|
||||
const uint16_t output =
|
||||
((noise >> 9) & 0b1000'0000'0000) | // b20 -> b11
|
||||
((noise >> 8) & 0b0100'0000'0000) | // b18 -> b10
|
||||
((noise >> 5) & 0b0010'0000'0000) | // b14 -> b9
|
||||
@@ -169,6 +179,9 @@ uint16_t Voice::NoiseGenerator::output() const {
|
||||
((noise << 1) & 0b0000'0100'0000) | // b5 -> b6
|
||||
((noise << 3) & 0b0000'0010'0000) | // b2 -> b5
|
||||
((noise << 4) & 0b0000'0001'0000); // b0 -> b4
|
||||
|
||||
assert(output <= Voice::MaxWaveformValue);
|
||||
return output;
|
||||
}
|
||||
|
||||
void Voice::NoiseGenerator::update(const bool test) {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
namespace MOS::SID {
|
||||
|
||||
struct Voice {
|
||||
static constexpr uint16_t MaxWaveformValue = (1 << 12) - 1;
|
||||
|
||||
struct Oscillator {
|
||||
// Programmer inputs.
|
||||
uint32_t pitch = 0;
|
||||
@@ -84,8 +86,6 @@ private:
|
||||
bool sync() const;
|
||||
bool gate() const;
|
||||
|
||||
static constexpr uint16_t MaxWaveformValue = (1 << 12) - 1;
|
||||
|
||||
uint16_t pulse_output() const;
|
||||
uint16_t triangle_output(const Voice &prior) const;
|
||||
};
|
||||
@@ -99,17 +99,12 @@ public:
|
||||
|
||||
// Outputs::Speaker::BufferSource.
|
||||
template <Outputs::Speaker::Action action>
|
||||
void apply_samples(std::size_t number_of_samples, Outputs::Speaker::MonoSample *target);
|
||||
void apply_samples(std::size_t, Outputs::Speaker::MonoSample *);
|
||||
bool is_zero_level() const;
|
||||
void set_sample_volume_range(std::int16_t);
|
||||
|
||||
private:
|
||||
Concurrency::AsyncTaskQueue<false> &audio_queue_;
|
||||
|
||||
// TODO: an emulator thread copy of voices needs to be kept too, to do the digital stuff, as
|
||||
// the current output of voice 3 can be read. Probably best if the audio thread posts its most
|
||||
// recent copy atomically and the emulator thread just catches up from whatever it has? I don't
|
||||
// think that spinning on voice 3 is common.
|
||||
Voice voices_[3];
|
||||
|
||||
uint8_t last_write_;
|
||||
|
||||
Reference in New Issue
Block a user