mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-11 15:49:38 +00:00
2d892da225
In support of which, it also introduces a means of sample source composition.
64 lines
1.9 KiB
C++
64 lines
1.9 KiB
C++
//
|
|
// CompoundSource.hpp
|
|
// Clock Signal
|
|
//
|
|
// Created by Thomas Harte on 19/12/2017.
|
|
// Copyright © 2017 Thomas Harte. All rights reserved.
|
|
//
|
|
|
|
#ifndef CompoundSource_h
|
|
#define CompoundSource_h
|
|
|
|
#include "SampleSource.hpp"
|
|
|
|
#include <cstring>
|
|
|
|
namespace Outputs {
|
|
namespace Speaker {
|
|
|
|
/*!
|
|
A CompoundSource adds together the sound generated by multiple individual SampleSources.
|
|
It's an instance of template metaprogramming; this is the base case.
|
|
*/
|
|
template <typename... T> class CompoundSource: public Outputs::Speaker::SampleSource {
|
|
public:
|
|
void get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
|
std::memset(target, 0, sizeof(std::int16_t) * number_of_samples);
|
|
}
|
|
};
|
|
|
|
/*!
|
|
A CompoundSource adds together the sound generated by multiple individual SampleSources.
|
|
It's an instance of template metaprogramming; this is the recursive case.
|
|
*/
|
|
template <typename T, typename... R> class CompoundSource<T, R...>: public Outputs::Speaker::SampleSource {
|
|
public:
|
|
CompoundSource(T &source, R &...next) : source_(source), next_source_(next...) {}
|
|
|
|
void get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
|
// This is an ugly solution: get whatever the next source supplies and add the local
|
|
// results to it, with the degenerate case performing a memset to supply an array of 0.
|
|
// TODO: do better. Might need some alteration of SampleSource.
|
|
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];
|
|
}
|
|
}
|
|
|
|
void skip_samples(const std::size_t number_of_samples) {
|
|
source_.skip_samples(number_of_samples);
|
|
next_source_.skip_samples(number_of_samples);
|
|
}
|
|
|
|
private:
|
|
T &source_;
|
|
CompoundSource<R...> next_source_;
|
|
};
|
|
|
|
}
|
|
}
|
|
|
|
#endif /* CompoundSource_h */
|