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

Thread: Teensy 4.0 FFT and AUDIO_INPUT_LINEIN

  1. #1
    Junior Member
    Join Date
    Dec 2021
    Posts
    7

    Teensy 4.0 FFT and AUDIO_INPUT_LINEIN

    Hi all,
    I'm winding down a vast synth project and thought it would be an easy thing to mix in line audio input when the time came. Turns out that isn't as easy as I thought and the trouble boiled down to the audio adapter FFT library I was using- all of it works fine but as long as I'm using FFT, AUDIO_INPUT_LINEIN simply draws a blank...

    Try it with the FFT and PeakAndRMSMeterStereo examples in Teensyduino 1.55- the FFT draws blanks while the RMS meter shows audio input levels... I just updated teensyduino to 1.55 and the issue persists. PassThroughStereo works fine as well.

    ...am I missing something?

    Any guidance is appreciated.

  2. #2
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,450
    Can you post the code that shows the problem?

  3. #3
    Junior Member
    Join Date
    Dec 2021
    Posts
    7
    It's the built-in example:

    // FFT Test
    //
    // Compute a 1024 point Fast Fourier Transform (spectrum analysis)
    // on audio connected to the Left Line-In pin. By changing code,
    // a synthetic sine wave can be input instead.
    //
    // The first 40 (of 512) frequency analysis bins are printed to
    // the Arduino Serial Monitor. Viewing the raw data can help you
    // understand how the FFT works and what results to expect when
    // using the data to control LEDs, motors, or other fun things!
    //
    // This example code is in the public domain.

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

    const int myInput = AUDIO_INPUT_LINEIN;
    //const int myInput = AUDIO_INPUT_MIC;

    // Create the Audio components. These should be created in the
    // order data flows, inputs/sources -> processing -> outputs
    //
    AudioInputI2S audioInput; // audio shield: mic or line-in
    AudioSynthWaveformSine sinewave;
    AudioAnalyzeFFT1024 myFFT;
    AudioOutputI2S audioOutput; // audio shield: headphones & line-out

    // Connect either the live input or synthesized sine wave
    AudioConnection patchCord1(audioInput, 0, myFFT, 0);
    //AudioConnection patchCord1(sinewave, 0, myFFT, 0);

    AudioControlSGTL5000 audioShield;

    void setup() {
    // Audio connections require memory to work. For more
    // detailed information, see the MemoryAndCpuUsage example
    AudioMemory(12);

    // Enable the audio shield and set the output volume.
    audioShield.enable();
    audioShield.inputSelect(myInput);
    audioShield.volume(0.5);

    // Configure the window algorithm to use
    myFFT.windowFunction(AudioWindowHanning1024);
    //myFFT.windowFunction(NULL);

    // Create a synthetic sine wave, for testing
    // To use this, edit the connections above
    sinewave.amplitude(0.8);
    sinewave.frequency(1034.007);
    }

    void loop() {
    float n;
    int i;

    if (myFFT.available()) {
    // each time new FFT data is available
    // print it all to the Arduino Serial Monitor
    Serial.print("FFT: ");
    for (i=0; i<40; i++) {
    n = myFFT.read(i);
    if (n >= 0.01) {
    Serial.print(n);
    Serial.print(" ");
    } else {
    Serial.print(" - "); // don't print "0.00"
    }
    }
    Serial.println();
    }
    }

  4. #4
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,450
    Code:
    AudioConnection patchCord1(audioInput, 0, myFFT, 0);
    That only looks at the left channel - perhaps you only have the right channel with a signal?

    BTW Code tags (the # button) are used for posting code so that formatting is not lost and a fixed-width font is employed.

  5. #5
    Junior Member
    Join Date
    Dec 2021
    Posts
    7
    Thank you Mark, I'm a longtime member but have been living problem free for long enough that I forgot my credentials as well as the code tags...
    I'm feeding my system with a stereo signal so both audio channels have signal... the PeakAndRMSMeterStereo and PassThroughStereo examples work fine; the FFT example runs but shows no input, even if I expand the serial printout to 4 digits.

    My synth code is too complex to post here (uses tabs in teensyduino for organization) but uses fastLED and FFT for visualization. This all works fine, it's just impossible to get AUDIO_INPUT_LINEIN working with it. I'm thinking of reworking the visualizer to use RMS values instead but the FFT just looks so good and helps with troubleshooting.

  6. #6
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,450
    You have connected to the right pads? There are both line output and line input pads on the Audio adapter. I suppose
    this must be right for the rms meter to work.

    You are inputing line level signals, not microphone level?

  7. #7
    Junior Member
    Join Date
    Dec 2021
    Posts
    7
    Correct- I always suspect my wiring but the fact that the same system works fine using the PeakAndRMSMeterStereo and PassThroughStereo examples tells me the issue is somewhere else. I'm also using line out so I will have to test that as well when I get through this issue.

  8. #8
    Junior Member
    Join Date
    Dec 2021
    Posts
    7
    FWIW here's my FFT visualizer code which works great for the 7 large indicator lamps I rewired with neopixel 5mm LEDs (the first LED acts as a logic level shifter, so 8 LEDs but only displaying on 7)... I'm thinking about rebuilding the synth from the design tool to include RMS instead of FFT because FFT just doesn't work with AUDIO_INPUT_LINEIN

    For the LEDs use WS2812Serial.h

    Code:
    void displayLEDs()
    {
      if (fft1024_1.available())
      {
        for (LEDcounter = 1; LEDcounter <= 8; LEDcounter++)
        {
          //     summer = fft1024_1.read(LEDcounter * (numOctaves + lowestOctave)  * 2, (LEDcounter * (numOctaves + lowestOctave)  * 3));
          summer = fft1024_1.read(LEDcounter * LEDcounter, ((LEDcounter + 1) * LEDcounter) + LEDcounter * LEDcounter);
          int averager = ((LEDcounter + 1) * LEDcounter) + LEDcounter * LEDcounter - LEDcounter * LEDcounter;
          summer = summer / averager;
          LEDhue = summer * 10000;
          LEDhue = constrain(LEDhue, 0, hueRange);
          LEDsat = summer   * 50000;
          LEDsat = constrain(LEDsat, 0, 255);
          leds[LEDcounter] = CHSV(hueOffset + LEDhue, 255, LEDsat);
          //      leds[0] = CHSV(0, 255, 255);
          if (LEDcounter == NUM_LEDS)
          {
            FastLED.show();
          }
        }
      }
    }

  9. #9
    Junior Member
    Join Date
    Dec 2021
    Posts
    7
    For added fun, here's the synth layout in the design tool:
    the last 4 taps in the delay aren't used... audio memory set to 200. The delay feedback loop seems clunky wrt memory but this sounds OK with randomly generated tonal values in various musical keys and modes.

    // GUItool: begin automatically generated code
    AudioSynthWaveformSine sine1; //xy=129.5,250.25000286102295
    AudioInputI2S i2s1; //xy=144.75,431
    AudioEffectEnvelope envelope1; //xy=186,298
    AudioSynthKarplusStrong string1; //xy=347.5,369.5
    AudioMixer4 mixer1; //xy=385,286
    AudioEffectDelay delay1; //xy=508,294
    AudioSynthWaveform lfo1; //xy=625,133
    AudioSynthWaveform lfo2; //xy=637,177
    AudioMixer4 mixer2; //xy=650,267
    AudioMixer4 mixer3; //xy=652,336
    AudioMixer4 mixer4; //xy=819,298
    AudioMixer4 mixer5; //xy=822.7500114440918,395.25000762939453
    AudioFilterLadder filter1; //xy=871,153
    AudioAnalyzeFFT1024 fft1024_1; //xy=956.25,452.5
    AudioOutputI2S i2s2; //xy=971.5,392
    AudioConnection patchCord1(sine1, envelope1);
    AudioConnection patchCord2(i2s1, 0, mixer1, 2);
    AudioConnection patchCord3(i2s1, 0, mixer5, 2);
    AudioConnection patchCord4(envelope1, 0, mixer5, 1);
    AudioConnection patchCord5(envelope1, 0, mixer1, 1);
    AudioConnection patchCord6(string1, 0, mixer1, 3);
    AudioConnection patchCord7(mixer1, delay1);
    AudioConnection patchCord8(delay1, 0, mixer2, 0);
    AudioConnection patchCord9(delay1, 1, mixer2, 1);
    AudioConnection patchCord10(delay1, 2, mixer2, 2);
    AudioConnection patchCord11(delay1, 3, mixer2, 3);
    AudioConnection patchCord12(delay1, 4, mixer3, 0);
    AudioConnection patchCord13(delay1, 5, mixer3, 1);
    AudioConnection patchCord14(delay1, 6, mixer3, 2);
    AudioConnection patchCord15(delay1, 7, mixer3, 3);
    AudioConnection patchCord16(lfo1, 0, filter1, 1);
    AudioConnection patchCord17(lfo2, 0, filter1, 2);
    AudioConnection patchCord18(mixer2, 0, mixer4, 0);
    AudioConnection patchCord19(mixer3, 0, mixer4, 1);
    AudioConnection patchCord20(mixer4, 0, filter1, 0);
    AudioConnection patchCord21(mixer4, 0, mixer5, 0);
    AudioConnection patchCord22(mixer5, 0, i2s2, 0);
    AudioConnection patchCord23(mixer5, 0, i2s2, 1);
    AudioConnection patchCord24(mixer5, fft1024_1);
    AudioConnection patchCord25(filter1, 0, mixer1, 0);
    AudioControlSGTL5000 sgtl5000_1; //xy=528.7222366333008,467.8174514770508
    // GUItool: end automatically generated code

    I get line audio input if I switch to RMS instead of FFT, but unfortunately it's just nothing or screaming feedback if I multiply it by more than 3.5 or so (mixed so that it bypasses the synth and goes to output with everything else zeroed out...). This has always worked with an electret mic as input but since this synth has an internal speaker it would just feed back. Putting this synth on a shelf for now as I'm not getting anywhere and I've put too much time into it at the moment.


    This code shows the RMS in blue on my 7 LEDs anyway; maybe do a nice blackbody temperature fade if I'm stuck with RMS...

    Code:
    void displayRMS()
    {
      if (rms1.available())
      {
        uint8_t RMSval = rms1.read() * 10.0;
        RMSval = constrain(RMSval, 1, 7);
        Serial.println(RMSval);
        for (LEDcounter = 1; LEDcounter <= 8; LEDcounter++)
        {
          leds[LEDcounter] = CHSV(0, 0, 0);
          //      leds[0] = CHSV(0, 255, 255);
          if (LEDcounter == NUM_LEDS)
          {
            leds[RMSval] = CHSV(255, 255, 255);
            FastLED.show();
          }
        }
      }
    }

  10. #10
    Junior Member
    Join Date
    Dec 2021
    Posts
    7
    got it. was monitoring the wrong input channel.. thanks for bearing with me this thing sounds absolutely amazing

Posting Permissions

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