Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 2 of 2

Thread: Realtime pitch shifter, flange, chorus and modulator MULTI FX Project

  1. #1

    Realtime pitch shifter, flange, chorus and modulator MULTI FX Project

    Hi everyone,
    Finally I got to work SGTL 5000 in way what I want and now Im able to writing own effect codes

    Still I have little issues witch my code because I used queues. I know that will be better if I going to create audio objects rather coding like that anyway for now I prefer my way
    If someone have suggestions how to improve my code and how to fix noise/distortion which occurred occasionally I will be happy and grateful if help me get it better.
    The effect is suitable for T4 witch audio shield. There is some initial code witch cool fx, just upload it to your T4 and have good fun!
    Effect include modulator, realtime pitch detune, reverb, flanger and chorus.
    Code:
    /*  Multi Fx by Diodac
    
        Set effect button on pin 2
        0 = clean
        1 = ring_mod_fx
        2 = pitch_fx
        3 = reverb_fx
        4 = flange_fx
        5 = chorus_fx
        Set level of effect potentiometer on A0
    */
    IntervalTimer timer;
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    #include <Bounce2.h>
    // GUItool: begin automatically generated code
    AudioInputI2S            i2s1Record;           //xy=609,170
    AudioMixer4              mixer1;         //xy=754,183
    AudioPlayQueue           queuePlay;         //xy=876,410
    AudioRecordQueue         queueRecord;         //xy=897,184
    AudioMixer4              mixer2;         //xy=1032,429
    AudioOutputI2S           i2s2Play;           //xy=1216,429
    AudioConnection          patchCord1(i2s1Record, 0, mixer1, 0);
    AudioConnection          patchCord2(i2s1Record, 1, mixer1, 1);
    AudioConnection          patchCord3(mixer1, queueRecord);
    AudioConnection          patchCord4(mixer1, 0, mixer2, 1);
    AudioConnection          patchCord5(queuePlay, 0, mixer2, 0);
    AudioConnection          patchCord6(mixer2, 0, i2s2Play, 0);
    AudioConnection          patchCord7(mixer2, 0, i2s2Play, 1);
    AudioControlSGTL5000     sgtl5000_1;     //xy=923,106
    // GUItool: end automatically generated code
    
    #define BUTTON_PIN 2
    #define LED_PIN 13
    Bounce debouncer = Bounce();
    
    elapsedMillis delayMillis;
    elapsedMillis delayControl;
    
    #define MAX_SAMPLES  128
    #define MAX_QUEUE_SIZE 8
    #define bufferSize 48000
    #define bias 512
    
    int16_t FASTRUN buffer[bufferSize];
    int16_t DMAMEM bufferIn[MAX_SAMPLES * MAX_QUEUE_SIZE];
    int16_t DMAMEM bufferOut[MAX_SAMPLES * MAX_QUEUE_SIZE];
    int32_t record_offset = 0, play_offset = 0;
    int16_t audioDataInput = 0, audioDataOutput = 0;
    static unsigned long pointer = 0;
    float volumeControl = 0;
    volatile int level = 0;
    byte switchEffect = 0;
    
    //Oscillators
    #define points 4095
    unsigned int FASTRUN modulation[points];
    
    //For Flange & Shifters++++++++++++++++++++
    #define MIN 2 //~60us distance
    #define MAX 400 //~ 8.5ms distance
    #define SIZE 400
    #define pitch 11700
    byte dir = 1;
    unsigned int utime = 0, offset = 0, increment = 0, divider = 0, distance = 0, fractional = 0x00;
    int speed = 0, sample = 0, time = 0;
    int32_t resultA = 0, resultB = 0, outputA = 0, outputB = 0;
    
    //Modulators & Wobbies++
    #define space 350
    #define maximum 300
    unsigned int wave = bias;
    int modulation_in = 0;
    int FASTRUN AB[maximum];
    int32_t delay_line = 0, line_A = 0, line_B = 0, calculator = 0, fraction = 0;
    double down = -0.5, down1 = -0.98, down2 = -0.8;
    double up =  0.5, up1 = 0.98, up2 = 0.8;
    
    //Reverb+++++++++++++++
    #define D1  4000
    #define D2  4000
    #define D3  4000
    #define D4  4000
    #define D5  10000
    #define D6  4000
    int  DV1 = 100;
    int  DV2 = 100;
    int  DV3 = 150;
    int  DV4 = 200;
    int  DV5 = 400;
    int  DV6 = 200;
    double  x1 = 0.69, x2 = 0.64, x3 = 0.59, x4 = 0.54;
    double  y_1 = 0.99 , y_2 = 0.94 , y_3 = 0.89 , y_4 = 0.84;
    int FASTRUN X1[D1];
    int FASTRUN X2[D2];
    int FASTRUN X3[D3];
    int FASTRUN X4[D4];
    int FASTRUN X5[D5];
    int FASTRUN X6[D6];
    int32_t  S1 = 0, S2 = 0, S3 = 0, S4 = 0, S5 = 0, S6 = 0, S7 = 0;
    long  DC1 = 0, DC2 = 0, DC3 = 0, DC4 = 0, DC5 = 0, DC6 = 1, DC7 = 1, DC8 = 0;
    
    // Multi ++++++++++++++++++++
    inline uint32_t M32x16(uint32_t x, uint32_t y) {
      return (uint32_t)(((uint32_t)x) * ((uint32_t)y) >> 16);
    }
    
    void setup() {
      Serial.begin(115200);
      AudioMemory(30);
      pinMode(14, INPUT_DISABLE);
      pinMode(15, INPUT_DISABLE);
      pinMode(16, INPUT_DISABLE);
      pinMode(17, INPUT_DISABLE);
      pinMode(22, INPUT_DISABLE);
      pinMode(BUTTON_PIN, INPUT_PULLUP);
      pinMode(LED_PIN, OUTPUT);
      debouncer.attach(BUTTON_PIN);
      debouncer.interval(5);
    
    
      modulation_generator();
    
      timer.begin(effect, 22.676);
      timer.priority(64);
      sgtl5000_1.enable();
      sgtl5000_1.inputSelect(AUDIO_INPUT_MIC);
      sgtl5000_1.micGain(25);
      //sgtl5000_1.lineInLevel(15);
      //sgtl5000_1.lineOutLevel(15);
    
      mixer1.gain(0, 0.7);
      mixer1.gain(1, 0.7);
      mixer1.gain(2, 0);
      mixer1.gain(3, 0);
    
      mixer2.gain(0, 1.0); // Fx signal
      mixer2.gain(1, 0);   // Dry signal
      mixer2.gain(2, 0);
      mixer2.gain(3, 0);
    
      queueRecord.begin();
    
    }
    
    void modulation_generator() {
      for (int i = 0; i < points; i++)
        modulation[i] = (0.99 * cos(((2.0 * PI) / points) * i));
    }
    
    void i2s_to_buffer() {
      memcpy(bufferIn + record_offset, queueRecord.readBuffer(), MAX_SAMPLES * 2);
      queueRecord.freeBuffer();
      record_offset += MAX_SAMPLES;
      while (record_offset >= (MAX_SAMPLES * MAX_QUEUE_SIZE))  record_offset = 0;
    }
    
    void buffer_to_i2s() {
      memcpy(queuePlay.getBuffer(), bufferOut + play_offset , MAX_SAMPLES * 2);
      queuePlay.playBuffer();
      play_offset += MAX_SAMPLES;
      while (play_offset >= (MAX_SAMPLES * MAX_QUEUE_SIZE)) play_offset = 0;
    }
    
    void loop() {
      while (delayControl >= 50) {
        delayControl = 0;
        volumeControl = map(analogRead(A1), 0, 1023, 127, 1023);
        volumeControl = volumeControl / 1023.0;
        sgtl5000_1.volume(volumeControl);
      }
    
      if (digitalRead(BUTTON_PIN) == LOW) {
        digitalWrite(LED_PIN, HIGH );
      } else digitalWrite(LED_PIN, LOW );
      delay(5);
    }
    
    void effect() {
      while (queueRecord.available() >= 2) i2s_to_buffer(), buffer_to_i2s();
      while (delayMillis >= 5) {
        delayMillis = 0;
        level = map(analogRead(A0), 0, 1023, 0, 1023);
      }
      debouncer.update();
      if (debouncer.rose()) {
        switchEffect = switchEffect + 1.0;
      }
    
      if (switchEffect >= 6) switchEffect = 0;
    
      switch (switchEffect) {
        case 0:
          clean();
          break;
        case 1:
          ring_mod_fx();
          break;
        case 2:
          pitch_fx();
          break;
        case 3:
          reverb_fx();
          break;
        case 4:
          flange_fx();
          break;
        case 5:
          chorus_fx();
          break;
      }
    }
    
    void clean() {
      pointer++;
      audioDataInput = bufferIn[pointer];
      bufferOut[pointer] = audioDataInput >> 1;
      while (pointer >= (MAX_SAMPLES * MAX_QUEUE_SIZE)) pointer = 0;
    }
    
    void ring_mod_fx() {
      pointer++;
      audioDataInput = bufferIn[pointer] >> 1;
      bufferOut[pointer] = audioDataOutput;
      while (pointer >= (MAX_SAMPLES * MAX_QUEUE_SIZE)) pointer = 0;
      time = map(level, 0, 1023, 330, 1);
      static long buffIn = bufferSize, buffOut = bufferSize - time;
      buffer[buffIn] = audioDataInput;
      buffIn++;
      if (buffIn >= space) buffIn = 0;
      buffOut = buffIn + offset;
      if (buffOut >= space) buffOut -= space;
      audioDataOutput = buffer[buffOut];
      if (dir) {
        if (offset >= (space - (unsigned int)time)) {
          dir = 0;
          offset--;
        }
        else offset++;
      }
      else {
        if (offset <= 4) {
          dir = 1;
          offset--;
        }
        else offset -= 1;
      }
    }
    
    void pitch_fx() {
      static unsigned int locationIn = SIZE, locationOut = SIZE - fractional;
      pointer++;
      audioDataInput = bufferIn[pointer] >> 1;
      bufferOut[pointer] = audioDataOutput;
      while (pointer >= (MAX_SAMPLES * MAX_QUEUE_SIZE)) pointer = 0;
    
      buffer[locationIn] = audioDataInput;
      locationIn++;
      if (locationIn >= SIZE) locationIn = 0;
      locationOut = locationIn + offset;
      if (locationOut >= SIZE) locationOut -= SIZE;
      outputA = buffer[locationOut];
      locationOut += (SIZE >> 1);
      if (locationOut >= SIZE) locationOut -= SIZE;
      outputB = buffer[locationOut];
      if (offset > (SIZE >> 1)) distance = SIZE - offset;
      else distance = offset;
      resultA = M32x16(outputA, (distance << 7));
      resultB = M32x16(outputB, (((SIZE >> 1) - distance) << 7));
      audioDataOutput = resultA += resultB;
      if (level > bias) {
        fractional += map(level, 511, 1023, 0, 63);
        if (fractional >= 0x0080) {
          offset += (fractional >> 7);
          fractional &= 0x007f;
        }
        if (offset >= SIZE) offset -= SIZE;
      } else if (level < bias) {
        fractional += map(level, 0, 511, 63, 0);
        if (fractional >= 0x0080) {
          offset -= (fractional >> 7);
          fractional &= 0x007f;
        }
        if (offset >= SIZE) offset += SIZE;
      }
    }
    
    void reverb_fx() {
      pointer++;
      audioDataInput = bufferIn[pointer] >> 1;
      bufferOut[pointer] = audioDataOutput;
      while (pointer >= (MAX_SAMPLES * MAX_QUEUE_SIZE)) pointer = 0;
    
      DV1 = map(level << 2, 0, 4095, 100, 4000);
      DV2 = map(level << 2, 0, 4095, 100, 4000);
      DV3 = map(level << 2, 0, 4095, 150, 4000);
      DV4 = map(level << 2, 0, 4095, 200, 4000);
      DV5 = map(level << 2, 0, 4095, 400, 10000);
      DV6 = map(level << 2, 0, 4095, 200, 4000);
    
      X1[DC1] = (audioDataInput + x1 * X1[DC1] / 1.2);
      X2[DC2] = (audioDataInput + x2 * X2[DC2] / 1.4);
      X3[DC3] = (audioDataInput * X3[DC3] / 1.6);
      X4[DC4] = (audioDataInput * X4[DC4] / 1.8);
    
      S1 =  y_1 * X1[DC1];
      S2 =  y_2 * X2[DC2];
      S3 =  y_3 * X3[DC3];
      S4 =  y_4 * X4[DC4];
    
      DC1++; if (DC1 >= DV1) DC1 = 0;
      DC2++; if (DC2 >= DV2) DC2 = 0;
      DC3++; if (DC3 >= DV3) DC3 = 0;
      DC4++; if (DC4 >= DV4) DC4 = 0;
    
      S5 = (S1 + S2 + S3 + S4) / 4;
      X5[DC7] = (S5 + x3 * X5[DC5]);
      S6 = -x3 * X5[DC7] + X5[DC5];
      DC5++; if (DC5 >= DV5) DC5 = 0;
      DC7++; if (DC7 >= D5) DC7 = 0;
      X6[DC8] = (S6 + x4 * X6[DC6]);
      S7 = (int32_t)(-x4 * X6[DC8] + X6[DC6]);
      DC6++; if (DC6 >= DV6) DC6 = 0;
      DC8++; if (DC8 >= D6) DC8 = 0;
      audioDataOutput = S7;
    }
    
    void flange_fx() {
      static int locationIn = SIZE, locationOut = SIZE - fractional;
      pointer++;
      audioDataInput = bufferIn[pointer] >> 1;
      bufferOut[pointer] = audioDataOutput;
      while (pointer >= (MAX_SAMPLES * MAX_QUEUE_SIZE)) pointer = 0;
    
      buffer[locationIn] = audioDataInput;
      locationIn++;
      if (locationIn >= SIZE) locationIn = 0;
      locationOut = locationIn - (fractional >> 8);
      if (locationOut < 0) locationOut += SIZE;
      outputA = buffer[locationOut] + audioDataInput;
      locationOut -= 1;
      if (locationOut < 0) locationOut += SIZE;
      outputB = buffer[locationOut] + audioDataInput;
      resultA = M32x16(outputA, ((0xff - (fractional & 0x00ff)) << 7));
      resultB = M32x16(outputB, ((fractional & 0x00ff) << 7));
      audioDataOutput = (resultA += resultB);
      int shift = level >> 6;
      if (shift >= 11) shift = 11;
      if (dir) {
        if ((fractional >> 8) >= MAX) dir = 0;
        fractional += (1 + shift);
      }
      else {
        if ((fractional >> 8) <= MIN) dir = 1;
        fractional -= (1 + shift);
      }
    }
    
    void chorus_fx() {
      pointer++;
      audioDataInput = bufferIn[pointer] >> 1;
      bufferOut[pointer] = audioDataOutput;
      while (pointer >= (MAX_SAMPLES * MAX_QUEUE_SIZE)) pointer = 0;
    
      modulation_in = (2 + (level >> 3));
      delay_line = modulation_in / 2;
      for (int index = 0; index <= modulation_in; index++)
        AB[modulation_in + 1 - index] = AB[modulation_in - index];
      AB[0] = up * audioDataInput + down * AB[delay_line];
      line_A = delay_line - delay_line * modulation[calculator * 2];
      line_B =  int32_t(line_A);
      fraction = line_A - line_B;
      if (fraction == 0) fraction = 0.01;
      if (fraction == 1) fraction = 0.99;
      calculator++;
      if (calculator * 2 >= points) calculator = 0;
      audioDataOutput = (int32_t)(AB[line_B + 1] * fraction + AB[line_B] * (1 - fraction));
    }

  2. #2
    I little bit improve my code and now it working better. But still comes strange artifactual noise in constant time interval approximately every 7 minutes. it is really weird and I can't find the problem. Also schroeder reverb need small improvement. Pitch shifter, chorus and flange working pretty nice
    Hopefully, Paul maybe you help me find mistake in my code, the incoming noise is a big problem.
    Code:
    /*  Multi Fx by Diodac
    
        Set effect button on pin 2
        0 = clean
        1 = ring_mod_fx
        2 = pitch_fx
        3 = reverb_fx
        4 = flange_fx
        5 = chorus_fx
        Set level of effect potentiometer on A0
        Set level of volume potentiometer on A1
        Set level of dry/wet potentiometer on A2
    */
    IntervalTimer timer;
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    #include <Bounce2.h>
    // GUItool: begin automatically generated code
    AudioInputI2S            i2s1Record;           //xy=609,170
    AudioMixer4              mixer1;         //xy=754,183
    AudioPlayQueue           queuePlay;         //xy=876,410
    AudioRecordQueue         queueRecord;         //xy=897,184
    AudioMixer4              mixer2;         //xy=1032,429
    AudioOutputI2S           i2s2Play;           //xy=1216,429
    AudioConnection          patchCord1(i2s1Record, 0, mixer1, 0);
    AudioConnection          patchCord2(i2s1Record, 1, mixer1, 1);
    AudioConnection          patchCord3(mixer1, queueRecord);
    AudioConnection          patchCord4(mixer1, 0, mixer2, 1);
    AudioConnection          patchCord5(queuePlay, 0, mixer2, 0);
    AudioConnection          patchCord6(mixer2, 0, i2s2Play, 0);
    AudioConnection          patchCord7(mixer2, 0, i2s2Play, 1);
    AudioControlSGTL5000     sgtl5000_1;     //xy=923,106
    // GUItool: end automatically generated code
    
    #define BUTTON_PIN 2
    #define LED_PIN 13
    Bounce change_fx = Bounce();
    
    elapsedMillis delayMillis;
    elapsedMillis delayControl;
    
    #define MAX_SAMPLES 128
    #define MAX_QUEUE_SIZE 8
    #define bufferSize 48000
    #define bias 512
    
    short FASTRUN buffer[bufferSize];
    short FASTRUN bufferIn[MAX_SAMPLES * MAX_QUEUE_SIZE];
    short FASTRUN bufferOut[MAX_SAMPLES * MAX_QUEUE_SIZE];
    int16_t queue_offset = 0, pointer = 0;
    volatile float volumeControl = 0, wet = 0, dry = 0;
    volatile int level = 0;
    byte switchEffect = 0;
    
    //Oscillators
    #define points 16383
    unsigned int FASTRUN modulation[points];
    
    //For Flange & Shifters++++++++++++++++++++
    #define MIN 2 //~60us distance
    #define MAX 400 //~ 8.5ms distance
    #define SIZE 400
    #define pitch 11700
    byte dir = 1;
    unsigned int utime = 0, offset = 0, increment = 0, divider = 0, distance = 0, fractional = 0x00;
    int speed = 0, sample = 0, time = 0;
    int32_t resultA = 0, resultB = 0, outputA = 0, outputB = 0;
    
    //Modulators & Wobbies+++++++++++++++++++++++++++
    #define space 350
    #define maximum 300
    unsigned int wave = bias;
    int modulation_in = 0;
    int FASTRUN AB[maximum];
    int32_t delay_line = 0, line_A = 0, line_B = 0, calculator = 0, fraction = 0;
    double down = -0.6, down1 = -0.98, down2 = -0.8;
    double up =  0.6, up1 = 0.98, up2 = 0.8;
    
    //Reverb+++++++++++++++++++++++++++++
    #define D1  4000
    #define D2  4000
    #define D3  4000
    #define D4  4000
    #define D5  10000
    #define D6  4000
    int  DV1 = 100;
    int  DV2 = 100;
    int  DV3 = 150;
    int  DV4 = 200;
    int  DV5 = 400;
    int  DV6 = 200;
    double  x1 = 0.69, x2 = 0.64, x3 = 0.59, x4 = 0.54;
    double  y_1 = 0.99 , y_2 = 0.94 , y_3 = 0.89 , y_4 = 0.84;
    short FASTRUN X1[D1];
    short FASTRUN X2[D2];
    short FASTRUN X3[D3];
    short FASTRUN X4[D4];
    short FASTRUN X5[D5];
    short FASTRUN X6[D6];
    double  S1 = 0, S2 = 0, S3 = 0, S4 = 0, S5 = 0, S6 = 0, S7 = 0;
    int32_t  DC1 = 0, DC2 = 0, DC3 = 0, DC4 = 0, DC5 = 0, DC6 = 1, DC7 = 1, DC8 = 0;
    
    // Multi ++++++++++++++++++++
    inline uint32_t M32x16(uint32_t x, uint32_t y) {
      return (uint32_t)(((uint32_t)x) * ((uint32_t)y) >> 16);
    }
    
    void setup() {
      Serial.begin(115200);
      AudioMemory(32);
      pinMode(14, INPUT_DISABLE);
      pinMode(15, INPUT_DISABLE);
      pinMode(16, INPUT_DISABLE);
      pinMode(17, INPUT_DISABLE);
      pinMode(22, INPUT_DISABLE);
      pinMode(BUTTON_PIN, INPUT_PULLUP);
      pinMode(LED_PIN, OUTPUT);
      change_fx.attach(BUTTON_PIN);
      change_fx.interval(15);
    
      modulation_oscillator();
    
      timer.begin(effect, 22.676);
      timer.priority(128);
      sgtl5000_1.enable();
      sgtl5000_1.volume(1.0);
      sgtl5000_1.inputSelect(AUDIO_INPUT_MIC);
      sgtl5000_1.micGain(25);
      //sgtl5000_1.lineInLevel(15);
      //sgtl5000_1.lineOutLevel(15);
    
      mixer1.gain(2, 0);
      mixer1.gain(3, 0);
      mixer2.gain(2, 0);
      mixer2.gain(3, 0);
    
      queuePlay.setBehaviour(AudioPlayQueue::NON_STALLING);
      queuePlay.setMaxBuffers(8);
      queueRecord.begin();
    
    }
    
    void modulation_oscillator() {
      for (int i = 0; i < points; i++)
        modulation[i] = (0.99 * cos(((2.0 * PI) / points) * i));
    }
    
    void i2s() {
      memcpy(&bufferIn[queue_offset], queueRecord.readBuffer(), 256);
      queueRecord.freeBuffer();
      int16_t *output = queuePlay.getBuffer();
      memcpy(output, &bufferOut[queue_offset] , 256);
      queue_offset += MAX_SAMPLES;
      while (queue_offset >= (MAX_SAMPLES * MAX_QUEUE_SIZE))  queue_offset = 0;
      queuePlay.playBuffer();
    }
    
    void loop() {
      while (delayControl >= 50) {
        delayControl = 0;
        mixer1.gain(0, volumeControl);
        mixer1.gain(1, volumeControl);
        mixer2.gain(0, wet);
        mixer2.gain(1, dry);
      }
    
      if (digitalRead(BUTTON_PIN) == LOW) {
        digitalWrite(LED_PIN, HIGH );
      } else digitalWrite(LED_PIN, LOW );
    }
    
    void effect() {
      while (queueRecord.available()) i2s();
      while (delayMillis >= 50) {
        delayMillis = 0;
        level = map(analogRead(A0), 0, 1023, 0, 1023);
        volumeControl = map(analogRead(A1), 0, 1023, 0, 1000);
        volumeControl = volumeControl / 1000.0;
        int val = map(analogRead(A2), 0, 1023, 0, 1000);
        wet = (float)val;
        wet = wet / 1000.0;
        dry = (float)map(val, 0, 1000, 10, 0);
        dry = dry / 10.0;
    
        change_fx.update();
        if (change_fx.rose()) {
          switchEffect = switchEffect + 1.0;
        }
      }
    
      if (switchEffect >= 6) switchEffect = 0;
    
      switch (switchEffect) {
        case 0:
          clean();
          break;
        case 1:
          ring_mod_fx();
          break;
        case 2:
          pitch_fx();
          break;
        case 3:
          reverb_fx();
          break;
        case 4:
          flange_fx();
          break;
        case 5:
          chorus_fx();
          break;
      }
    }
    
    void clean() {
      pointer++;
      while (pointer >= (MAX_SAMPLES * MAX_QUEUE_SIZE)) pointer = 0;
      bufferOut[pointer] = bufferIn[pointer];
    
    }
    
    void ring_mod_fx() {
      static long buffIn = bufferSize, buffOut = bufferSize - time;
    
      pointer++;
      while (pointer >= (MAX_SAMPLES * MAX_QUEUE_SIZE)) pointer = 0;
      time = map(level, 0, 1023, 330, 1);
      buffer[buffIn] = bufferIn[pointer];
      buffIn++;
      if (buffIn >= space) buffIn = 0;
      buffOut = buffIn + offset;
      if (buffOut >= space) buffOut -= space;
      bufferOut[pointer] = buffer[buffOut];
      if (dir) {
        if (offset >= (space - (unsigned int)time)) {
          dir = 0;
          offset--;
        }
        else offset++;
      }
      else {
        if (offset <= 4) {
          dir = 1;
          offset--;
        }
        else offset -= 1;
      }
    }
    
    void pitch_fx() {
      static unsigned int locationIn = SIZE, locationOut = SIZE - fractional;
    
      pointer++;
      while (pointer >= (MAX_SAMPLES * MAX_QUEUE_SIZE)) pointer = 0;
      buffer[locationIn] = bufferIn[pointer];
      locationIn++;
      if (locationIn >= SIZE) locationIn = 0;
      locationOut = locationIn + offset;
      if (locationOut >= SIZE) locationOut -= SIZE;
      outputA = buffer[locationOut];
      locationOut += (SIZE >> 1);
      if (locationOut >= SIZE) locationOut -= SIZE;
      outputB = buffer[locationOut];
      if (offset > (SIZE >> 1)) distance = SIZE - offset;
      else distance = offset;
      resultA = M32x16(outputA, (distance << 7));
      resultB = M32x16(outputB, (((SIZE >> 1) - distance) << 7));
      bufferOut[pointer] = resultA += resultB;
      if (level > bias) {
        fractional += map(level, 511, 1023, 0, 63);
        if (fractional >= 0x0080) {
          offset += (fractional >> 7);
          fractional &= 0x007f;
        }
        if (offset >= SIZE) offset -= SIZE;
      } else if (level < bias) {
        fractional += map(level, 0, 511, 63, 0);
        if (fractional >= 0x0080) {
          offset -= (fractional >> 7);
          fractional &= 0x007f;
        }
        if (offset >= SIZE) offset += SIZE;
      }
    }
    
    void reverb_fx() {
      pointer++;
      while (pointer >= (MAX_SAMPLES * MAX_QUEUE_SIZE)) pointer = 0;
    
      DV1 = map(level, 0, 1023, 100, 4000);
      DV2 = map(level, 0, 1023, 100, 4000);
      DV3 = map(level, 0, 1023, 150, 4000);
      DV4 = map(level, 0, 1023, 200, 4000);
      DV5 = map(level, 0, 1023, 400, 10000);
      DV6 = map(level, 0, 1023, 200, 4000);
    
      X1[DC1] = (bufferIn[pointer] + x1 * X1[DC1] / 1.2);
      X2[DC2] = (bufferIn[pointer] + x2 * X2[DC2] / 1.4);
      X3[DC3] = (bufferIn[pointer] * X3[DC3] / 1.6);
      X4[DC4] = (bufferIn[pointer] * X4[DC4] / 1.8);
    
      S1 =  y_1 * X1[DC1];
      S2 =  y_2 * X2[DC2];
      S3 =  y_3 * X3[DC3];
      S4 =  y_4 * X4[DC4];
    
      DC1++; if (DC1 >= DV1) DC1 = 0;
      DC2++; if (DC2 >= DV2) DC2 = 0;
      DC3++; if (DC3 >= DV3) DC3 = 0;
      DC4++; if (DC4 >= DV4) DC4 = 0;
    
      S5 = (S1 + S2 + S3 + S4) / 4;
      X5[DC7] = (S5 + x3 * X5[DC5]);
      S6 = -x3 * X5[DC7] + X5[DC5];
      DC5++; if (DC5 >= DV5) DC5 = 0;
      DC7++; if (DC7 >= D5) DC7 = 0;
      X6[DC8] = (S6 + x4 * X6[DC6]);
      S7 = (-x4 * X6[DC8] + X6[DC6]);
      DC6++; if (DC6 >= DV6) DC6 = 0;
      DC8++; if (DC8 >= D6) DC8 = 0;
      bufferOut[pointer] = (int16_t)S7;
    }
    
    void flange_fx() {
      static int locationIn = SIZE, locationOut = SIZE - fractional;
    
      pointer++;
      while (pointer >= (MAX_SAMPLES * MAX_QUEUE_SIZE)) pointer = 0;
      buffer[locationIn] = bufferIn[pointer];
      locationIn++;
      if (locationIn >= SIZE) locationIn = 0;
      locationOut = locationIn - (fractional >> 8);
      if (locationOut < 0) locationOut += SIZE;
      outputA = buffer[locationOut] + bufferIn[pointer];
      locationOut -= 1;
      if (locationOut < 0) locationOut += SIZE;
      outputB = buffer[locationOut] + bufferIn[pointer];
      resultA = M32x16(outputA, ((0xff - (fractional & 0x00ff)) << 7));
      resultB = M32x16(outputB, ((fractional & 0x00ff) << 7));
      bufferOut[pointer] = (resultA += resultB);
      int shift = level >> 6;
      if (shift >= 11) shift = 11;
      if (dir) {
        if ((fractional >> 8) >= MAX) dir = 0;
        fractional += (1 + shift);
      }
      else {
        if ((fractional >> 8) <= MIN) dir = 1;
        fractional -= (1 + shift);
      }
    }
    
    void chorus_fx() {
      pointer++;
      while (pointer >= (MAX_SAMPLES * MAX_QUEUE_SIZE)) pointer = 0;
      modulation_in = (2 + (level >> 3));
      delay_line = modulation_in / 2;
      for (int index = 0; index <= modulation_in; index++)
        AB[modulation_in + 1 - index] = AB[modulation_in - index];
      AB[0] = up * bufferIn[pointer] + down * AB[delay_line];
      line_A = delay_line - delay_line * modulation[calculator * 2];
      line_B =  int32_t(line_A);
      fraction = line_A - line_B;
      if (fraction == 0) fraction = 0.01;
      if (fraction == 1) fraction = 0.99;
      calculator++;
      if (calculator * 2 >= points) calculator = 0;
      bufferOut[pointer] = (int32_t)(AB[line_B + 1] * fraction + AB[line_B] * (1 - fraction));
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •