#ifndef SHIFTER_H #define SHIFTER_H #include "Helmholtz.h" #include "shifter_voice.h" #define BUFFER_SIZE 8192 #define MAX_VOICES 12 template 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(float samplerate, int samplesPerBlock); 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; ShifterVoice voices[MAX_VOICES]; 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 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 float out_period = 0; //C3 float in_period = 366.936; float out_period_counter = 0; float cos_lookup[8192]; float sample_rate_; int blocksize; }; #endif