portemento, adsr

This commit is contained in:
michalcourson
2025-10-25 14:49:02 -04:00
parent 7ba141daed
commit d68a6d5c2a
12 changed files with 2121 additions and 1460 deletions

View File

@ -20,9 +20,9 @@ void Shifter::Init()
volume = 1;
helm.setframesize(1024);
helm.setoverlap(1);
for (int i = 0; i < MAX_VOICES + 1; ++i)
for (int i = 0; i < MAX_VOICES; ++i)
{
out_midi[i] = -1;
voices[i].Init(48000);
}
for (int i = 0; i < BUFFER_SIZE; ++i)
{
@ -33,7 +33,6 @@ void Shifter::Init()
for (int i = 0; i < 8192; ++i) {
cos_lookup[i] = cos(2 * PI_F * i / 8192.0);
}
out_panning[MAX_VOICES] = 0.5f;
}
void Shifter::Process(const float* const* in,
@ -104,22 +103,25 @@ void Shifter::DetectPitch(const float* const* in, float** out, size_t size)
if (midi != last_autotune_midi) {
last_autotune_midi = midi;
out_periods[MAX_VOICES] = in_period;
out_period = in_period;
}
float error = target_out_period - out_periods[MAX_VOICES];
float error = target_out_period - out_period;
float adjustment = error * out_period_filter_amount;
//target_out_period = in_period * out_period_filter_amount + target_out_period * (1 - out_period_filter_amount);
out_midi[MAX_VOICES] = midi;
out_periods[MAX_VOICES] += adjustment;
out_midi = midi;
out_period += adjustment;
}
void Shifter::SetRates() {}
float Shifter::GetOutputEnvelopePeriod(int out_voice) {
if (out_voice >= MAX_VOICES) {
return in_period * formant_preserve + out_period *(1.0 - formant_preserve);
}
//TODO add something so that low pitch ratios end up reducing formant_preservation
return in_period * formant_preserve + out_periods[out_voice] * (1.0 - formant_preserve);
return in_period * formant_preserve + voices[out_voice].CurrentPeriod() * (1.0 - formant_preserve);
}
int Shifter::GetPeakIndex() {
@ -198,8 +200,16 @@ void Shifter::AddInterpolatedFrame(int voice, int max_index, float resampling_pe
float interp = f_index - (int)f_index;
mult = .5 * (1 - cos_lookup[(int)((float)j / (resampling_period * 2.0) * 8191.0)]);
float value = ((1 - interp) * in_buffer[(int)f_index] + (interp)*in_buffer[(int)(f_index + 1) % 8192]) * mult;
out_buffer[0][out_index] += value * (1 - out_panning[voice]);
out_buffer[1][out_index] += value * out_panning[voice];
if(voice >= MAX_VOICES) {
//value *= volume;
out_buffer[0][out_index] += value;
out_buffer[1][out_index] += value;
} else {
value *= voices[voice].CurrentAmplitude() * volume;
out_buffer[0][out_index] += value * voices[voice].GetPanning(0);
out_buffer[1][out_index] += value * voices[voice].GetPanning(1);
}
f_index += period_ratio;
@ -220,13 +230,12 @@ void Shifter::GetSamples(float** output, const float* input, size_t size)
{
//add new samples if necessary
for (int out_p = 0; out_p < MAX_VOICES + 1; ++out_p)
for (int out_p = 0; out_p < MAX_VOICES; ++out_p)
{
if (out_midi[out_p] == -1) continue;
if (out_period_counters[out_p] > out_periods[out_p])
if (!voices[out_p].IsActive()) continue;
voices[out_p].Process();
if (voices[out_p].PeriodOverflow())
{
out_period_counters[out_p] -= out_periods[out_p];
float resampling_period = GetOutputEnvelopePeriod(out_p);
@ -237,6 +246,19 @@ void Shifter::GetSamples(float** output, const float* input, size_t size)
AddInterpolatedFrame(out_p, max_index, resampling_period);
}
}
if (out_period_counter > out_period)
{
out_period_counter -= out_period;
float resampling_period = GetOutputEnvelopePeriod(MAX_VOICES);
//find the start index
int max_index = GetPeakIndex();
//add samples centered on that max
AddInterpolatedFrame(MAX_VOICES, max_index, resampling_period);
}
//add input samples
in_buffer[in_playhead] = input[i];
@ -256,27 +278,20 @@ void Shifter::GetSamples(float** output, const float* input, size_t size)
{
out_playhead -= BUFFER_SIZE;
}
for (int out_p = 0; out_p < MAX_VOICES + 1; ++out_p)
{
if (out_midi[out_p] == -1) continue;
out_period_counters[out_p] += 1;
}
out_period_counter++;
}
}
void Shifter::AddMidiNote(int note) {
for (int i = 0; i < MAX_VOICES; ++i) {
if (out_midi[i] == note) {
if (voices[i].IsActive() && voices[i].GetMidiNote() == note) {
return;
}
}
for (int i = 0; i < MAX_VOICES; ++i) {
if (out_midi[i] == -1) {
out_midi[i] = note;
out_periods[i] = 48000.0f / mtof(note);
out_period_counters[i] = 0;
out_panning[i] = rand() / (float)RAND_MAX;
if (!voices[i].IsActive()) {
voices[i].Trigger(note);
return;
}
}
@ -285,8 +300,8 @@ void Shifter::AddMidiNote(int note) {
void Shifter::RemoveMidiNote(int note) {
for (int i = 0; i < MAX_VOICES; ++i) {
if (out_midi[i] == note) {
out_midi[i] = -1;
if (voices[i].IsActive() && voices[i].GetMidiNote() == note) {
voices[i].Release();
return;
}
}