Teensy 4.1 I2S In and Outputs

Aloxen

New member
Hello,

I need to mix two I2S inputs into one output, but I am failing to get just one input through the teensy to the output.

I have an ESP32, which functions as a bluetooth receiver:

Code:
#include "AudioTools.h"
#include "BluetoothA2DPSink.h"

I2SStream i2s;
BluetoothA2DPSink a2dp_sink(i2s);

void setup() {
  Serial.begin(115200);

  auto cfg = i2s.defaultConfig();
  cfg.pin_bck  = 16;
  cfg.pin_ws   = 17;
  cfg.pin_data = 18;
  cfg.sample_rate = 44100;
  cfg.bits_per_sample = 16;
  cfg.channels = 2;
  cfg.i2s_format = I2S_PHILIPS_FORMAT;
  i2s.begin(cfg);

  a2dp_sink.set_auto_reconnect(true);
  a2dp_sink.start("ESP32-Teensy");
}

void loop() {
}

For now I was just focusing on getting this audio into the teensy (as a passthrough) and out to a MAX98357A which than goes into the speaker. Later one, I want to add a microphone Input and mix it with the input from the music (to create ANC)

I connected everything like this:

ESP -> Teensy

Gio 16 (BCLK) -> 21
Gio 17 (LRCLK) -> 20
Gio 18 (Data) -> 13

Gnd -> Gnd

Teensy -> MAX98357A

2 -> LRCLK
3 -> VIN
4 -> BCLK

gnd -> gnd
5 -> v1n


And this is my Teensy Code:
Code:
#include <Audio.h>
// Audio-Objekte
AudioInputI2S        i2s1_in;       // Input from ESP32
AudioOutputI2S2      i2s2_out;      // Output to MAX98357A
AudioConnection      patchCord1(i2s1_in, 0, i2s2_out, 0);
AudioConnection      patchCord2(i2s1_in, 1, i2s2_out, 1);
void setup() {
  AudioMemory(12);
  Serial.begin(115200);
  delay(500);
  Serial.println("Teensy I2S debug start");
}
void loop() {
}


My result is that there is no music playing... I can confirm that the esp is receiving data from the smartphone and at least trying to send it and whenever it sends, an orange LED is turned on on the Teensy. The Speakers are making a steady background noice, which does not change when I start and stop the music on the smartphone.

I tested the Sound output manually with a test sketch, so we can assume that the speakers and the MAX98357A are working. I also tested if the ESP32 is sending something with LEDs, which it does, so it is either a problem between the communication of ESP and Teensy, or it is a problem with the passing through part.

Does anyone have an idea why this would not work?

Thanks in advance
 
Last edited:
Gio 18 (Data) -> 13

This doesn't look right. AudioInputI2S on Teensy 4.1 receives on pin 8.

From the design tool documentation (right side panel).

1753916377613.png


Teensy 3.2 used pin 13. But on Teensy 4.1 the data input is pin 8.
 
I'm not very familiar with ESP32, but another possible issue to consider is who controls the clock signals. In this config, Teensy outputs LRCLK, BCLK, MCLK. You need the ESP32 to configure those signals as inputs. It can't work if both try to transmit the clocks.
 
Hi, thanks for the advice.

I tried it with pin 8, but it did not work either, but I will keep it that way.

I also assumed that it has something to do with the master/slave relationship between the Teensy and the ESP32. I am using your AD2P Library and I do not know how to put ESP32 in Slave mode. According to ChatGPT, this library does not support I2S in slave mode. Any ideas, because I really do not want to write this all by myself :)


Just for my understanding: How would that work, if the Teensy is sending the clock signals, but the ESP32 is sending the audio data?
 
Have you connected the DAC directly to the ESP32 (without the teensy in the middle) to make sure they're both working?
 
Okay, I narrowed it down.

As jmarsh suggested, I tried that and it played a sound. Since I later want to manipulate the audio from the Bluetooth input, I need the Teensy in between. I also tested, if the teensy can play a sound (without the Bluetooth input) and with this configuration it played a sound:

2 -> DIN
3 -> LRCLK
4 -> BCLK

(as the link from PaulStoffregen suggested)

I now tried it with the audio input (21 -> Gio 18 (BCLK), 20 -> Gio 17 (LRCLK), 8 -> Gio 16 (Data)) and there is a rythmic rattling comming out of the speakers, but unfortunately not the music i was playing :(

Ig that means, that the passthrough does it's thing, but there is a conflict in communication between ESP32 and Teensy, likely caused by a mixed up master/slave relation ship. I've read that it is not a good idea to use the teensy as slave and you can only use one input and one output. Since I need two inputs, I have to make Teensy master and ESP32 Slave, right? And does anyone know how to do that?

Thanks a lot for your help guys
 
Have you connected the DAC directly to the ESP32 (without the teensy in the middle) to make sure they're both working?
This is good advice...

I also assumed that it has something to do with the master/slave relationship between the Teensy and the ESP32
Yes. Since you don't know how to put the ESP32 into slave mode, you should use the Teensy library's slave mode - something like this (untested):
C++:
#include <Audio.h>
// Audio-Objekte
AudioInputI2Sslave   i2s1_in;       // Input from ESP32
AudioOutputI2Sslave  i2s1_out;      // Output to MAX98357A
AudioConnection      patchCord1(i2s1_in, 0, i2s1_out, 0);
AudioConnection      patchCord2(i2s1_in, 1, i2s1_out, 1);
void setup() {
  AudioMemory(12);
  Serial.begin(115200);
  delay(500);
  Serial.println("Teensy I2S debug start");
}
void loop() {
}
Note you don't need to use I2S2, and in fact it'd probably cause problems because the clocks won't be in sync. The MAX98357A input should be connected to Teensy pin 7 (I2S output data), all clock signals connected together (ESP32, Teensy, MAX98357A).

I am using your AD2P Library
No you're not - the Teensy doesn't have an A2DP library

I've read that it is not a good idea to use the teensy as slave
Citation needed

Since I need two inputs
Can you clarify that? I²S gives you two channels (left and right) per data pin; Teensy can use more pins for more channels, but not AFAIK in slave mode. You'd have to get the ESP32 into slave mode, or do some deep diving into the Teensy library, in order to get more than stereo.
 
The issue with using the Teensy in slave mode is going to be when adding the additional microphone input. I'm sure it's possible but not with the current audio library code.

(Kind of makes me wonder why there are no FlexIO based audio library objects... they would be much more configurable with regards to speeds and which pins are used for input/output.)
 
Indeed we don't have code in the audio library to resample incoming I2S data to Teensy's internal clock. So if you use an I2S slave interface, it causes the entire audio library to run at the external clock. You can't mix an I2S slave interface with any of the normal master mode interfaces, because those master mode ones run from Teensy's internal clock.

While this is theoretically just a matter of programming, and perhaps some of the work may already exist in the Async SPDIF code, as a practical matter (as far as I know) nobody has put the work into creating I2S slave I/O that resamples to Teensy's internal clock.

Likewise, FlexIO audio is theoretically possible and at least some of the work may be done in NXP's documentation and examples. But we don't have this in the audo library (or a number of other code / libraries that work together with the audio library) for the same reason... nobody has put in the effort.
 
I can confirm that both were in master mode and were both generating clocks. I am going to use a bluetooth module, which is sending via I2S in slave mode by default
 
Hopeful you'll share which module and confirm whether it really works and if any special setup needed. Just a little confirmed info about a working setup might really help others who want to connect Bluetooth audio and combine or modify I2S data.
 
Back
Top