mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-24 12:30:17 +00:00
With minor infrastructure fixes, switch Mockingboard to stereo.
This commit is contained in:
parent
e1fdda928a
commit
51de1892c0
@ -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),
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user