1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-23 20:29:42 +00:00

With minor infrastructure fixes, switch Mockingboard to stereo.

This commit is contained in:
Thomas Harte 2024-02-15 09:42:33 -05:00
parent e1fdda928a
commit 51de1892c0
3 changed files with 30 additions and 28 deletions

View File

@ -65,12 +65,12 @@ constexpr float master_clock = 14318180.0;
/// allowing for stretched CPU clock cycles.
struct StretchedAYPair:
Apple::II::AYPair,
public Outputs::Speaker::BufferSource<StretchedAYPair, false> {
public Outputs::Speaker::BufferSource<StretchedAYPair, true> {
using AYPair::AYPair;
template <Outputs::Speaker::Action action>
void apply_samples(std::size_t number_of_samples, Outputs::Speaker::MonoSample *target) {
void apply_samples(std::size_t number_of_samples, Outputs::Speaker::StereoSample *target) {
// (1) take 64 windows of 7 input cycles followed by one window of 8 input cycles;
// (2) after each four windows, advance the underlying AY.
@ -168,10 +168,10 @@ template <Analyser::Static::AppleII::Target::Model model, bool has_mockingboard>
Audio::Toggle audio_toggle_;
StretchedAYPair ays_;
using SourceT =
std::conditional_t<has_mockingboard, Outputs::Speaker::CompoundSource<Audio::Toggle, StretchedAYPair>, Audio::Toggle>;
std::conditional_t<has_mockingboard, Outputs::Speaker::CompoundSource<StretchedAYPair, Audio::Toggle>, Audio::Toggle>;
using LowpassT = Outputs::Speaker::PullLowpass<SourceT>;
Outputs::Speaker::CompoundSource<Audio::Toggle, StretchedAYPair> mixer_;
Outputs::Speaker::CompoundSource<StretchedAYPair, Audio::Toggle> mixer_;
Outputs::Speaker::PullLowpass<SourceT> speaker_;
Cycles cycles_since_audio_update_;
@ -570,7 +570,7 @@ template <Analyser::Static::AppleII::Target::Model model, bool has_mockingboard>
video_(video_bus_handler_),
audio_toggle_(audio_queue_),
ays_(audio_queue_),
mixer_(audio_toggle_, ays_),
mixer_(ays_, audio_toggle_),
speaker_(lowpass_source()),
language_card_(*this),
auxiliary_switches_(*this),

View File

@ -28,16 +28,19 @@ class AYPair {
}
void set_sample_volume_range(std::int16_t range) {
ays_[0].set_sample_volume_range(range >> 1);
ays_[1].set_sample_volume_range(range >> 1);
ays_[0].set_sample_volume_range(range);
ays_[1].set_sample_volume_range(range);
}
bool is_zero_level() const {
return ays_[0].is_zero_level() && ays_[1].is_zero_level();
}
Outputs::Speaker::MonoSample level() const {
return ays_[0].level() + ays_[1].level();
Outputs::Speaker::StereoSample level() const {
Outputs::Speaker::StereoSample level;
level.left = ays_[0].level();
level.right = ays_[1].level();
return level;
}
GI::AY38910::AY38910SampleSource<false> &get(int index) {

View File

@ -77,29 +77,28 @@ template <typename... T> class CompoundSource:
// Map up and return.
for(std::size_t c = 0; c < number_of_samples; c++) {
Outputs::Speaker::apply<action>(target[c].left, StereoSample(conversion_source_[c]));
Outputs::Speaker::apply<action>(target[c], StereoSample(conversion_source_[c]));
}
return;
}
} else {
constexpr bool is_final_source = sizeof...(R) == 0;
constexpr bool is_final_source = sizeof...(R) == 0;
// Get the rest of the output, if any.
if constexpr (!is_final_source) {
next_source_.template apply_samples<action, output_stereo>(number_of_samples, target);
}
if(source_.is_zero_level()) {
// This component is currently outputting silence; therefore don't add anything to the output
// audio. Zero fill only if this is the final source (as everything above will be additive).
if constexpr (is_final_source) {
Outputs::Speaker::fill<action>(target, target + number_of_samples, typename SampleT<output_stereo>::type());
// Get the rest of the output, if any.
if constexpr (!is_final_source) {
next_source_.template apply_samples<action, output_stereo>(number_of_samples, target);
}
return;
}
// Add in this component's output.
source_.template apply_samples<is_final_source ? Action::Store : Action::Mix>(number_of_samples, target);
if(source_.is_zero_level()) {
// This component is currently outputting silence; therefore don't add anything to the output
// audio. Zero fill only if this is the final source (as everything above will be additive).
if constexpr (is_final_source) {
Outputs::Speaker::fill<action>(target, target + number_of_samples, typename SampleT<output_stereo>::type());
}
return;
}
// Add in this component's output.
source_.template apply_samples<is_final_source ? Action::Store : Action::Mix>(number_of_samples, target);
}
}
void set_scaled_volume_range(int16_t range, double *volumes, double scale) {