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

Thread: Delay: Longer timing? And crunchy sound in feedback loop?

  1. #1
    Junior Member
    Join Date
    Apr 2018
    Posts
    12

    Delay: Longer timing? And crunchy sound in feedback loop?

    Hey everyone,

    So I have my project working well, except I should be using a Teensy 3.6 because I need longer delay times.

    Is there any way to expand the length of the delay on a 3.2 or is it totally dependant on memory rather than timing?

    Also another issue that I have is that there's a crunchy sound that builds in the feedback loop.
    I've attached a sample of it here:

    AUDIO SAMPLE

    And here is the code that i'm using.

    Code:
    // GUItool: begin automatically generated code
    AudioSynthWaveformSine   sine1;          //xy=165,457
    AudioSynthWaveformSine   sine2;          //xy=186,530
    AudioSynthWaveformModulated waveformMod1;   //xy=283,320
    AudioEffectEnvelope      envelope1;      //xy=480,328
    AudioEffectDelay         delay1;         //xy=541,571
    AudioMixer4              mixer1;         //xy=577,446
    AudioOutputI2S           i2s1;           //xy=726,694
    AudioConnection          patchCord1(sine1, 0, waveformMod1, 0);
    AudioConnection          patchCord2(sine1, 0, mixer1, 3);
    AudioConnection          patchCord3(sine2, 0, waveformMod1, 1);
    AudioConnection          patchCord4(waveformMod1, envelope1);
    AudioConnection          patchCord5(envelope1, 0, mixer1, 0);
    AudioConnection          patchCord6(delay1, 0, mixer1, 1);
    AudioConnection          patchCord7(mixer1, 0, i2s1, 0);
    AudioConnection          patchCord8(mixer1, delay1);
    AudioConnection          patchCord9(mixer1, 0, i2s1, 1);
    AudioControlSGTL5000     sgtl5000_1;     //xy=333,784
    // GUItool: end automatically generated code
    
    
    void setup() {
      Serial.begin(9600);
      pinMode(0, INPUT_PULLUP);
      pinMode(1, INPUT_PULLUP);
      pinMode(2, INPUT_PULLUP);
    
      delay(300);
      Serial.println("Siren");
      
      // Audio connections
      AudioMemory(160);
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.5);
    
      // Configure sine waves
      waveformMod1.frequency(261.63);
      waveformMod1.amplitude(1.0);
      sine1.frequency(20.3); // Sine waves are low frequency oscillators (LFO)
      sine2.frequency(1.2);
    
      current_waveform = WAVEFORM_SINE;
      waveformMod1.begin(current_waveform);
    
      // delay setup
      mixer1.gain(0, 0.5);
      mixer1.gain(1, 0.7);
      delay1.delay(0, 400);
    
      // envelope setup
      envelope1.attack(200);
      envelope1.decay(200);
    
      // drum setup
    //  drum1.frequency(1000);
    //  drum1.length(350);
      
    }

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,582
    Longer audio delay requires more memory.

    There is support for a SPI RAM chip, using the delayExt object. That involves quite a lot of extra overhead for the SPI communication, but it works quite well if you're not short on CPU time.

  3. #3
    Junior Member
    Join Date
    Apr 2018
    Posts
    12
    Yeah probably just easier to switch out the Teensy.

    Did you have a chance to listen to the crunchy sound problem in the feedback loop?

  4. #4
    Senior Member
    Join Date
    Apr 2014
    Posts
    318
    I am not sure what you want out of this, but you have it printing "Siren" so I assume a siren sound sound.
    I was only trying it on a 3.2 and I dont have an I2S amp connected so changed it to DAC and modified or simplified it a bit so it sounds a bit like a siren and definitely not chrunchy, below is the code and attached is screen dupm from Audacity recording, I it a 200 Hz wave modulated and output through an envelope to switch it on an off repeatedly.....you can fiddle with all the parameters and see what happens

    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    
    // GUItool: begin automatically generated code
    AudioSynthWaveformSine   sine1;          //xy=165,457
    AudioSynthWaveformSine   sine2;          //xy=186,530
    AudioEffectEnvelope      envelope1;      //xy=480,328
    AudioSynthWaveformModulated waveformMod1;   //xy=283,320
    AudioMixer4              mixer1;         //xy=502,193
    AudioMixer4              mixer2;         //xy=502,193
    AudioEffectDelay         delay1;         //xy=514,434
    AudioOutputAnalog           dac1;           //xy=726,694
    AudioConnection          patchCord1(sine1, 0, waveformMod1, 0);
    AudioConnection          patchCord3(sine2, 0, waveformMod1, 1);
    AudioConnection          patchCord6(waveformMod1, 0, envelope1, 0);
    AudioConnection          patchCord5(envelope1, 0, dac1, 0);
    AudioControlSGTL5000     sgtl5000_1;     //xy=333,784
    // GUItool: end automatically generated code
    
    
    void setup() {
      Serial.begin(9600);
      pinMode(0, INPUT_PULLUP);
      pinMode(1, INPUT_PULLUP);
      pinMode(2, INPUT_PULLUP);
    
      delay(300);
      Serial.println("Siren");
      
      // Audio connections
      AudioMemory(160);
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.5);
    
      // Configure sine waves
      waveformMod1.frequency(261.63);
      waveformMod1.amplitude(1.0);
      sine1.frequency(2.3); // Sine waves are low frequency oscillators (LFO)
      sine2.frequency(1.2);
    
     // current_waveform = WAVEFORM_SINE;
     // waveformMod1.begin(current_waveform);
    
     waveformMod1.begin(WAVEFORM_SINE);
    
      // delay setup
      mixer1.gain(0, 0.5);
      mixer1.gain(1, 0.7);
      delay1.delay(0, 400);
    
      // envelope setup
      envelope1.attack(200);
      envelope1.sustain(1.0);
      envelope1.decay(200);
    
      // drum setup
    //  drum1.frequency(1000);
    //  drum1.length(350);
      
    }
    
    
    
    void loop() {
      // put your main code here, to run repeatedly:
    envelope1.noteOn();
    
    delay(2000);
    
    envelope1.noteOff();
    
    delay(2000);
    
    
    }
    Click image for larger version. 

