1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-22 12:33:29 +00:00

Ensures consistent audio pipeline.

This commit is contained in:
Thomas Harte 2019-06-01 17:29:57 -04:00
parent 5c08bb810e
commit 983407896c
3 changed files with 17 additions and 8 deletions

View File

@ -24,7 +24,9 @@ void Audio::post_sample(uint8_t sample) {
const auto write_pointer = sample_queue_.write_pointer.load();
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;
if(next_write_pointer == read_pointer) {
return;
}
sample_queue_.buffer[write_pointer] = sample;
sample_queue_.write_pointer.store(next_write_pointer);
@ -64,13 +66,12 @@ void Audio::get_samples(std::size_t number_of_samples, int16_t *target) {
// that's something to return to.
// TODO: temporary implementation. Very inefficient. Replace.
while(number_of_samples--) {
*target = volume_multiplier_ * int16_t(sample_queue_.buffer[read_pointer] * volume_ * enabled_mask_);
++target;
for(std::size_t sample = 0; sample < number_of_samples; ++sample) {
target[sample] = volume_multiplier_ * int16_t(sample_queue_.buffer[read_pointer]);// * volume_ * enabled_mask_);
++subcycle_offset_;
if(subcycle_offset_ == sample_length) {
// printf("%d: %d\n", sample_queue_.buffer[read_pointer], volume_multiplier_ * sample_queue_.buffer[read_pointer] * volume_ * enabled_mask_);
// printf("%d: %d\n", sample_queue_.buffer[read_pointer], volume_multiplier_ * int16_t(sample_queue_.buffer[read_pointer]));
subcycle_offset_ = 0;
const unsigned int next_read_pointer = (read_pointer + 1) % sample_queue_.buffer.size();
if(next_read_pointer != write_pointer) {

View File

@ -61,7 +61,7 @@ class Audio: public ::Outputs::Speaker::SampleSource {
// A queue of fetched samples; read from by one thread,
// written to by another.
struct {
std::array<uint8_t, 2048> buffer;
std::array<uint8_t, 4096> buffer;
std::atomic<unsigned int> read_pointer, write_pointer;
} sample_queue_;
@ -71,8 +71,7 @@ class Audio: public ::Outputs::Speaker::SampleSource {
int enabled_mask_ = 0;
std::int16_t volume_multiplier_ = 0;
std::size_t subcycle_offset_;
std::size_t subcycle_offset_ = 0;
};
}

View File

@ -59,6 +59,10 @@ class ConcreteMachine:
audio_.speaker.set_input_rate(float(CLOCK_RATE));
}
~ConcreteMachine() {
audio_.queue.flush();
}
void set_scan_target(Outputs::Display::ScanTarget *scan_target) override {
video_.set_scan_target(scan_target);
}
@ -236,6 +240,7 @@ class ConcreteMachine:
// video_.run_for(time_since_video_update_.flush());
// As above: flush audio after video.
via_.flush();
audio_.queue.perform();
}
@ -344,6 +349,10 @@ class ConcreteMachine:
audio_.time_since_update += duration;
}
void flush() {
audio_.flush();
}
private:
ConcreteMachine &machine_;
RealTimeClock &clock_;