Go Down

Topic: SOLVED:Arduino Due Delay Effect - Noisy playback *only* with variable delay time (Read 322 times) previous topic - next topic

Grumpy_Mike

Quote
Unfortunately, the running average didn't appear to help.
You could try a real average, take n samples and then create an average, then update your delay value. A running average will always reflect noise, if you are only using a few samples. 

kreiff

You could try a real average, take n samples and then create an average, then update your delay value. A running average will always reflect noise, if you are only using a few samples. 
YES!!!! That was it Mike!! The pot is just mega jittery.

Thank you! I ended up having to take an average of about 2000 samples - I may need to fine tune it more from here - but this works at least when the pot is static

Here is my code:
Code: [Select]

//Setup the ring buffer
#define BSIZE 20000 //Buffer size, sets the maximum delay time.
int ring_buff[BSIZE]; //Ring buffer

const int numReadings = 2000;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;

void setup() {
 
  //Initialize the buffer contents to all zero
  for (int i=0; i<BSIZE; i++){
    ring_buff[i] = 0;
  }

   for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
   }

  //Enable the ADC and DAC pins
  pinMode(A0, INPUT); // Define A0 as ADC input
  pinMode(A1, INPUT); // Define A1 as a multi-purpose Pot (currently used for testing variable delay times)
  analogReadResolution(12); //Override 10 bit default. We can go to 12 bits because the board used is a Due
  analogWriteResolution(12); //Override default 8 bit since we'll use DAC1 output on Due board

  //Open serial monitor transcript
  Serial.begin(115200);
  }

void loop() {
 
  int analogin; //stores ADC data
  float old_value1; // values read from the tap point
  int analogout; //value to be output and stored into buffer at current_tap
  int analogout_buf; //duplicate of analogue out taken before effect mix attenuation
  int current_tap = 0; //The current tap point - incremented after each sample
  int tap; //Temp variable used in indexing into older tap points
  byte effectMix; // variable for setting the effect vs. input mix
  int delayTime; // sets delay time

  //While loop to improve effect timing
  while (1) {

    total = total - readings[readIndex];
    // read from the sensor:
    readings[readIndex] = analogRead(A1);
    // add the reading to the total:
    total = total + readings[readIndex];
    // advance to the next position in the array:
    readIndex = readIndex + 1;

    // if we're at the end of the array...
    if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }

  // calculate the average:
    average = total / numReadings;
    analogin = analogRead(A0) - 2048; //Making audio values bi-polar

    delayMicroseconds(20);
   
    effectMix = 0; //map(analogRead(2), 0, 4095, 0, 8);
    delayTime = map(average, 0, 4095, 1,20000); //sets delay time, mapped usable values between 900 - 20000

    tap = current_tap - delayTime; // sets temp tap value and grabs values earlier in the ring buffer
    if (tap < 0){                  //if tap is negative number, pushes it back to the top of the ring buffer
      tap += BSIZE;
    }
    old_value1 = ring_buff[tap];   //grabs delayed audio for playback
   
    //Scale values by a specfic divisor to determine feedback amount
    old_value1 /= 2;

    analogout_buf =  analogin + old_value1; //add passthrough audio from ADC to scaled delayed audio

    //Limit the outputs to mimic normal overload distortion
    //avoid digital number wraparound - might not be needed for the buffer?
    if(analogout_buf > 2047){ analogout_buf = 2047;}
    if(analogout_buf < -2047){ analogout_buf = -2047;}
   
    //Effect Level for repeats (i.e. turn down input signal)
    //analogin = analogin >> effectMix; //commented out for testing
   
    analogout = analogin + old_value1; //add passthrough audio from ADC to scaled delayed audio
   
    //Limit the outputs to mimic normal overload distortion
    //avoid digital number wraparound
    if(analogout > 2047){ analogout = 2047;}
    if(analogout < -2047){ analogout = -2047;}
   
    //store duplicated output in buffer for "effect only" playback
    ring_buff[current_tap] = analogout_buf;
   
    //increment (circular) tap-point
    current_tap++;
    if(current_tap > BSIZE-1){ //if tap point goes beyond BSIZE, start back at 0
      current_tap = 0;
    }
   
    //Scale the value back to an unsigned value in preparation for output to DAC
    analogout += 2048;
   
    //Write to DAC1 output pin on Due board
    analogWrite(DAC0, analogout);

   }
}

Go Up