Teensy 4.1 and 4-channel audio (AudioInputI2SQuad)

Is there a simple way to read line in through the audio boards through the adc and put the values in a buffer? Or do you have to use queue to create the audio buffer?
 
Do I need to remove the 10K resistor?

The 10K resistors on pin 6 are fine. No need to remove them.


Is there a simple way to read line in through the audio boards through the adc and put the values in a buffer? Or do you have to use queue to create the audio buffer?

That's what the audio library queue object does... it puts the data into buffers for you.

There is no other "simple" way. But if you want something that's not simple, you could copy the I2S code from the audio library and modify it any way you like. But managing DMA is pretty far from "simple". Unless you really enjoy messing with that sort of low-level code, your best path is to use the already well developed audio library and its queue method to get access to the raw data.
 
I would love to use the library for that exact reason. I guess I just had a way in my head I was going to do this using just the Teensy, but now with the library that has shifted.

The general idea is to be able to find the lag between two microphones based on phase shift. What would be the best way to go about this using the library? General ideas here would be use queue and then compare the signals to each other after some peak value has been reached on one of the microphones. I think this would work and is similar to the way I was planning on doing it with just the Teensy.

Could I possibly use the FIR filter and mixer together in order to find the lag?
 
Hi everyone,
I am using two SGTL5000 with a teensy 4.1 to record 4 channel on a SD card. I have used the code that record stereo in one raw file and extended it to 4 channel. The problem is that during the recording I occasionnaly have small cuts on the audio channels. They are not constant and happen at any time (sometimes never). I wanted to know if anyone had encoutered that same thing ?
here is my code

Code:
// Enregistre le microphone interne et externe separement et joue separement chaque microphone pour deux oreillette
// On branche le cable jaune (micro externe) sur le channel L  et le bleu(micro interne) sur le R
#include <Arduino.h>
#include "Adafruit_NeoTrellis.h"
#include <Bounce.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Keyboard.h>

#define FILE_BASE_NAME "Audio_2Earpiece"
#define BUFFER_SIZE_AUDIO 1024

const int myInput = AUDIO_INPUT_LINEIN;
const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;

char fileName1[] = FILE_BASE_NAME "00.raw";

float volume = 0.5;
int lineIninter = 5;
int lineIn = 5;
bool record_flag = false;
bool buffer_flag = false;


// GUItool: begin automatically generated code
AudioInputI2SQuad i2s_quad1;  // xy=82,307
AudioRecordQueue queue1;      // xy=98,73
AudioRecordQueue queue4;      // xy=146,554
AudioRecordQueue queue2;      // xy=381,460
AudioRecordQueue queue3;      // xy=420,33
AudioOutputI2SQuad i2s_quad2; // xy=793,287
AudioConnection patchCord1(i2s_quad1, 0, queue1, 0);
// AudioConnection patchCord2(i2s_quad1, 0, i2s_quad2, 0);
// AudioConnection patchCord3(i2s_quad1, 0, i2s_quad2, 2);
AudioConnection patchCord4(i2s_quad1, 1, queue2, 0);
AudioConnection patchCord5(i2s_quad1, 2, queue3, 0);
// AudioConnection patchCord6(i2s_quad1, 2, i2s_quad2, 1);
// AudioConnection patchCord7(i2s_quad1, 2, i2s_quad2, 3);
AudioConnection patchCord8(i2s_quad1, 3, queue4, 0);
AudioControlSGTL5000 sgtl5000_1; // xy=285,444
AudioControlSGTL5000 sgtl5000_2; // xy=382,494
// GUItool: end automatically generated code



// Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN BUILTIN_SDCARD
#define SDCARD_MOSI_PIN 7
#define SDCARD_SCK_PIN 14

// Remember which mode we're doing
int mode = 0; // 0=stopped, 1=recording, 2=playing
int startTime;

// The file where data is recorded
File frec;

void setup()
{

  // Audio connections require memory, and the record queue
  // uses this memory to buffer incoming audio.
  AudioMemory(120);
  // Enable the audio shield, select input, and enable output
  sgtl5000_1.setAddress(HIGH);
  sgtl5000_1.enable();
  sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN);
  sgtl5000_1.micGain(15);
  sgtl5000_1.lineInLevel(5, 5);
  sgtl5000_1.volume(0.5);
  sgtl5000_2.setAddress(LOW);
  sgtl5000_2.enable();
  sgtl5000_2.inputSelect(AUDIO_INPUT_LINEIN);
  sgtl5000_2.micGain(15);
  sgtl5000_2.lineInLevel(5, 5);
  sgtl5000_2.volume(0.5);
  queue1.begin(); // Internal Right
  queue2.begin(); // External Right
  queue3.begin(); // Internal Left
  queue4.begin(); // External Left
  Serial.println("Audio Shield initialized");


  // Initialize the SD card
  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  Keyboard.begin();
  if (!(SD.begin(BUILTIN_SDCARD)))
  {
    // stop here if no SD card, but print a message
    while (1)
    {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }

  Serial.println("Setup Done");
}

