GDSTx Library Incompatibility

Hi,

I'm having some trouble integrating the GDSTx library to send data streamed from the teensy audio library to a display. The two libraries work fine separately, but putting them in one project breaks everything. Right off the bat, they make calls to different SD.h libraries, but that was an easy fix since I don't need SD card access.

The real problem is that the moment I run GD.begin(), my record queue becomes all 0.00 values and will not fill up. I am using an I2S input object patched through to a recording queue.

I was wondering if anyone knows where to start with fixing this? Any ideas what might be causing this? I'm assuming they are using the same registers to store data?

I don't imagine it will help but I've included my code here anyway.

Code:
#include <ADC.h>
#include <queue>
#include <math.h>
#include <unordered_map>
#include <GDSTx.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>

struct Point {
  float x,y;
  unsigned long valueHash;
};

const int x_res = 1024;
const int y_res = 600;
const int ax_center[] = {x_res/2, y_res/2};
const double cosTheta = cos(45 * M_PI / 180.0);
const double sinTheta = sin(45 * M_PI / 180.0);

AudioInputI2S            i2s1;      //xy=151,200
AudioAnalyzePrint        print1;
AudioRecordQueue         leftqueue;         //xy=362,195
AudioRecordQueue         rightqueue;         //xy=362,195
AudioConnection          patchCord1(i2s1, 0, leftqueue, 0);
AudioConnection          patchCord2(i2s1, 1, rightqueue, 0);
AudioConnection          patchCord3(i2s1, 0, print1, 0);

std::unordered_map<long, int> plotcount;
std::queue<Point> measurementQueue;

void setup() {
  AudioMemory(12);
  GD.begin();
  Serial.begin(9600);
}

void loop() {
  leftqueue.clear();
  rightqueue.clear();
  leftqueue.begin();
  rightqueue.begin();

  while(leftqueue.available() < 6 && rightqueue.available() < 6){
    ;
  }

  leftqueue.end();
  rightqueue.end();
  for (int b = 1; b <= 6; b++){
    int16_t rightinterim[256];
    int16_t leftinterim[256];

    memcpy(rightinterim,rightqueue.readBuffer(),256);
    rightqueue.freeBuffer();
    memcpy(leftinterim,leftqueue.readBuffer(),256);
    leftqueue.freeBuffer();

    for (int i=1;i<128;i++){
      Point p;
      p.x = rightinterim[i];
      p.y = leftinterim[i];

      p.valueHash = static_cast<long>(p.x, p.y);
      plotcount[p.valueHash] = 0;

      Serial.print(p.x);
      Serial.print(", ");
      Serial.println(p.y);

      Serial.print(p.x);
      Serial.print(", ");
      Serial.println(p.y);
      measurementQueue.push(p); //
    }
  }

  while (!measurementQueue.empty()) {
    Point p = measurementQueue.front();
    measurementQueue.pop();
  }
  plotcount.clear();
}
 
When fixes were implemented in the GDS Tx library, you mentioned that you were building a (taking your own words) "audio vectorscope for displaying oscilloscope art".

Indeed there are some incompatibilities between the SD.h, Audio.h and SdFat.h libraries; which overlap with GDSTx.h. In my case, I wanted to build a real-time FFT visualizer. With the extensive capabilities of the Audio.h library that comes with the teensyduino and the processing power of teensy 4 or 4.1; I ventured into the project.

In my case, I only monitor one of the audio signals from the PC, it seems to me to be the right channel. I condition this signal first with this circuit:

teensy audio input.png


In order to "listen to the audio signal" I use these instructions, I must clarify that I do not use the audioshield.
Code:
#include <Audio.h>

AudioInputAnalog         adc1;   //adc1(A2)    adc1
AudioAnalyzeFFT1024      fft1024_2;
AudioOutputI2S           i2s1;
AudioConnection          patchCord3(adc1, fft1024_2);

In the setup, I use these lines, after GD.begin()

Code:
  analogReadAveraging(4);
  AudioMemory(30);
  fft1024_2.windowFunction(AudioWindowWelch1024);

With these lines it is possible to obtain the FFT and graph it on the screen using GDSTx, in this case, it is a 4.3" NHD-FT813.

I modified the Audio.h library with these lines:

Code:
// while you make changes.
//
#define AudioNoInterrupts() (NVIC_DISABLE_IRQ(IRQ_SOFTWARE))
#define AudioInterrupts()   (NVIC_ENABLE_IRQ(IRQ_SOFTWARE))
#define SDAudio   0        //0 for FFT on GDSTx  1 normal use
// include all the library headers, so a sketch can use a single

And later, these:

Code:
#include "play_memory.h"
#include "play_queue.h"

#if (SDAudio==1)
#include "play_sd_raw.h"
#include "play_sd_wav.h"
#endif

#include "play_serialflash_raw.h"
#include "record_queue.h"

And by the way, the values are very small, they must be scaled so that they can be "seen" on the serial monitor or on the TFT. Look at this example on the serial monitor, I recommend implementing the circuit to condition the audio input signal to avoid negative voltages
Code:
#include <Audio.h>

AudioInputAnalog         adc1;   //adc1(A2)    adc1   
AudioAnalyzeFFT1024      fft1024_2;
AudioOutputI2S           i2s1; 
AudioConnection          patchCord3(adc1, fft1024_2);

#include <GDSTx.h>

#define NUM_BINS 380
double Datos[NUM_BINS];

void setup()
{
  Serial.begin(9600);
  GD.begin();

  analogReadAveraging(4);
  AudioMemory(30);
  fft1024_2.windowFunction(AudioWindowWelch1024);
 
}

void loop()
{
  if (fft1024_2.available())
  {
    for (int i=0; i < NUM_BINS; i=i+1)
    { 
      Datos[i] = fft1024_2.read(i)*10000;
      if (Datos[i]<=0){Datos[i]=0;}
      Serial.println(Datos[i]);
    }

  }
}

I am going to modify the above code to display the FFT on the TFT. I just put together the PCB for a 5" NHD-FT813 screen, which arrived last week.

For the audio input I use pin A2. How many audio inputs are you going to use in your project?
 
Last edited:
Hey thanks for the response! I'm currently only testing with one stereo i2s input, but I'm planning on adding a spdif input as well.

I fixed it actually. I made the changes that you did to Audio.h, and I also went into the GDSTx.cpp file and changed line 52: "SdFs SD", and changed the "SD" to a different handle (and updated all the uses of SD later in the code to match the new name), and that fixed everything.
 
So you can now see data on the serial monitor with the GD.begin() call?. Brilliant. Waiting for more information about your project

PD: Just by using "SD" in the line "SdFs SD", wow, what a thing!
 
Back
Top