mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-16 18:30:32 +00:00
Merge pull request #416 from TomHarte/AppleAudio
Corrects Apple II output audio.
This commit is contained in:
commit
fa0b6e8a08
@ -29,9 +29,12 @@ class Toggle: public Outputs::Speaker::SampleSource {
|
|||||||
bool get_output();
|
bool get_output();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Accessed on the calling thread.
|
||||||
bool is_enabled_ = false;
|
bool is_enabled_ = false;
|
||||||
int16_t level_ = 0, volume_ = 0;
|
|
||||||
Concurrency::DeferringAsyncTaskQueue &audio_queue_;
|
Concurrency::DeferringAsyncTaskQueue &audio_queue_;
|
||||||
|
|
||||||
|
// Accessed on the audio thread.
|
||||||
|
int16_t level_ = 0, volume_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,9 @@ class ConcreteMachine:
|
|||||||
void update_video() {
|
void update_video() {
|
||||||
video_->run_for(cycles_since_video_update_.flush());
|
video_->run_for(cycles_since_video_update_.flush());
|
||||||
}
|
}
|
||||||
|
static const int audio_divider = 8;
|
||||||
void update_audio() {
|
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];
|
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
|
// 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).
|
// 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.
|
// Also, start with randomised memory contents.
|
||||||
Memory::Fuzz(ram_, sizeof(ram_));
|
Memory::Fuzz(ram_, sizeof(ram_));
|
||||||
|
@ -86,6 +86,18 @@ template <typename T> class LowpassSpeaker: public Speaker {
|
|||||||
filter_parameters_.parameters_are_dirty = true;
|
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
|
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.
|
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
|
// 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_;
|
T &sample_source_;
|
||||||
|
|
||||||
std::size_t output_buffer_pointer_ = 0;
|
std::size_t output_buffer_pointer_ = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user