wip: ADSR

This commit is contained in:
2023-08-09 01:38:40 +04:00
parent 64fa6396bc
commit c63db4fa07
6 changed files with 131 additions and 2 deletions

63
src/ADSR.cpp Normal file
View File

@@ -0,0 +1,63 @@
#include "ADSR.h"
#include "Settings.h"
#include "Logger.h"
ADSR::ADSR(/* args */) {
m_parameters.attack_time = 0.025f;
m_parameters.decay_time = 0.3f;
m_parameters.sustain_level = 0.6f;
m_parameters.release_time = 1.0f;
m_counter = 0;
}
ADSR::ADSR(ADSRParameters param) {
m_parameters = param;
m_counter = 0;
}
ADSR::~ADSR() {}
void ADSR::set_state(std::size_t attack_samples, std::size_t decay_samples,
std::size_t release_samples) {
if (m_counter < attack_samples) {
m_state = Attack;
} else if (m_counter >= attack_samples &&
m_counter < attack_samples + decay_samples) {
m_state = Decay;
} else if (m_counter >= attack_samples + decay_samples) {
m_state = Sustain;
}
}
void ADSR::process_sample(float* sample, std::size_t attack_samples,
std::size_t decay_samples,
std::size_t release_samples) {
set_state(attack_samples, decay_samples, release_samples);
if (m_state == Attack) {
(*sample) = (float)(1.f / attack_samples) * m_counter;
} else if (m_state == Decay) {
}
m_counter++;
// todo: release state on note off (in reset function?)
}
void ADSR::RetriggerState() {
m_counter = 0;
m_state = Attack;
}
void ADSR::Process(std::vector<float>& samples) {
const std::size_t attack_samples =
(std::size_t)(m_parameters.attack_time * SAMPLE_RATE);
const std::size_t decay_samples =
(std::size_t)(m_parameters.decay_time * SAMPLE_RATE);
const std::size_t release_samples =
(std::size_t)(m_parameters.release_time * SAMPLE_RATE);
write_log("Attack samples: %zu \n", attack_samples);
for (std::size_t i = 0; i < samples.size(); i++) {
process_sample(&samples[i], attack_samples, decay_samples,
release_samples);
}
write_log("Processed samples: %zu \n", m_counter);
}

View File

@@ -1,11 +1,19 @@
#include "Synth.h"
#include "ADSR.h"
#include "KeyBoard.h"
#include "OscillatorType.h"
#include "Settings.h"
Synth::Synth(/* args */) { AddOscillator(); }
Synth::Synth(/* args */) {
AddOscillator();
AddEffect(new ADSR());
}
Synth::~Synth() {}
Synth::~Synth() {
m_oscillators.clear();
m_effects.clear();
m_out_signal.clear();
}
std::vector<float>& Synth::get_note(int semitone, float beats) {
float hz = KeyBoard::GetHzBySemitone(semitone);
@@ -20,13 +28,24 @@ std::vector<float>& Synth::get_note(int semitone, float beats) {
return m_adder.SumOscillators(m_oscillators, duration);
}
void Synth::apply_effects() {
for (Effect* effect : m_effects) {
// maybe not here
effect->RetriggerState();
effect->Process(m_out_signal);
}
}
void Synth::ProduceNoteSound(Note input) {
float length = 1.f / input.length;
int semitone_shift = KeyBoard::GetSemitoneShift(input.name);
m_out_signal = get_note(semitone_shift, length);
apply_effects();
}
void Synth::AddOscillator() {
m_oscillators.push_back(
new Oscillator(OscillatorType::Sine, 440.f, VOLUME));
}
void Synth::AddEffect(Effect* fx) { m_effects.push_back(fx); }