Teensy in Raspberry I2S based digital chain.

Status
Not open for further replies.
Hello again Paul,
the BCLK/LRCLK ratio of 64 is working now. (It was either a wiring problem or the fact I removed the unneeded libaries and only left Audio.h as in your code listing)
The problem of the left channel appearing on every other output cycle could be an oscilloscope measuring problem: by adjusting the trigger holdoff the signal appears either (correctly) every cycle or every other cycle.
(The fact the Raspberry Pi has a very bad LRCLK clock probably doesn't help)
The main remaining problem is that I still get audio only on the left channel with the 32 bit setup (Raspberry) whatever signal (Left or Right) I pass through.
If you still have your setup wired, for peace of mind, could you kindly run the Sine wave through the right channel also? Thanks
B.
PS just tested the output through the whole audio chain (TDA1543 DAC)
When both channels patched, audio on Left Speaker only
When only Left channel patched, audio on Left Speaker only (with lower volume)
When only Right channel patched, audio on Left Speaker only (with lower volume)
(I do this by commenting // in front of AudioConnection )
 
Last edited:
[Rant] One thing I noted when trying Teensy to a Linux system (SPI or I2S), the Linux device drivers are not as easy modifiable as I'm used with teensy.
All the modular approach, which make high level programming easier, make (at least fo me) device driver modification extreme difficult. [/RANT]
As, I will soon need an I2S to RPI (or Olimex) interface, I'm following this thread
 
[Rant] One thing I noted when trying Teensy to a Linux system (SPI or I2S), the Linux device drivers are not as easy modifiable as I'm used with teensy.
All the modular approach, which make high level programming easier, make (at least fo me) device driver modification extreme difficult. [/RANT]
As, I will soon need an I2S to RPI (or Olimex) interface, I'm following this thread

Hello WMXZ
The reason I'm trying to wire the Teensy to the Raspberry is for music reproduction. I've already tried a Minidsp Minisharc DSP and (pending further testing) I've noted a slight sound quality degradation (which could be due to the ASCR converter 44.1Lhz > 48Khz)
I presume the Teensy would be more "transparent" in this regard and flexible to program. Digital time delays and FIR DSP being Teensy's end tasks :) It would be easy to create 8 channel output using 4 Teensies (or 2 actually) with one Raspberry as master, each with it's own Delay and FIR (this would be for Car Audio). If there's anything I can answer or try for you (about the RPI-Teensy relationship) please feel free to ask.
 
The main remaining problem is that I still get audio only on the left channel with the 32 bit setup (Raspberry) whatever signal (Left or Right) I pass through.
If you still have your setup wired, for peace of mind, could you kindly run the Sine wave through the right channel also?

Yes, it's still sitting on my desk with all 4 scope probes connected.

I changed the Teensy 3.2 to this: (hopefully the smaller amplitude, higher frequency data will be discernible on the scope)

Code:
#include <Audio.h>

AudioSynthWaveformSine   sine1;          //xy=128,113
AudioSynthWaveformSine   sine2;          //xy=132,169
AudioOutputI2S           i2s1;           //xy=280,136
AudioConnection          patchCord1(sine1, 0, i2s1, 0);
AudioConnection          patchCord2(sine2, 0, i2s1, 1);

void setup() {
  AudioMemory(10);
  sine1.frequency(440);
  sine1.amplitude(0.9);
  sine2.frequency(2000);
  sine2.amplitude(0.12);
}

void loop() {
}

Here's what I see on the scope.

file.png
 
The main remaining problem is that I still get audio only on the left channel with the 32 bit setup (Raspberry) whatever signal (Left or Right) I pass through.
If you still have your setup wired, for peace of mind, could you kindly run the Sine wave through the right channel also?

Yes, it's still sitting on my desk with all 4 scope probes connected.

I changed the Teensy 3.2 to this: (hopefully the smaller amplitude, higher frequency data will be discernible on the scope)

Code:
#include <Audio.h>

AudioSynthWaveformSine   sine1;          //xy=128,113
AudioSynthWaveformSine   sine2;          //xy=132,169
AudioOutputI2S           i2s1;           //xy=280,136
AudioConnection          patchCord1(sine1, 0, i2s1, 0);
AudioConnection          patchCord2(sine2, 0, i2s1, 1);

void setup() {
  AudioMemory(10);
  sine1.frequency(440);
  sine1.amplitude(0.9);
  sine2.frequency(2000);
  sine2.amplitude(0.12);
}

void loop() {
}

Here's what I see on the scope.

View attachment 14800

Here's a zoom in to 5 us/div time scale, which allows the scope's serial decode to actually show all 32 bits.

file.png
 
I tried one more test with BCLK/LRCLK ratio at 32, and I was able to reproduce the problem with the missing right channel.

Here's the Teensy 3.2 code: (using the same hardware and Teensy 3.6 code as msg #23)

Code:
#include <Audio.h>

AudioSynthWaveformSine   sine1;          //xy=128,113
AudioSynthWaveformSine   sine2;          //xy=132,169
AudioOutputI2SQuad       i2s1;           //xy=280,136
AudioConnection          patchCord1(sine1, 0, i2s1, 0);
AudioConnection          patchCord2(sine2, 0, i2s1, 1);

void setup() {
  AudioMemory(10);
  sine1.frequency(440);
  sine1.amplitude(0.9);
  sine2.frequency(2000);
  sine2.amplitude(0.12);
}

void loop() {
}

Here's the scope screen where the I2S slave output is missing the right channel.

file.png


I will add this to my list of bugs to fix.

For now, looks like I2S slave mode is only working with both channels if you have BCLK/LRCLK ratio of 64.
 
I tried one more test with BCLK/LRCLK ratio at 32, and I was able to reproduce the problem with the missing right channel.

Here's the Teensy 3.2 code: (using the same hardware and Teensy 3.6 code as msg #23)

Code:
#include <Audio.h>

AudioSynthWaveformSine   sine1;          //xy=128,113
AudioSynthWaveformSine   sine2;          //xy=132,169
AudioOutputI2SQuad       i2s1;           //xy=280,136
AudioConnection          patchCord1(sine1, 0, i2s1, 0);
AudioConnection          patchCord2(sine2, 0, i2s1, 1);

void setup() {
  AudioMemory(10);
  sine1.frequency(440);
  sine1.amplitude(0.9);
  sine2.frequency(2000);
  sine2.amplitude(0.12);
}

void loop() {
}

Here's the scope screen where the I2S slave output is missing the right channel.

View attachment 14803


I will add this to my list of bugs to fix.

For now, looks like I2S slave mode is only working with both channels if you have BCLK/LRCLK ratio of 64.

Hello !
Good that we could come to the end of it and that the bug is being taken care of. :)
One little thought is still bothering me regarding the left channel (sometimes) appearing on every other output cycle.
The fact is that when I activated (on the Teensy) one channel only (instead of both) the sound would be fainter on the playing speaker. This would be consistent with the data appearing once every other ouput cycle.
As I said before I could reproduce both situations on my oscilloscope by regulating the trigger. So this begs the question: could it be that it was your oscilloscope which was being "tricked" into
displaying data on all cycles? The only way to be sure would be to check on a data logger...
At this point this would probably get automatically fixed when you take care of the bug, but may be helpful with debugging. (?)
Thanks B.
 
Last edited:
I do still have the hardware on my desk (but going to put it away after this message). I'm re-running the BCLK/LRCLK ratio = 64 test, same as msg #30.

could it be that it was your oscilloscope which was being "tricked" into displaying data on all cycles?

Those screenshots are with the scope in running mode, where the screen shows a "digital phosphor" composite of many horizontal "sweeps"... so unlikely as this seems, maybe possible.

Here's a couple single sweep captures, where you can see 4 consecutive L+R output cycles (the most that allows the protocol decode to show 4 hex digits).

file.png

file.png

I pressed the single sweep button a couple dozen times and all were like these, with data in every slot.

Set the horizontal scale for 50 us/div, to "zoom out" for 5X more, which is about as much as can be seen on my scope's screen. Here's a single sweep which captures a couple dozen consecutive L+R output cycles.

file.png

With this too, I pressed the Single button many times. Didn't see any where data was missing from any L or R phase.


The only way to be sure would be to check on a data logger...

I suppose someone could do that with one of those cheap USB logic analyzers. I could also capture a longer single sweep on the scope and then zoom in and slowly scroll through it. But I'm feeling pretty confident from the 50 us/div single sweep that isn't likely to turn up anything new.

Dropouts spaced many samples apart would also be heard as a strong tone or buzzing sound, not merely reduced sound level.


Something else that might explain a lower signal level is all the bits getting shifted over by 1 position. As a final test, here's a zoom in to look at just the 16 bits (in run mode, where we see a composite of many sweeps).

file.png

Seems pretty clear Teensy is sending the bits in the same clock cycles after LRCLK changes. Here's an extreme zoom in.

file.png

The green and red data change at almost but not quite exactly the same instance relative to the falling edge of BCLK. That's not too surprising, since the green signal comes from Teensy 3.2 in I2S master mode and the red comes from Teensy 3.6 in I2S slave mode.

Whatever I2S slave device you're using to hear the data should have plenty of setup time before the BCLK rising edge, and plenty of hold time after.

However... and this is just a blind (deaf) guess, if your output device is sampling the data on the falling edge of BCLK, then there's a very strong chance it will receive Teensy's output effectively right shifted by 1 bit, which could cut the amplitude in half or give you a 6 dB reduction in audio level. If the Raspberry Pi is changing its output on the rising edge (rather than the falling edge as Teensy does), or it it's clock signal has some delay, then such a device would receive it properly but not receive Teensy's data properly. I'd suggest looking carefully at the I2S setup on all devices and make sure all are sampling data at the rising edge of BCLK, and either changing their output on the falling edge, or at least somewhere in the BCLK cycle to get the data bit stable well before that rising edge and held well after it.
 
I do still have the hardware on my desk (but going to put it away after this message). I'm re-running the BCLK/LRCLK ratio = 64 test, same as msg #30.



Those screenshots are with the scope in running mode, where the screen shows a "digital phosphor" composite of many horizontal "sweeps"... so unlikely as this seems, maybe possible.

Here's a couple single sweep captures, where you can see 4 consecutive L+R output cycles (the most that allows the protocol decode to show 4 hex digits).

View attachment 14804

View attachment 14805

I pressed the single sweep button a couple dozen times and all were like these, with data in every slot.

Set the horizontal scale for 50 us/div, to "zoom out" for 5X more, which is about as much as can be seen on my scope's screen. Here's a single sweep which captures a couple dozen consecutive L+R output cycles.

View attachment 14806

With this too, I pressed the Single button many times. Didn't see any where data was missing from any L or R phase.




I suppose someone could do that with one of those cheap USB logic analyzers. I could also capture a longer single sweep on the scope and then zoom in and slowly scroll through it. But I'm feeling pretty confident from the 50 us/div single sweep that isn't likely to turn up anything new.

Dropouts spaced many samples apart would also be heard as a strong tone or buzzing sound, not merely reduced sound level.


Something else that might explain a lower signal level is all the bits getting shifted over by 1 position. As a final test, here's a zoom in to look at just the 16 bits (in run mode, where we see a composite of many sweeps).

View attachment 14807

Seems pretty clear Teensy is sending the bits in the same clock cycles after LRCLK changes. Here's an extreme zoom in.

View attachment 14808

The green and red data change at almost but not quite exactly the same instance relative to the falling edge of BCLK. That's not too surprising, since the green signal comes from Teensy 3.2 in I2S master mode and the red comes from Teensy 3.6 in I2S slave mode.

Whatever I2S slave device you're using to hear the data should have plenty of setup time before the BCLK rising edge, and plenty of hold time after.

However... and this is just a blind (deaf) guess, if your output device is sampling the data on the falling edge of BCLK, then there's a very strong chance it will receive Teensy's output effectively right shifted by 1 bit, which could cut the amplitude in half or give you a 6 dB reduction in audio level. If the Raspberry Pi is changing its output on the rising edge (rather than the falling edge as Teensy does), or it it's clock signal has some delay, then such a device would receive it properly but not receive Teensy's data properly. I'd suggest looking carefully at the I2S setup on all devices and make sure all are sampling data at the rising edge of BCLK, and either changing their output on the falling edge, or at least somewhere in the BCLK cycle to get the data bit stable well before that rising edge and held well after it.

Hello Paul,
My mistake that I have not made myself clear enough. The drop in output level is only noticed in BCLK/LRCLK ratio = 32.
When both channels are patched the volume is ok, but Left channel only. When Right only channel is patched through, or Left only channel is patched through, the sound will come from (only) Left channel but with lower volume.
This was also the instance when the data was appearing on every other output cycle on the oscilloscope, so I related the two facts.
The one clock delay you have noticed is part of the I2S protocol and is correct: "The transmitter always sends the MSB of the next word one clock period after the WS changes."
That is done so the listening device has time to prepare to receive the data on the opposite channel.
https://www.sparkfun.com/datasheets/BreakoutBoards/I2SBUS.pdf
I am going to get a cheap Logic analyzer sooner or later and this is something I will verify (and let you know). Since by now you have probably dismantled the setup :) , maybe this is something to verify when you fix the bug :) (of BCLK/LRCLK = 32)
Thanks for now! B.
 
