1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-03 11:30:02 +00:00

Pushes Mac audio further towards being able to function.

This commit is contained in:
Thomas Harte 2019-06-01 15:18:27 -04:00
parent 6d985866ee
commit 17635da812
3 changed files with 28 additions and 11 deletions

View File

@ -10,41 +10,55 @@
using namespace Apple::Macintosh;
namespace {
const HalfCycles sample_length(704);
}
Audio::Audio(Concurrency::DeferringAsyncTaskQueue &task_queue) : task_queue_(task_queue) {}
// MARK: - Inputs
void Audio::post_sample(uint8_t sample) {
// Grab the read and write pointers, ensure there's room for a new sample and, if not,
// drop this one.
const auto write_pointer = sample_queue_.write_pointer.load();
// const auto pointers
const auto read_pointer = sample_queue_.read_pointer.load();
const decltype(write_pointer) next_write_pointer = (write_pointer + 1) % sample_queue_.buffer.size();
if(next_write_pointer == read_pointer) return;
sample_queue_.buffer[write_pointer] = sample;
sample_queue_.write_pointer.store(next_write_pointer);
}
void Audio::set_volume(int volume) {
// Post the volume change as a deferred event.
task_queue_.defer([=] () {
volume_ = volume;
});
}
void Audio::set_enabled(bool on) {
// Post the enabled mask change as a deferred event.
task_queue_.defer([=] () {
is_enabled_ = on;
enabled_mask_ = on ? 1 : 0;
});
}
// MARK: - Output generation
bool Audio::is_zero_level() {
return !volume_ || !is_enabled_;
return !volume_ || !enabled_mask_;
}
void Audio::set_sample_volume_range(std::int16_t range) {
// Some underflow here doesn't really matter.
volume_multiplier_ = range / 7;
}
void Audio::get_samples(std::size_t number_of_samples, int16_t *target) {
// if(is_zero_level()) {
// memset(target, 0, number_of_samples * sizeof(int16_t));
// }
// TODO.
}
void Audio::skip_samples(std::size_t number_of_samples) {
// TODO.
}

View File

@ -9,9 +9,9 @@
#ifndef Audio_hpp
#define Audio_hpp
#include "../../../Outputs/Speaker/Implementation/SampleSource.hpp"
#include "../../../Concurrency/AsyncTaskQueue.hpp"
#include "../../../ClockReceiver/ClockReceiver.hpp"
#include "../../../Outputs/Speaker/Implementation/SampleSource.hpp"
#include <array>
#include <atomic>
@ -51,6 +51,7 @@ class Audio: public ::Outputs::Speaker::SampleSource {
// to satisfy ::Outputs::Speaker (included via ::Outputs::Filter.
void get_samples(std::size_t number_of_samples, int16_t *target);
void skip_samples(std::size_t number_of_samples);
bool is_zero_level();
void set_sample_volume_range(std::int16_t range);
@ -61,15 +62,17 @@ class Audio: public ::Outputs::Speaker::SampleSource {
// written to by another.
struct {
std::array<uint8_t, 2048> buffer;
std::atomic<int> read_pointer, write_pointer;
std::atomic<unsigned int> read_pointer, write_pointer;
} sample_queue_;
// Stateful variables, modified from the audio generation
// thread only.
int volume_ = 0;
bool is_enabled_ = false;
int enabled_mask_ = 0;
std::int16_t volume_multiplier_ = 0;
HalfCycles subcycle_offset_;
};
}

View File

@ -236,7 +236,7 @@ class ConcreteMachine:
// video_.run_for(time_since_video_update_.flush());
// As above: flush audio after video.
audio_.queue.flush();
audio_.queue.perform();
}
void set_rom_is_overlay(bool rom_is_overlay) {