mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +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.
|
/// As per ::SampleSource; provides audio output.
|
||||||
void get_samples(std::size_t number_of_samples, std::int16_t *target);
|
void get_samples(std::size_t number_of_samples, std::int16_t *target);
|
||||||
void set_sample_volume_range(std::int16_t range);
|
void set_sample_volume_range(std::int16_t range);
|
||||||
|
static constexpr bool get_is_stereo() { return false; }
|
||||||
|
|
||||||
/// Writes to the SCC.
|
/// Writes to the SCC.
|
||||||
void write(uint16_t address, uint8_t value);
|
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) {
|
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) {
|
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 {
|
template <typename... S> class CompoundSourceHolder: public Outputs::Speaker::SampleSource {
|
||||||
public:
|
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);
|
std::memset(target, 0, sizeof(std::int16_t) * number_of_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,18 +85,39 @@ template <typename... T> class CompoundSource:
|
|||||||
public:
|
public:
|
||||||
CompoundSourceHolder(S &source, R &...next) : source_(source), next_source_(next...) {}
|
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()) {
|
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);
|
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 {
|
} else {
|
||||||
int16_t next_samples[number_of_samples];
|
// This will happen only if mapping from mono to stereo, never in the
|
||||||
next_source_.get_samples(number_of_samples, next_samples);
|
// other direction, because the compound source outputs stereo if any
|
||||||
source_.get_samples(number_of_samples, target);
|
// subcomponent does. So it outputs mono only if no stereo devices are
|
||||||
while(number_of_samples--) {
|
// in the mixing chain.
|
||||||
target[number_of_samples] += next_samples[number_of_samples];
|
while(buffer_size--) {
|
||||||
|
target[buffer_size] += local_samples[buffer_size >> 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: accelerate above?
|
||||||
}
|
}
|
||||||
|
|
||||||
void skip_samples(const std::size_t number_of_samples) {
|
void skip_samples(const std::size_t number_of_samples) {
|
||||||
|
Loading…
Reference in New Issue
Block a user