The one clock delay you have noticed is part of the I2S protocol ...... maybe this is something to verify when you fix the bug :) (of BCLK/LRCLK = 32)

I believe this 1 BCLK delay is visible in the image on msg #31.


Since by now you have probably dismantled the setup

Yes, I cleared it off my desk to make room for testing Apple's release of MacOS Mojave.
 
I tried one more test with BCLK/LRCLK ratio at 32, and I was able to reproduce the problem with the missing right channel.

Here's the Teensy 3.2 code: (using the same hardware and Teensy 3.6 code as msg #23)

Code:
#include <Audio.h>

AudioSynthWaveformSine   sine1;          //xy=128,113
AudioSynthWaveformSine   sine2;          //xy=132,169
AudioOutputI2SQuad       i2s1;           //xy=280,136
AudioConnection          patchCord1(sine1, 0, i2s1, 0);
AudioConnection          patchCord2(sine2, 0, i2s1, 1);

void setup() {
  AudioMemory(10);
  sine1.frequency(440);
  sine1.amplitude(0.9);
  sine2.frequency(2000);
  sine2.amplitude(0.12);
}

void loop() {
}

Here's the scope screen where the I2S slave output is missing the right channel.

View attachment 14803


I will add this to my list of bugs to fix.

For now, looks like I2S slave mode is only working with both channels if you have BCLK/LRCLK ratio of 64.

Hello Paul,
I was wondering if this bug was taken care of in the end.
Thanks
 
Status
Not open for further replies.
Back
Top