void loop()
{
   if (Serial.available() > 0)
  {
    char inChar = Serial.read();
    switch (inChar)
    {
    case 'r':
      Serial.println("Record Button Press");
      if (mode == 0)
      {
        startRecording(); // Création du fichier AUDIO dans la carte SD
        mode = 1;
      }
      break;
    case 's':
      Serial.println("Stop Button Press");
      if (mode == 1)
      {
        stopRecording(); // Fermeture du fichier AUDIO dans la carte SD
        mode = 0;
      }
      break;
    }
  }
  if (mode == 1)
  {                                  // Si on appui sur le bouton Play :                            // Sinon :
    continueRecording(); // La fonction d'acquisition de l'audio NE PEUT PAS écrire les données sur la carte SD
  }
}

// Strat recording for the right earpiece
void startRecording()
{
  Serial.println("startRecording");
  while (SD.exists(fileName1))
  {
    if (fileName1[BASE_NAME_SIZE + 1] != '9')
    {
      fileName1[BASE_NAME_SIZE + 1]++;
    }

    else if (fileName1[BASE_NAME_SIZE] != '9')
    {
      fileName1[BASE_NAME_SIZE + 1] = '0';
      fileName1[BASE_NAME_SIZE]++;
    }
    else
    {
      Serial.println(F("Can't create file name"));
      return;
    }
  }
  frec = SD.open(fileName1, FILE_WRITE);
    if (frec) {
    Serial.println("File Open");
    queue1.begin(); // queue 1 = shield non modifé channel L
    queue2.begin(); // queue 2 =  shield non modifé channel R
    queue3.begin(); // queue 3 =  shield modifé channel L
    queue4.begin(); // queue 4 =  shield  modifé channel R

  }
}

// write all 512 bytes to the SD card   
void continueRecording() {
   if (queue1.available() >= 2 && queue2.available() >= 2) {
byte buffer[BUFFER_SIZE_AUDIO];
    byte buffer1[BUFFER_SIZE_AUDIO / 4];                         // buffer du channel L shield normal
    byte buffer2[BUFFER_SIZE_AUDIO / 4];                         // buffer du channel R shield normal
    byte buffer3[BUFFER_SIZE_AUDIO / 4];                         // buffer du channel L shield modifié
    byte buffer4[BUFFER_SIZE_AUDIO / 4];                         // buffer du channel R shield modifié
    memcpy(buffer1, queue1.readBuffer(), BUFFER_SIZE_AUDIO / 4); // Oreillette externe droite
    memcpy(buffer2, queue2.readBuffer(), BUFFER_SIZE_AUDIO / 4); // Oreillette interne droite
    memcpy(buffer3, queue3.readBuffer(), BUFFER_SIZE_AUDIO / 4); // Oreillette externe gauche
    memcpy(buffer4, queue4.readBuffer(), BUFFER_SIZE_AUDIO / 4); // Oreillette interne gauche
    queue1.freeBuffer();
    queue2.freeBuffer();
    queue3.freeBuffer();
    queue4.freeBuffer();
    int b =0;
    for (int i = 0; i < BUFFER_SIZE_AUDIO; i += 8)
    {
      buffer[i] = buffer1[b];
      buffer[i + 1] = buffer1[b + 1];
      buffer[i + 2] = buffer2[b];
      buffer[i + 3] = buffer2[b + 1];
      buffer[i + 4] = buffer3[b];
      buffer[i + 5] = buffer3[b + 1];
      buffer[i + 6] = buffer4[b];
      buffer[i + 7] = buffer4[b + 1];
      b = b + 2;
    }
    frec.write(buffer, BUFFER_SIZE_AUDIO);  //256 or 512 (dudes code)
  }
}

void stopRecording() {
  Serial.println("StopRecording");
  queue1.end();
  queue2.end();
  queue3.end();
  queue4.end();
  // flush buffer
  while (queue1.available() > 0 && queue2.available() > 0) {
    queue1.readBuffer();
    queue1.freeBuffer();
    queue2.readBuffer();
    queue2.freeBuffer();
    queue3.readBuffer();
    queue3.freeBuffer();
    queue4.readBuffer();
    queue4.freeBuffer();
  }
  frec.close(); // close file
}


}
 

Attachments

  • Screenshot 2023-03-02 104219.jpg
    Screenshot 2023-03-02 104219.jpg
    28.6 KB · Views: 54
Last edited:
Hi everyone,
I am using two SGTL5000 with a teensy 4.1 to record 4 channel on a SD card. I have used the code that record stereo in one raw file and extended it to 4 channel. The problem is that during the recording I occasionnaly have small cuts on the audio channels. They are not constant and happen at any time (sometimes never). I wanted to know if anyone had encoutered that same thing ?

This to be expected.
120 blocks for AudioMemory is too little for the occasional delays of the microSD cards that can last over 100 ms.
Increase AudioMemory and if you need more space use external memory (which needs soldering of PSRAM and custom AudioMemory macro).
It can and has been done.
 
Back
Top