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:
parent
5c08bb810e
commit
983407896c
@ -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) {
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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_;
|
||||
|
Loading…
Reference in New Issue
Block a user