mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-27 01:31:42 +00:00
Makes CompoundSource mono/stereo-aware.
This commit is contained in:
parent
50d356be2f
commit
545a6177bb
@ -32,6 +32,7 @@ class SCC: public ::Outputs::Speaker::SampleSource {
|
||||
/// As per ::SampleSource; provides audio output.
|
||||
void get_samples(std::size_t number_of_samples, std::int16_t *target);
|
||||
void set_sample_volume_range(std::int16_t range);
|
||||
static constexpr bool get_is_stereo() { return false; }
|
||||
|
||||
/// Writes to the SCC.
|
||||
void write(uint16_t address, uint8_t value);
|
||||
|
@ -33,7 +33,7 @@ template <typename... T> class CompoundSource:
|
||||
}
|
||||
|
||||
void get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
||||
source_holder_.get_samples(number_of_samples, target);
|
||||
source_holder_.template get_samples<get_is_stereo()>(number_of_samples, target);
|
||||
}
|
||||
|
||||
void skip_samples(const std::size_t number_of_samples) {
|
||||
@ -66,7 +66,7 @@ template <typename... T> class CompoundSource:
|
||||
|
||||
template <typename... S> class CompoundSourceHolder: public Outputs::Speaker::SampleSource {
|
||||
public:
|
||||
void get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
||||
template <bool output_stereo> void get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
||||
std::memset(target, 0, sizeof(std::int16_t) * number_of_samples);
|
||||
}
|
||||
|
||||
@ -85,18 +85,39 @@ template <typename... T> class CompoundSource:
|
||||
public:
|
||||
CompoundSourceHolder(S &source, R &...next) : source_(source), next_source_(next...) {}
|
||||
|
||||
void get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
||||
template <bool output_stereo> void get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
||||
// Get the rest of the output.
|
||||
next_source_.template get_samples<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 — just pass the call onward.
|
||||
source_.skip_samples(number_of_samples);
|
||||
next_source_.get_samples(number_of_samples, target);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get this component's output.
|
||||
auto buffer_size = number_of_samples * (output_stereo ? 2 : 1);
|
||||
int16_t local_samples[buffer_size];
|
||||
source_.get_samples(number_of_samples, local_samples);
|
||||
|
||||
// Merge it in; furthermore if total output is stereo but this source isn't,
|
||||
// map it to stereo.
|
||||
if constexpr (output_stereo == S::get_is_stereo()) {
|
||||
while(buffer_size--) {
|
||||
target[buffer_size] += local_samples[buffer_size];
|
||||
}
|
||||
} else {
|
||||
int16_t next_samples[number_of_samples];
|
||||
next_source_.get_samples(number_of_samples, next_samples);
|
||||
source_.get_samples(number_of_samples, target);
|
||||
while(number_of_samples--) {
|
||||
target[number_of_samples] += next_samples[number_of_samples];
|
||||
// This will happen only if mapping from mono to stereo, never in the
|
||||
// other direction, because the compound source outputs stereo if any
|
||||
// subcomponent does. So it outputs mono only if no stereo devices are
|
||||
// in the mixing chain.
|
||||
while(buffer_size--) {
|
||||
target[buffer_size] += local_samples[buffer_size >> 1];
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: accelerate above?
|
||||
}
|
||||
|
||||
void skip_samples(const std::size_t number_of_samples) {
|
||||
|
Loading…
Reference in New Issue
Block a user