150 lines
3.3 KiB
C++
150 lines
3.3 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);
|
|
void SetPortamentoTime(float time) {
|
|
for (int i = 0; i < MAX_VOICES; ++i) {
|
|
voices[i].SetPortamentoTime(time);
|
|
}
|
|
}
|
|
|
|
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 |