basic freeze
This commit is contained in:
@ -35,6 +35,7 @@ void Shifter::Init(float samplerate, int samplesPerBlock)
|
||||
for (int i = 0; i < MAX_VOICES; ++i)
|
||||
{
|
||||
voices[i].Init(samplerate);
|
||||
freeze_voices[i].Init(samplerate);
|
||||
}
|
||||
for (int i = 0; i < BUFFER_SIZE; ++i)
|
||||
{
|
||||
@ -127,6 +128,11 @@ float Shifter::GetOutputEnvelopePeriod(int out_voice) {
|
||||
return in_period * formant_preserve + voices[out_voice].CurrentPeriod() * (1.0 - formant_preserve);
|
||||
}
|
||||
|
||||
float Shifter::GetOutputEnvelopePeriodFreeze(int freeze_voice) {
|
||||
//TODO add something so that low pitch ratios end up reducing formant_preservation
|
||||
return freeze_period * formant_preserve + freeze_voices[freeze_voice].CurrentPeriod() * (1.0 - formant_preserve);
|
||||
}
|
||||
|
||||
int Shifter::GetPeakIndex() {
|
||||
int index = in_playhead - in_period * 2;
|
||||
if (index < 0)
|
||||
@ -152,39 +158,6 @@ int Shifter::GetPeakIndex() {
|
||||
return max_index;
|
||||
}
|
||||
|
||||
//void Shifter::AddInterpolatedFrame(int voice, int max_index, float resampling_period) {
|
||||
// float period_ratio = resampling_period / out_periods[voice];
|
||||
// float f_index;
|
||||
// f_index = max_index - resampling_period;
|
||||
// if (f_index < 0)
|
||||
// {
|
||||
// f_index += BUFFER_SIZE;
|
||||
// }
|
||||
// float mult = 0;
|
||||
// int out_index = out_playhead;
|
||||
// for (int j = 0; j < resampling_period * 2; ++j)
|
||||
// {
|
||||
// // mult = .5
|
||||
// // * (1 - cosf(2 * PI_F * j / (period_to_use * 2 - 1)));
|
||||
// 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];
|
||||
//
|
||||
//
|
||||
// f_index += period_ratio;
|
||||
// if (f_index >= BUFFER_SIZE)
|
||||
// {
|
||||
// f_index -= BUFFER_SIZE;
|
||||
// }
|
||||
// if (++out_index >= BUFFER_SIZE)
|
||||
// {
|
||||
// out_index -= BUFFER_SIZE;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
void Shifter::AddInterpolatedFrame(int voice, int max_index, float resampling_period) {
|
||||
float period_ratio = in_period / resampling_period;
|
||||
@ -230,6 +203,22 @@ void Shifter::AddInterpolatedFrame(int voice, int max_index, float resampling_pe
|
||||
|
||||
void Shifter::GetSamples(float** output, const float* input, size_t size)
|
||||
{
|
||||
if (freeze_needs_copy) {
|
||||
freeze_needs_copy = false;
|
||||
//copy current buffer to freeze buffer
|
||||
int index = GetPeakIndex();
|
||||
memset(freeze_buffer, 0, sizeof(freeze_buffer));
|
||||
CopyInputToFreezeBuffer(index);
|
||||
//init freeze voices
|
||||
for (int i = 0; i < MAX_VOICES; ++i) {
|
||||
//freeze_voices[i].Init(sample_rate_);
|
||||
if (voices[i].IsActive()) {
|
||||
freeze_voices[i].Trigger(voices[i].GetMidiNote());
|
||||
freeze_voices[i].panning = voices[i].panning;
|
||||
freeze_voices[i].SetPortamentoTime(0.0001f);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
|
||||
@ -251,6 +240,20 @@ void Shifter::GetSamples(float** output, const float* input, size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
//add freeze samples if necessary
|
||||
for (int out_p = 0; out_p < MAX_VOICES; ++out_p)
|
||||
{
|
||||
freeze_voices[out_p].Process();
|
||||
if (!freeze_voices[out_p].IsActive()) continue;
|
||||
if (freeze_voices[out_p].PeriodOverflow())
|
||||
{
|
||||
float resampling_period = GetOutputEnvelopePeriodFreeze(out_p);
|
||||
|
||||
//add samples centered on that max
|
||||
AddFreezeToOutput(out_p, resampling_period);
|
||||
}
|
||||
}
|
||||
|
||||
if (out_period_counter > out_period)
|
||||
{
|
||||
out_period_counter -= out_period;
|
||||
@ -328,4 +331,75 @@ void Shifter::SetHarmonyMix(float mix) {
|
||||
harmony_mix = 1.0f;
|
||||
melody_mix = (1.0f - mix) * 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void Shifter::CopyInputToFreezeBuffer(int max_index) {
|
||||
freeze_period = in_period;
|
||||
float period_ratio = 1;
|
||||
float f_index;
|
||||
f_index = max_index - in_period;
|
||||
if (f_index < 0)
|
||||
{
|
||||
f_index += BUFFER_SIZE;
|
||||
}
|
||||
float mult = 0;
|
||||
for (int j = 0; j < in_period * 2; ++j)
|
||||
{
|
||||
mult = .5 * (1 - cos_lookup[(int)((float)j / (in_period * 2.0) * 8191.0)]);
|
||||
float value = in_buffer[(int)f_index] * mult;
|
||||
freeze_buffer[j] = value;
|
||||
f_index += 1;
|
||||
if (f_index >= BUFFER_SIZE)
|
||||
{
|
||||
f_index -= BUFFER_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Shifter::AddFreezeToOutput(int voice, float resampling_period) {
|
||||
float period_ratio = freeze_period / resampling_period;
|
||||
float f_index;
|
||||
f_index = 0;
|
||||
if (f_index < 0)
|
||||
{
|
||||
f_index += BUFFER_SIZE;
|
||||
}
|
||||
float mult = 0;
|
||||
int out_index = out_playhead;
|
||||
for (int j = 0; j < resampling_period * 2; ++j)
|
||||
{
|
||||
// mult = .5
|
||||
// * (1 - cosf(2 * PI_F * j / (period_to_use * 2 - 1)));
|
||||
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) * freeze_buffer[(int)f_index] + (interp)*freeze_buffer[(int)(f_index + 1) % 8192]);
|
||||
value *= freeze_voices[voice].CurrentAmplitude();
|
||||
out_buffer[0][out_index] += value * freeze_voices[voice].GetPanning(0) * freeze_volume;
|
||||
out_buffer[1][out_index] += value * freeze_voices[voice].GetPanning(1) * freeze_volume;
|
||||
|
||||
|
||||
f_index += period_ratio;
|
||||
if (f_index >= BUFFER_SIZE)
|
||||
{
|
||||
f_index -= BUFFER_SIZE;
|
||||
}
|
||||
if (++out_index >= BUFFER_SIZE)
|
||||
{
|
||||
out_index -= BUFFER_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Shifter::SetFreeze(bool freeze) {
|
||||
if (!freeze_mode && freeze) {
|
||||
freeze_needs_copy = true;
|
||||
|
||||
}
|
||||
else if (freeze_mode && !freeze) {
|
||||
//release freeze voices
|
||||
for (int i = 0; i < MAX_VOICES; ++i) {
|
||||
freeze_voices[i].Release();
|
||||
}
|
||||
}
|
||||
freeze_mode = freeze;
|
||||
}
|
||||
Reference in New Issue
Block a user