Files
harmonizer_plugin/Source/Shifter.h
2025-10-30 19:49:58 -04:00

145 lines
3.1 KiB
C++

#ifndef SHIFTER_H
#define SHIFTER_H
#include "Helmholtz.h"
#include "shifter_voice.h"
#define BUFFER_SIZE 8192
#define MAX_VOICES 12
template <typename T, size_t max_capacity>
class circ_queue {
public:
circ_queue() {
head = buffer;
tail = buffer;
size = 0;
capacity = max_capacity;
}
void push(T val) {
if (size == max_capacity) {
pop();
}
*tail = val;
if (++tail >= buffer + max_capacity) {
tail -= max_capacity;
}
size++;
//*head = val;
}
void clear() {
head = buffer;
tail = buffer;
size = 0;
}
T pop() {
if (size > 0) {
T to_ret = *head;
if (++head >= buffer + max_capacity) {
head -= max_capacity;
}
--size;
return to_ret;
}
else {
return T();
}
}
T& get(int indx) {
T* ret_ptr = head + indx;
if (ret_ptr >= buffer + max_capacity) {
ret_ptr -= max_capacity;
}
return *ret_ptr;
}
T& operator[](int indx) {
T* ret_ptr = head + indx;
if (ret_ptr >= buffer + max_capacity) {
ret_ptr -= max_capacity;
}
return *ret_ptr;
}
size_t capacity;
// int size() { return capacity; }
size_t size;
T buffer[max_capacity];
T* head;
T* tail;
};
class Shifter {
public:
void Init();
void Process(const float* const* in,
float** out,
size_t size);
void AddMidiNote(int note);
void RemoveMidiNote(int note);
void SetFormantPreserve(float val) { formant_preserve = val; }
void SetAutoTuneSpeed(float val);
float out_midi = 40;
private:
void DetectPitch(const float* const* in, float** out, size_t size);
void SetRates();
void GetSamples(float** output, const float* input, size_t size);
float GetOutputEnvelopePeriod(int out_voice);
int GetPeakIndex();
void AddInterpolatedFrame(int voice, int max_index, float period_to_use);
Helmholtz helm;
// GranularSustain player;
int selected_sample;
bool playing;
bool looping;
bool loop_engaged;
float play_head;
float rate_factor;
float sample_freq = 440;
float freq_target = 440;
float last_freq = 440;
double current_pitch = 440;
double smear_thresh = .085;
double smear_step = 0.003;
bool onset_trigger = false;
bool pitch_trigger = false;
int trigger_bank;
circ_queue<float, 3> prev_freqs;
float formant_preserve = 0;
float volume;
float pitch_adj;
bool last_record;
int record_playhead;
bool dry_wet = false;
bool is_pitched = true;
float last_freqs[3];
float in_buffer[BUFFER_SIZE];
float out_buffer[2][BUFFER_SIZE];
int out_playhead = 0;
int in_playhead = 0;
int last_autotune_midi = -1;
float out_period_filter_amount = 0.7f; // You can expose this as a parameter
ShifterVoice voices[MAX_VOICES];
float out_period = 0; //C3
float in_period = 366.936;
float out_period_counter = 0;
float cos_lookup[8192];
};
#endif