| 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); | |||||
| } | } |