Odd interaction: AudioInputI2S, AudioSynthWaveform, AudioRecordQueue, AudioPlayQueue

kenjib

Member
I am having a weird issue with these four elements. Here is my audio design tool setup:

delayissue.png

The Teensy and audio shield are connected to and powered from my computer. A guitar is going into channel 1 of the mixer using the left line in feed on the audio shield. The synth stuff going in to channel 2 of the mixer is just a square wave set to turn on and off automatically by LFO. The effect2In and effect2Out parts go to my effects processing loop where I am applying a very simple 10000 sample long delay effect with no feedback. Here are the issues I'm noticing:

1. So right away there is a lot of noise on the line coming from the i2s input. I could probably use a pre-amp or something, but still this noise level is way above what I should normally expect. It sounds kind of like white noise with maybe a very faint high pitched whistling. This noise remains when I disconnect entirely from the audio in pins on the shield.
2. I hear the square wave playing regularly. I also hear the echo from the delay. However, I *also* hear a third very faint repeat of the sound as if there was a very small amount of feedback to the delay (which I don't see in my code). The timing of this faint echo changes when I change the delay time from 10,000 samples to something else -- i.e. it's always on time as a feedback delay.
3. If I remove the I2S input from the code, the faint extra echo on the synth goes away and the synth sound has just one echo like I would expect.

I am wondering if anyone else can verify whether or not it happens on their Teensy 4.1 + Audio Shield as well because this seems so strange to me that I am wondering if maybe my teensy and/or audio shield are damaged. Maybe I am just doing something wrong with the code though. Does anyone see anything? I'm pretty stumped here.

Here is the source code. I spent all day stripping it down to the bare minimum from a much larger codebase:

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioSynthWaveform       waveform2;      //xy=81,122
AudioSynthWaveformDc     dc1;            //xy=91,162
AudioSynthWaveform       waveform1;      //xy=214,76
AudioMixer4              mixer1;         //xy=234,142
AudioInputI2S            audioIn;        //xy=357,70
AudioEffectMultiply      multiply1;      //xy=367,114
AudioMixer4              synthMixer;     //xy=516,89
AudioRecordQueue         effect2In;      //xy=661,89
AudioPlayQueue           effect2Out;     //xy=787,88
AudioOutputI2S           audioOut;       //xy=927,87
AudioConnection          patchCord1(waveform2, 0, mixer1, 0);
AudioConnection          patchCord2(dc1, 0, mixer1, 1);
AudioConnection          patchCord3(waveform1, 0, multiply1, 0);
AudioConnection          patchCord4(mixer1, 0, multiply1, 1);
AudioConnection          patchCord5(audioIn, 0, synthMixer, 0);
AudioConnection          patchCord6(multiply1, 0, synthMixer, 1);
AudioConnection          patchCord7(synthMixer, effect2In);
AudioConnection          patchCord8(effect2Out, 0, audioOut, 1);
AudioConnection          patchCord9(effect2Out, 0, audioOut, 0);
AudioControlSGTL5000     sgtl5000_1;     //xy=752,135
// GUItool: end automatically generated code


int16_t delayBuffer[44100] = {};
int writeIndex = 0;
int readIndex = 34100;

void processAudioEngine() {
}

void setup() {
  AudioMemory(60);

  sgtl5000_1.enable();
  sgtl5000_1.volume(0.80);
  sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN);

  synthMixer.gain(0, 1.0);
  synthMixer.gain(1, 1.0);

  waveform1.begin(WAVEFORM_SQUARE);
  waveform1.amplitude(0.2);
  waveform1.frequency(100);

  waveform2.begin(WAVEFORM_PULSE);
  waveform2.amplitude(0.5);
  waveform2.frequency(0.6);
  waveform2.pulseWidth(0.1);

  dc1.amplitude(0.5);

  // Calls to AudioRecordQueue.being must always be last in this function to avoid latency.
  effect2In.begin();
}


void loop() {
  if (effect2In.available() >= 1) {
    while (effect2In.available() > 1) {
      effect2In.readBuffer();
      effect2In.freeBuffer();
    }
    int16_t *audioBuffer = effect2Out.getBuffer();
    memcpy(audioBuffer, effect2In.readBuffer(), 256);
    effect2In.freeBuffer();
    for (int i = 0; i < 128; i++) {
      int16_t nextSample = audioBuffer[i];
      delayBuffer[writeIndex] = nextSample;
      nextSample = nextSample + delayBuffer[readIndex];
      audioBuffer[i] = nextSample;
  
      readIndex++;
      if (readIndex >= 44100) {
        readIndex -= 44100;
      }
      writeIndex++;
      if (writeIndex >= 44100) {
        writeIndex -= 44100;
      }
    }
    effect2Out.playBuffer();
  }
}

Thanks in advance for any help!

-Kenji
 
Last edited:
Back
Top