- #include "Instrument.h"
- #include "waveforms/Sawtooth.h"
- #include "waveforms/Sine.h"
- #include "waveforms/Square.h"
- #include "waveforms/Triangle.h"
- #include "effects/Distortion.h"
-
- Instrument::Instrument(AudioHost *host) {
- this->host = host;
- wave = new Sine();
- wave->host = host;
- envelope->initialize(host);
- auto *filter = new LowPass();
- filter->host = host;
- effects.push_back(filter);
- auto *noise = new Noise();
- noise->host = host;
- effects.push_back(noise);
- auto *distortion = new Distortion();
- distortion->host = host;
- effects.push_back(distortion);
- }
-
- void multiply(float *target, float *modulation, uint32_t size) {
- for (uint32_t i = 0; i < size; i++) {
- target[i] *= modulation[i];
- }
- }
-
- void multiply(float *target, float value, uint32_t size) {
- for (uint32_t i = 0; i < size; i++) {
- target[i] *= value;
- }
- }
-
- void add(float *target, float *other, uint32_t size) {
- for (uint32_t i = 0; i < size; i++) {
- target[i] += other[i];
- }
- }
-
- void processEffect(float *waveform, uint32_t count, Effect *effect) {
- if (effect->influence < 0.01f) {
- return;
- }
- effect->input = waveform;
- float *effectOutput = effect->render(count);
- multiply(effectOutput, effect->influence, count);
- multiply(waveform, 1 - effect->influence, count);
- add(waveform, effectOutput, count);
- }
-
- void Instrument::render(float *buffer, uint32_t count) {
- float *waveform = wave->render(count);
- for (auto effect: effects) {
- processEffect(waveform, count, effect);
- }
- multiply(waveform, envelope->render(count), count);
- multiply(waveform, volume, count);
- add(buffer, waveform, count);
- }
-
- void Instrument::startNote(float frequency) {
- wave->setFrequency(frequency);
- envelope->startNote();
- for (auto effect: effects) {
- effect->frequency = frequency;
- effect->update();
- }
- }
-
- void Instrument::endNote() {
- envelope->endNote();
- }
-
- void Instrument::setWaveform(WaveformType waveform) {
- Waveform *old = wave;
- switch (waveform) {
- case SINE:
- wave = new Sine();
- break;
- case SAWTOOTH:
- wave = new Sawtooth();
- break;
- case SQUARE:
- wave = new Square();
- break;
- case TRIANGLE:
- wave = new Triangle();
- }
- wave->host = host;
- delete old;
- }