Name:	Siren1.JPG 
Views:	37 
Size:	59.5 KB 
ID:	13577

  5. #5
    Junior Member
    Join Date
    Apr 2018
    Posts
    12
    Quote Originally Posted by Teenfor3 View Post
    I am not sure what you want out of this, but you have it printing "Siren" so I assume a siren sound sound.
    I was only trying it on a 3.2 and I dont have an I2S amp connected so changed it to DAC and modified or simplified it a bit so it sounds a bit like a siren and definitely not chrunchy, below is the code and attached is screen dupm from Audacity recording, I it a 200 Hz wave modulated and output through an envelope to switch it on an off repeatedly.....you can fiddle with all the parameters and see what happens
    Mmmm I think you've missed what's going on here. What i'm looking for is a clean sound regardless of what it is thats put into the delay and feedback.

    The Crunchy sound arrises from the delay + feedback loop, which you have removed from your sketch.

  6. #6
    Junior Member
    Join Date
    Apr 2018
    Posts
    12
    Teenfor3: Try this and you'll hear the crunchyness on the overlap.

    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioSynthWaveformSine   sine1;          //xy=164.2857208251953,556.857177734375
    AudioSynthWaveformSine   sine2;          //xy=185.2857208251953,629.857177734375
    AudioSynthWaveformModulated waveformMod1;   //xy=282.2857208251953,419.857177734375
    AudioMixer4              mixer1;         //xy=445.5714454650879,532.8571338653564
    AudioEffectDelay         delay1;         //xy=471.85709381103516,693.8571701049805
    AudioEffectEnvelope      envelope1;      //xy=479.2857208251953,427.857177734375
    AudioOutputI2S           i2s1;           //xy=737.142822265625,587.1428451538086
    AudioConnection          patchCord1(sine1, 0, waveformMod1, 0);
    AudioConnection          patchCord2(sine2, 0, waveformMod1, 1);
    AudioConnection          patchCord3(waveformMod1, envelope1);
    AudioConnection          patchCord4(mixer1, delay1);
    AudioConnection          patchCord5(mixer1, 0, i2s1, 0);
    AudioConnection          patchCord6(mixer1, 0, i2s1, 1);
    AudioConnection          patchCord7(delay1, 0, mixer1, 1);
    AudioConnection          patchCord8(envelope1, 0, mixer1, 0);
    AudioControlSGTL5000     sgtl5000_1;     //xy=332.2857208251953,883.857177734375
    // GUItool: end automatically generated code
    
    
    void setup() {
      Serial.begin(9600);
      pinMode(0, INPUT_PULLUP);
      pinMode(1, INPUT_PULLUP);
      pinMode(2, INPUT_PULLUP);
    
      delay(300);
      Serial.println("Siren");
      
      // Audio connections
      AudioMemory(160);
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.5);
    
      // Configure sine waves
      waveformMod1.frequency(261.63);
      waveformMod1.amplitude(1.0);
      sine1.frequency(2.3); // Sine waves are low frequency oscillators (LFO)
      sine2.frequency(1.2);
    
     // current_waveform = WAVEFORM_SINE;
     // waveformMod1.begin(current_waveform);
    
     waveformMod1.begin(WAVEFORM_SINE);
    
      // delay setup
      mixer1.gain(0, 0.5);
      mixer1.gain(1, 0.7);
      delay1.delay(0, 400);
    
      // envelope setup
      envelope1.attack(200);
      envelope1.sustain(1.0);
      envelope1.decay(200);
    
      // drum setup
    //  drum1.frequency(1000);
    //  drum1.length(350);
      
    }
    
    
    
    void loop() {
      // put your main code here, to run repeatedly:
    envelope1.noteOn();
    
    delay(2000);
    
    envelope1.noteOff();
    
    delay(2000);
    
    
    }

  7. #7
    Senior Member
    Join Date
    Apr 2014
    Posts
    318
    Yes the sketch runs for me, OK, I am not sure if it is distortion or just gain of signal too high when the signals feedback signal is looped. I run it open loop as well and you can see the wave forms from each delayed by the amount set. If you want more delay add 2 delays in series......dont know what you want what are you expecting to get......did you do any sums. I reduced the gain on the delay mix input......and not as harsh a sound and looks more like modulated....post what you are expecting to get out.

  8. #8
    Junior Member
    Join Date
    Apr 2018
    Posts
    12
    Quote Originally Posted by Teenfor3 View Post
    Yes the sketch runs for me, OK, I am not sure if it is distortion or just gain of signal too high when the signals feedback signal is looped. I run it open loop as well and you can see the wave forms from each delayed by the amount set. If you want more delay add 2 delays in series......dont know what you want what are you expecting to get......did you do any sums. I reduced the gain on the delay mix input......and not as harsh a sound and looks more like modulated....post what you are expecting to get out.
    I worked it out, it was some additional code I had written to update the delay time to an analog input. It was where I placed the code that was causing problems.

    Iíll post a sketch for others to be able to replicate the problem for anyone else who might encounter it

  9. #9
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    Location
    Canada
    Posts
    227
    When I was developing my AnalogDelay effect, I wanted to get long delays, without using up all of the valuable Teensy RAM, so I did what Paul suggested above, I used external SPI RAM.

    However, as Paul mentioned that the SPI uses up quite a bit of CPU time, so I modified crteensy's DmaSpi library to work with SPI RAM. Once I switched to using DMA for audio delay transfers, I got the best of both worlds, long delays and low CPU load.

    In the end, I created a general purpose AudioDelay class that I can use for either internal or external delay. When external, it uses a class called ExternalSramManager that treats the external SRAM as a pool you request blocks from then pass it to the AudioDelay class for sue. The manager provides the option to use DMA for data transfers.

    If you're interested, you can find a reference to my AudioDelay class here on Github.

  10. #10
    Junior Member
    Join Date
    Apr 2018
    Posts
    12
    @Blackaddr Oh that sounds good. Actually I think I came across some alternative Delay effects the other day but couldnít find them again?

    Is there an example sketch that shows the usage for your AudioDelay class?

    Iím thinking it could be easier to just swap my 3.2 out for a 3.6, but now iím concerned that just doing that will increase my CPU load? Or do you think that wonít make a difference?

  11. #11
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    Location
    Canada
    Posts
    227
    Quote Originally Posted by botoxparty View Post
    @Blackaddr Oh that sounds good. Actually I think I came across some alternative Delay effects the other day but couldn’t find them again?

    Is there an example sketch that shows the usage for your AudioDelay class?

    I’m thinking it could be easier to just swap my 3.2 out for a 3.6, but now i’m concerned that just doing that will increase my CPU load? Or do you think that won’t make a difference?
    I like to recommend to people do the easiest thing first (less debugging!) then get more advanced when the easy route isn't good enough. That said, hardware costs money and your time is (usually) free. If the T3.6 is going to do everything you need in terms of RAM/CPU, just buy one if the cost is reasonable to you.

    Depending on how comfortable you are with C++, adding a SPI RAM and using DMA will let you do more with less hardware, but expect more learning and debugging required.

    A word of warning, my BAGuitary library a framework I'm building to have lots of reusable classes to make it easy to build a variety of effects. That said, in order to make it 'easy' to build effects, the underling library framework is complex though I've been trying to use dOxygen to document all the APIs. It's designed with this board here, so you may need to modify some code if your pinouts for SPI RAM would be different.

    If you're still interested, start looking here, which is a demo INO for the AudioEffectAnalogDelay object. The demo and sub-components use a variety of classes, here's a brief summary, the details you can get from examining code:

    demo:
    - AudioEffectAnalogDelay - an Audio library compatible effect that simulates a BBD delay pedal (connect to/from with AudioConnections)
    - ExternalSramManager - a memory pool manager for requesting memory 'slots' or blocks from the memory device.
    - ExtMemSlot - an object that provides an easy read/write interface to external SPI memory handled by the SRAM manager.

    Some BAGuitar classes used under the hood:
    - AudioDelay - a general purpose audio delay class for use WITHIN a Teensy Audio effect class, it CANNOT be directly connected to via AudioConnection patch signals. Supports internal RAM, or external RAM using an ExtMemSlot
    - BASpiMemoryDMA - a class providing SPI level read/write access to an external SRAM device. Used by ExtMemSLot.

  12. #12
    Senior Member
    Join Date
    Apr 2014
    Posts
    318
    I think the delay as the feedback in your sketch is causing it to oscillate...????? there is a high frequency which look random ontop of the wave and doesn't cause much noise if the gain of the mixer is low.....I modified the sketch to add the direct mod signal to the delayed mod signal and play them out over I2s to the audio board headphone socket as you sketch and I think it works better......but maybe not what you want......I can now fiddle with the settings gains and frequencies and get all sorts of shapes and sounds...attached is screen dump from audacity of it running slow as per the settings in the sketchsketch Click image for larger version. 

