1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-09-07 12:54:34 +00:00

Merge pull request #416 from TomHarte/AppleAudio

Corrects Apple II output audio.
This commit is contained in:
Thomas Harte 2018-04-21 18:01:59 -04:00 committed by GitHub
commit fa0b6e8a08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 13 deletions

View File

@ -29,9 +29,12 @@ class Toggle: public Outputs::Speaker::SampleSource {
bool get_output();
private:
// Accessed on the calling thread.
bool is_enabled_ = false;
int16_t level_ = 0, volume_ = 0;
Concurrency::DeferringAsyncTaskQueue &audio_queue_;
// Accessed on the audio thread.
int16_t level_ = 0, volume_ = 0;
};
}

View File

@ -51,8 +51,9 @@ class ConcreteMachine:
void update_video() {
video_->run_for(cycles_since_video_update_.flush());
}
static const int audio_divider = 8;
void update_audio() {
speaker_.run_for(cycles_since_audio_update_.divide(Cycles(16)));
speaker_.run_for(audio_queue_, cycles_since_audio_update_.divide(Cycles(audio_divider)));
}
uint8_t ram_[48*1024];
@ -82,7 +83,7 @@ class ConcreteMachine:
// The speaker, however, should think it is clocked at half the master clock, per a general
// decision to sample it at seven times the CPU clock (plus stretches).
speaker_.set_input_rate(static_cast<float>(master_clock / (2.0 * 16.0)));
speaker_.set_input_rate(static_cast<float>(master_clock / (2.0 * static_cast<float>(audio_divider))));
// Also, start with randomised memory contents.
Memory::Fuzz(ram_, sizeof(ram_));

View File

@ -86,6 +86,18 @@ template <typename T> class LowpassSpeaker: public Speaker {
filter_parameters_.parameters_are_dirty = true;
}
/*!
Schedules an advancement by the number of cycles specified on the provided queue.
The speaker will advance by obtaining data from the sample source supplied
at construction, filtering it and passing it on to the speaker's delegate if there is one.
*/
void run_for(Concurrency::DeferringAsyncTaskQueue &queue, const Cycles cycles) {
queue.defer([this, cycles] {
run_for(cycles);
});
}
private:
/*!
Advances by the number of cycles specified, obtaining data from the sample source supplied
at construction, filtering it and passing it on to the speaker's delegate if there is one.
@ -173,16 +185,6 @@ template <typename T> class LowpassSpeaker: public Speaker {
// TODO: input rate is less than output rate
}
/*!
Provides a convenience shortcut for deferring a call to run_for.
*/
void run_for(Concurrency::DeferringAsyncTaskQueue &queue, const Cycles cycles) {
queue.defer([this, cycles] {
run_for(cycles);
});
}
private:
T &sample_source_;
std::size_t output_buffer_pointer_ = 0;