portemento, adsr
This commit is contained in:
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user