Name:	SirenModDelayMix.JPG 
Views:	41 
Size:	96.3 KB 
ID:	13584

    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioSynthWaveformSine   sine1;          //xy=164.2857208251953,556.857177734375
    AudioSynthWaveformSine   sine2;          //xy=185.2857208251953,629.857177734375
    AudioSynthWaveformModulated waveformMod1;   //xy=282.2857208251953,419.857177734375
    AudioMixer4              mixer1;         //xy=445.5714454650879,532.8571338653564
    AudioEffectDelay         delay1;         //xy=471.85709381103516,693.8571701049805
    //AudioEffectDelay         delay2;         //xy=471.85709381103516,693.8571701049805
    //AudioEffectEnvelope      envelope1;      //xy=479.2857208251953,427.857177734375
    AudioOutputI2S           i2s1;           //xy=737.142822265625,587.1428451538086
    AudioConnection          patchCord1(sine1, 0, waveformMod1, 0);
    AudioConnection          patchCord2(sine2, 0, waveformMod1, 1);
    AudioConnection          patchCord3(waveformMod1, delay1);
    AudioConnection          patchCord4(delay1, 0, mixer1, 0);
    AudioConnection          patchCord5(waveformMod1, 0, mixer1, 1);
    AudioConnection          patchCord6(mixer1, 0, i2s1, 0);
    AudioConnection          patchCord7(mixer1, 0, i2s1, 1);
    // AudioConnection          patchCord7(delay1, 0, delay2, 0);
    //AudioConnection          patchCord9(delay1, 0, mixer1, 1);
    //AudioConnection          patchCord8(envelope1, 0, mixer1, 0);
    AudioControlSGTL5000     sgtl5000_1;     //xy=332.2857208251953,883.857177734375
    // GUItool: end automatically generated code
    
    
    void setup() {
      Serial.begin(9600);
    //  pinMode(0, INPUT_PULLUP);
    //  pinMode(1, INPUT_PULLUP);
    //  pinMode(2, INPUT_PULLUP);
    
      delay(300);
      Serial.println("Siren");
      
      // Audio connections
      AudioMemory(160);
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.5);
    
      // Configure sine waves
      waveformMod1.frequency(261.63);
      waveformMod1.amplitude(0.8);
      sine1.frequency(0.1); // Sine waves are low frequency oscillators (LFO)
      sine2.frequency(1.0);
    
     // current_waveform = WAVEFORM_SINE;
     // waveformMod1.begin(current_waveform);
    
     waveformMod1.begin(WAVEFORM_SINE);
    
      // delay setup
      mixer1.gain(0,  0.4);
      mixer1.gain(1, 0.4);
     // mixer1.gain(2,  0.0);
      delay1.delay(0, 10);
     // delay2.delay(0, 100);
      
      // envelope setup
     // envelope1.attack(800);
      //envelope1.sustain(0.8);
     // envelope1.decay(800);
    
      // drum setup
    //  drum1.frequency(1000);
    //  drum1.length(350);
      
    }
    
    
    
    void loop() {
      // put your main code here, to run repeatedly:
    // envelope1.noteOn();
    
    // delay(6000);
    
    //while(true);
    
    // envelope1.noteOff();
    
    //delay(2000);
    
    }

  13. #13
    Junior Member
    Join Date
    Sep 2019
    Posts
    4
    Hi Botoxparty,

    I think I have been encountering the same problem--i get a crunchyness when I change the delay rate. Care to post the sketch to your solution?

    This is my first, teensy project. I just need a simple delay that doesn't clip when I change the delay speed. I've mostly used the format from the feedback delay tutorial.

    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioInputI2S            i2s1;           //xy=127,95
    AudioMixer4              mixer1;         //xy=304,177
    AudioEffectDelay         delay1;         //xy=418,382
    AudioMixer4              mixer2;         //xy=516,125
    AudioOutputI2S           i2s2;           //xy=684,200
    AudioConnection          patchCord1(i2s1, 0, mixer1, 0);
    AudioConnection          patchCord2(i2s1, 0, mixer2, 0);
    AudioConnection          patchCord3(mixer1, delay1);
    AudioConnection          patchCord4(mixer1, 0, mixer2, 3);
    AudioConnection          patchCord5(delay1, 0, mixer1, 3);
    AudioConnection          patchCord6(mixer2, 0, i2s2, 0);
    AudioConnection          patchCord7(mixer2, 0, i2s2, 1);
    AudioControlSGTL5000     sgtl5000_1;     //xy=142,325
    // GUItool: end automatically generated code
    
    void setup() {
      Serial.begin(9600);
      pinMode(0, INPUT_PULLUP);
      AudioMemory(850);
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.4);
      sgtl5000_1.inputSelect(AUDIO_INPUT_MIC);
      sgtl5000_1.micGain(40);
      mixer1.gain(0, 0.5);
      mixer1.gain(3, 0.5);
      mixer2.gain(0, 0.5);
      mixer2.gain(3, 0.5);
      delay1.delay(0, 500);
      delay(100);
    }
    
    void loop() {
      // uncomment for A1 knob to control the feedback level
     
      int knob = analogRead(A1);
      float feedback = (float)(knob + 100) / 1050.0;
      mixer1.gain(3, feedback);
    
      int knob2 = analogRead(A2);
      float delayrate = (float)(knob2 / 1050.0) * 1500;
      delay1.delay(0, delayrate);
    Cheers,

  14. #14
    The crunchyness is possibly caused by just as little as one sample going too high (positive or negative) and wrapping round. Once this gets into any filter the filter usually gets confused and struggles to recover. Try turning the level down by 6dB and see if the same happens.

  15. #15
    Junior Member
    Join Date
    Sep 2019
    Posts
    4
    Quote Originally Posted by MikeDB View Post
    The crunchyness is possibly caused by just as little as one sample going too high (positive or negative) and wrapping round. Once this gets into any filter the filter usually gets confused and struggles to recover. Try turning the level down by 6dB and see if the same happens.
    Thanks for the advice. I tried reducing the gain--from the mic, and from the delay into the mixer--and the output volume, unfortunately it has made no difference. I added a filter which softens the distortion but it is still occurring. I'm only getting distortion when I change the delay rate with an analog input to a value less than the maximum (which in this case I have set at 800ms). Without experience behind me, I just don't know if it is the software or the hardware... I'm using the memory from the Teensy 3.5 for the audio delay.

  16. #16
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    Location
    Canada
    Posts
    227
    Quote Originally Posted by Minch View Post
    Thanks for the advice. I tried reducing the gain--from the mic, and from the delay into the mixer--and the output volume, unfortunately it has made no difference. I added a filter which softens the distortion but it is still occurring. I'm only getting distortion when I change the delay rate with an analog input to a value less than the maximum (which in this case I have set at 800ms). Without experience behind me, I just don't know if it is the software or the hardware... I'm using the memory from the Teensy 3.5 for the audio delay.
    You can get distortion when adjusting the delay because you are violating the Nyquist rate. It only occurs when changing the delay value?

    If so, this can happen because Nyquist sets a limit on how much change in magnitude can occur from sample to sample. When you change the delay, the "next" sample is taken from a different point in the delay line where teh signal jump exceeds Nyquist limit. So as you change the delay, you'll get some pitch modulation effect as well as some sample aliasing.

    You've got it connected to an analog pot right? Try turning it very slowly. You may find there is a speed at which you turn the knob that the distortion occurs.

  17. #17
    Junior Member
    Join Date
    Sep 2019
    Posts
    4
    I had pondered that something like the Nyquist rate could be the cause. Thanks for teaching me that. It is an analog pot. I tried turning it slower (really really slow) but found no difference in result. What is peculiar is, if I have the pot at any other position than all the way to the right, I will get on the distortion on the delay.

  18. #18
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    Location
    Canada
    Posts
    227
    Quote Originally Posted by Minch View Post
    I had pondered that something like the Nyquist rate could be the cause. Thanks for teaching me that. It is an analog pot. I tried turning it slower (really really slow) but found no difference in result. What is peculiar is, if I have the pot at any other position than all the way to the right, I will get on the distortion on the delay.
    Even with the pot not moving, the analog read value will still be jumping around a lot due to noise, which is the same as twitching the knob back and forth randomly at high speed. Are you filtering the pot values? A simple IIR filter will smooth that out since you are dealing with long timescales.

    Try adding something this in your code, see if it improves it:
    Code:
    // in your global variables
    float previousValue = 0.0f;
    // It will take about 100 reads to transition from the old value to the new pot value at 0.99.
    // Set this as close to 1.0f as possible but still feel like the delay knob has good feel. E.g. 0.999f, 0.9999f if necessary.
    const float ALPHA = 0.99f;
    
    // ... in your loop or function to get new pot value and update delay
    // update the pot value
    int rawValue = analogRead(POT_PIN);
    float filteredValue = (ALPHA * previousValue) + (1.0f - ALPHA)*((float)rawValue);
    updateDelay(newValue); // update the delay value based on the filter pot position.
    previousValue = filteredValue; the new value becomes the old value to use next time the code is called
    // ...

  19. #19
    Senior Member
    Join Date
    Apr 2014
    Posts
    318
    Hi Minch.....Just noticed you have AudioMemory(850); .....Probably far too big a number......try AudioMemory(50); instead.
    I dont have a i2s source setup as input so cannot try it out now without setting up......

    Try your sketch with a sine wave input and dac output and see if you have same problems first...it will be simpler for anyone to try out and test and test.

    PS I see your delay is 500 ms .....500 / 2.9 = 170 mem blocks approx plus 50 blocks connections gives 220 blocks
    So maybe AudioMemory(220); might be better....????
    Last edited by Teenfor3; 09-03-2019 at 02:53 PM.

  20. #20
    Junior Member
    Join Date
    Sep 2019
    Posts
    4
    Hi Blackaddr,

    Thanks for the help. So I tried that out, it did address the problem of the distortion when the pan pot is idle anywhere but at max. But there is still some distortion when the knob is changed.

    Teenfor3,

    Thanks. I have played around with the AudioMemory and saw no difference. At 850 my Teensy still had another 22% of memory left.

    --

    I have been talking to a guy from youtube, who has a teensy delay pedal that seems to do what I want mine to do. He said he encountered a similar problem and found a work around. I don't know what it is... so I just have to convince him to let me see his sketch.

    https://www.youtube.com/watch?v=FQJq...AKjNwy&index=8

  21. #21
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    Location
    Canada
    Posts
    227
    Quote Originally Posted by Minch View Post
    Hi Blackaddr,
    Thanks for the help. So I tried that out, it did address the problem of the distortion when the pan pot is idle anywhere but at max. But there is still some distortion when the knob is changed.
    Two possibilities:

    #1 When you adjust delay, you are still jumping between discrete delay times (resolution 1/44100 seconds) which in itself causes aliasing. When people design chorus/flanger pedals an LFO is automatically "turning the knob" for them. This creates artifacts as jumping between discrete delays violates Nyquist so you must have the instantaneous delay linearly interpolated as the output BETWEEN two audio samples. Delay thus becomes continuous instead of quantized. For delay pedals most people don't care about artifacts when the knob is turning, only when it's not turning should it be error free. But that's up to you.

    #2 The delay rate is still just generally changing too darn fast when you turn the knob.

    Adding the basic filter accounted for how fast it changes due to noise when still so the delay value isn't jumping around, but when you turn your knob your filter still isn't enough to limit the rate to prevent Nyquist aliasing.

    Perhaps you need another mechanism to deal with when the knob is turning. Try slewing from a tracked pot position to the desired position to control how fast it moves from current to desired. Here's some psuedo code to illustrate the idea.

    Code:
    const float MAX_POSITION_CHANGE = 0.0001f; // Set this as small as possible while still feeling that the knob is generally responsive, not too laggy
    const float trackingPotPosition;
    // ...
    // Inside code that reads the pot and updates the delay parameter.
    float currentPotPosition = (float)analogRead(POT_PIN); // Get the current position
    float potPositionDelta = currentPotPosition - trackingPotPosition; // this is the difference between tracking position and the instantaneous position. Can be positive or negative.
    
    if (abs(potPositionDelta) > MAX_POSITION_CHANGE) {
        // adjust up or down
        if (potPositionDelta > 0.0f) {
          trackingPotPosition += MAX_POSITION_CHANGE;
        } else {
          trackingPotPosition -= MAX_POSITION_CHANGE;
        }
    }

Posting Permissions

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