sample_bank = sample_bank_def; | sample_bank = sample_bank_def; | ||||
} | } | ||||
void AudioEffectGranular::freeze(int16_t activate, int16_t playpack_rate_def, int16_t freeze_length_def) | |||||
void AudioEffectGranular::beginFreeze_int(int grain_samples) | |||||
{ | { | ||||
if (activate == 0) { | |||||
grain_mode = 0; | |||||
allow_len_change = true; | |||||
return; | |||||
} | |||||
__disable_irq(); | __disable_irq(); | ||||
grain_mode = 1; | grain_mode = 1; | ||||
rate(playpack_rate_def); | |||||
if (max_sample_len <= 1500) { | |||||
freeze_len = max_sample_len; | |||||
if (grain_samples < max_sample_len) { | |||||
freeze_len = grain_samples; | |||||
} else { | } else { | ||||
freeze_len = ((max_sample_len - 1500) * freeze_length_def / 1023) + 1500; | |||||
freeze_len = grain_samples; | |||||
} | } | ||||
sample_loaded = false; | sample_loaded = false; | ||||
write_en = false; | write_en = false; | ||||
sample_req = true; | sample_req = true; | ||||
__enable_irq(); | __enable_irq(); | ||||
Serial.print("in = "); | Serial.print("in = "); | ||||
Serial.print(freeze_length_def); | |||||
Serial.print(grain_samples); | |||||
Serial.print(", freeze len = "); | Serial.print(", freeze len = "); | ||||
Serial.println(freeze_len); | Serial.println(freeze_len); | ||||
} | } | ||||
void AudioEffectGranular::shift(int16_t activate, int16_t playpack_rate_def, int16_t grain_length_def) | |||||
void AudioEffectGranular::beginPitchShift_int(int grain_samples) | |||||
{ | { | ||||
if (activate == 0) { | |||||
grain_mode = 0; | |||||
allow_len_change = true; | |||||
return; | |||||
} | |||||
__disable_irq(); | __disable_irq(); | ||||
grain_mode = 2; | grain_mode = 2; | ||||
rate(playpack_rate_def); | |||||
if (allow_len_change) { | if (allow_len_change) { | ||||
if (grain_length_def < 100) grain_length_def = 100; | |||||
if (grain_samples < 100) grain_samples = 100; | |||||
int maximum = (max_sample_len - 1) / 3; | int maximum = (max_sample_len - 1) / 3; | ||||
if (grain_length_def > maximum) grain_length_def = maximum; | |||||
glitch_len = grain_length_def; | |||||
if (grain_samples > maximum) grain_samples = maximum; | |||||
glitch_len = grain_samples; | |||||
} | } | ||||
sample_loaded = false; | sample_loaded = false; | ||||
write_en = false; | write_en = false; | ||||
__enable_irq(); | __enable_irq(); | ||||
} | } | ||||
void AudioEffectGranular::stop() | |||||
{ | |||||
grain_mode = 0; | |||||
allow_len_change = true; | |||||
} | |||||
void AudioEffectGranular::rate(int16_t playpack_rate_def) | void AudioEffectGranular::rate(int16_t playpack_rate_def) | ||||
{ | { | ||||
playpack_rate = playpack_rate_def; | playpack_rate = playpack_rate_def; |
AudioEffectGranular(void): AudioStream(1,inputQueueArray) { } | AudioEffectGranular(void): AudioStream(1,inputQueueArray) { } | ||||
void begin(int16_t *sample_bank_def, int16_t max_len_def); | void begin(int16_t *sample_bank_def, int16_t max_len_def); | ||||
void rate(int16_t playpack_rate_def); | void rate(int16_t playpack_rate_def); | ||||
void freeze(int16_t activate, int16_t playpack_rate_def, int16_t grain_length_def); | |||||
void shift(int16_t activate, int16_t playpack_rate_def, int16_t grain_length_def); | |||||
void beginFreeze(float grain_length) { | |||||
if (grain_length <= 0.0) return; | |||||
beginFreeze_int(grain_length * (AUDIO_SAMPLE_RATE_EXACT * 0.001) + 0.5); | |||||
} | |||||
void beginPitchShift(float grain_length) { | |||||
if (grain_length <= 0.0) return; | |||||
beginPitchShift_int(grain_length * (AUDIO_SAMPLE_RATE_EXACT * 0.001) + 0.5); | |||||
} | |||||
void stop(); | |||||
virtual void update(void); | virtual void update(void); | ||||
private: | private: | ||||
void beginFreeze_int(int grain_samples); | |||||
void beginPitchShift_int(int grain_samples); | |||||
audio_block_t *inputQueueArray[1]; | audio_block_t *inputQueueArray[1]; | ||||
int16_t *sample_bank; | int16_t *sample_bank; | ||||
int16_t max_sample_len; | int16_t max_sample_len; |
Bounce button1 = Bounce(1, 15); | Bounce button1 = Bounce(1, 15); | ||||
Bounce button2 = Bounce(2, 15); | Bounce button2 = Bounce(2, 15); | ||||
#define GRANULAR_MEMORY_SIZE 12800 // enough for 29 ms at 44.1 kHz | |||||
#define GRANULAR_MEMORY_SIZE 12800 // enough for 290 ms at 44.1 kHz | |||||
int16_t granularMemory[GRANULAR_MEMORY_SIZE]; | int16_t granularMemory[GRANULAR_MEMORY_SIZE]; | ||||
// Use these with the Teensy Audio Shield | // Use these with the Teensy Audio Shield | ||||
button0.update(); | button0.update(); | ||||
button1.update(); | button1.update(); | ||||
button2.update(); | button2.update(); | ||||
// read knobs | |||||
int knobA2 = analogRead(A2); | |||||
int knobA3 = analogRead(A3); | |||||
// read knobs, scale to 0-1.0 numbers | |||||
float knobA2 = (float)analogRead(A2) / 1023.0; | |||||
float knobA3 = (float)analogRead(A3) / 1023.0; | |||||
if (button0.fallingEdge()) { | if (button0.fallingEdge()) { | ||||
granular1.freeze(1, knobA2, knobA3); | |||||
// Button 0 starts Freeze effect | |||||
granular1.beginFreeze(knobA3 * 290.0); | |||||
} | } | ||||
if (button0.risingEdge()) { | if (button0.risingEdge()) { | ||||
granular1.freeze(0, knobA2, knobA3); | |||||
granular1.stop(); | |||||
} | } | ||||
if (button1.fallingEdge()) { | if (button1.fallingEdge()) { | ||||
granular1.shift(1, knobA2, knobA3); | |||||
// Button 1 starts Pitch Shift effect | |||||
granular1.beginPitchShift(knobA3 * 100.0); | |||||
} | } | ||||
if (button1.risingEdge()) { | if (button1.risingEdge()) { | ||||
granular1.shift(0, knobA2, knobA3); | |||||
granular1.stop(); | |||||
} | } | ||||
// continuously adjust pitch bend | |||||
granular1.rate(knobA2 * 1023.0); | |||||
} | } |