diff --git a/app/src/main/cpp/Envelope.cpp b/app/src/main/cpp/Envelope.cpp index 56e9316..8b9d12a 100644 --- a/app/src/main/cpp/Envelope.cpp +++ b/app/src/main/cpp/Envelope.cpp @@ -1,11 +1,21 @@ +#include +#include "Instrument.h" #include "Envelope.h" +void Envelope::initialize(AudioHost *host) { + attackIncrement = 1 / attack / host->sampleRate; + delayIncrement = 1 / delay / host->sampleRate; + releaseIncrement = 1 / release / host->sampleRate; + __android_log_print(ANDROID_LOG_DEBUG, "Envelope", "increments: %f %f %f", attackIncrement, + delayIncrement, releaseIncrement); +} + void Envelope::startNote() { - value = 1; + phase = ATTACK; } void Envelope::endNote() { - value = 0; + phase = RELEASE; } float *Envelope::render(uint32_t sampleCount) { @@ -14,6 +24,29 @@ buffer = new float[sampleCount]; } for (int i = 0; i < sampleCount; ++i) { + switch (phase) { + case ATTACK: + value += attackIncrement; + if (value > 1) { + value = 1; + phase = DELAY; + } + break; + case DELAY: + value -= delayIncrement; + if (value < sustain) { + value = sustain; + phase = SUSTAIN; + } + break; + case RELEASE: + value -= releaseIncrement; + if (value < 0) { + value = 0; + phase = NONE; + } + break; + } buffer[i] = value; } return buffer; diff --git a/app/src/main/cpp/Envelope.cpp b/app/src/main/cpp/Envelope.cpp index 56e9316..8b9d12a 100644 --- a/app/src/main/cpp/Envelope.cpp +++ b/app/src/main/cpp/Envelope.cpp @@ -1,11 +1,21 @@ +#include +#include "Instrument.h" #include "Envelope.h" +void Envelope::initialize(AudioHost *host) { + attackIncrement = 1 / attack / host->sampleRate; + delayIncrement = 1 / delay / host->sampleRate; + releaseIncrement = 1 / release / host->sampleRate; + __android_log_print(ANDROID_LOG_DEBUG, "Envelope", "increments: %f %f %f", attackIncrement, + delayIncrement, releaseIncrement); +} + void Envelope::startNote() { - value = 1; + phase = ATTACK; } void Envelope::endNote() { - value = 0; + phase = RELEASE; } float *Envelope::render(uint32_t sampleCount) { @@ -14,6 +24,29 @@ buffer = new float[sampleCount]; } for (int i = 0; i < sampleCount; ++i) { + switch (phase) { + case ATTACK: + value += attackIncrement; + if (value > 1) { + value = 1; + phase = DELAY; + } + break; + case DELAY: + value -= delayIncrement; + if (value < sustain) { + value = sustain; + phase = SUSTAIN; + } + break; + case RELEASE: + value -= releaseIncrement; + if (value < 0) { + value = 0; + phase = NONE; + } + break; + } buffer[i] = value; } return buffer; diff --git a/app/src/main/cpp/Envelope.h b/app/src/main/cpp/Envelope.h index 57bdfeb..aeaaf58 100644 --- a/app/src/main/cpp/Envelope.h +++ b/app/src/main/cpp/Envelope.h @@ -1,17 +1,26 @@ #ifndef MUSIC_ENVELOPE_H #define MUSIC_ENVELOPE_H -#include - class Envelope; +#include +#include "AudioHost.h" + +enum EnvelopePhase { + NONE, ATTACK, DELAY, SUSTAIN, RELEASE, +}; + class Envelope { private: uint32_t bufferSize = 0; float *buffer; -public: - float attack, delay, sustain, release; + EnvelopePhase phase; + float attackIncrement, delayIncrement, releaseIncrement; float value = 1; +public: + float attack = 0.05, delay = 0.2, sustain = 0.75, release = 0.1; + + void initialize(AudioHost *host); void startNote(); diff --git a/app/src/main/cpp/Envelope.cpp b/app/src/main/cpp/Envelope.cpp index 56e9316..8b9d12a 100644 --- a/app/src/main/cpp/Envelope.cpp +++ b/app/src/main/cpp/Envelope.cpp @@ -1,11 +1,21 @@ +#include +#include "Instrument.h" #include "Envelope.h" +void Envelope::initialize(AudioHost *host) { + attackIncrement = 1 / attack / host->sampleRate; + delayIncrement = 1 / delay / host->sampleRate; + releaseIncrement = 1 / release / host->sampleRate; + __android_log_print(ANDROID_LOG_DEBUG, "Envelope", "increments: %f %f %f", attackIncrement, + delayIncrement, releaseIncrement); +} + void Envelope::startNote() { - value = 1; + phase = ATTACK; } void Envelope::endNote() { - value = 0; + phase = RELEASE; } float *Envelope::render(uint32_t sampleCount) { @@ -14,6 +24,29 @@ buffer = new float[sampleCount]; } for (int i = 0; i < sampleCount; ++i) { + switch (phase) { + case ATTACK: + value += attackIncrement; + if (value > 1) { + value = 1; + phase = DELAY; + } + break; + case DELAY: + value -= delayIncrement; + if (value < sustain) { + value = sustain; + phase = SUSTAIN; + } + break; + case RELEASE: + value -= releaseIncrement; + if (value < 0) { + value = 0; + phase = NONE; + } + break; + } buffer[i] = value; } return buffer; diff --git a/app/src/main/cpp/Envelope.h b/app/src/main/cpp/Envelope.h index 57bdfeb..aeaaf58 100644 --- a/app/src/main/cpp/Envelope.h +++ b/app/src/main/cpp/Envelope.h @@ -1,17 +1,26 @@ #ifndef MUSIC_ENVELOPE_H #define MUSIC_ENVELOPE_H -#include - class Envelope; +#include +#include "AudioHost.h" + +enum EnvelopePhase { + NONE, ATTACK, DELAY, SUSTAIN, RELEASE, +}; + class Envelope { private: uint32_t bufferSize = 0; float *buffer; -public: - float attack, delay, sustain, release; + EnvelopePhase phase; + float attackIncrement, delayIncrement, releaseIncrement; float value = 1; +public: + float attack = 0.05, delay = 0.2, sustain = 0.75, release = 0.1; + + void initialize(AudioHost *host); void startNote(); diff --git a/app/src/main/cpp/Instrument.cpp b/app/src/main/cpp/Instrument.cpp index 9e200d8..55d7ecd 100644 --- a/app/src/main/cpp/Instrument.cpp +++ b/app/src/main/cpp/Instrument.cpp @@ -2,6 +2,7 @@ Instrument::Instrument(AudioHost *host) { wave->initialize(host); + envelope->initialize(host); } float *multiply(float *target, float *modulation, uint32_t size) {