Distributed DSP and I2S TDM

aidyw

Active member
Hi,
I am planning a new audio project using Teensy 4.0. This requires a significant number of ADC inputs coming from different ADCs. The intention is to have a central uC used to drive a UI via touchscreen and this device will also handle all outbound (i.e to DAC) DSP work. Postprocessing, limiting, EQ, crossover etc.

On the input side from the ADCs I need to offload the DSP work (EQ compression, reverb etc) to 2 Teensy4.0 devices, each of these will handle incoming I2S from at least 2 ADC ICs. So a total of 4 ADC ICs. The idea is to make the ADC chips modular to the system (pluggable). Here is the 1000 word picture, as a basic overview.
ADC_distributed_DSP.png

I see a significant issue based on the current Audio Library. This being that it is stated that only a single instance of the TDM object can be created for each Teensy? From what I understand each MMXRT1062 has 1 I2S module, but 2 TX and 2 RX interfaces, is it not possible to use both in TDM. If my memory serves me, the Kenetis chips can have independent data on each TX and RX pair, but they must share the same clocking scheme, i.e. master or slave. Therefore is this instantiation limitation just due to the current state of this library, or is there so more fundamental issue restricting this usage.

Any insights would be appreciated.
Aidan
 
It's true that you can only have one instance of the TDM object ... but it does (technically) provide 16 channels. Paul created a board based on the CS42448 which provides 8 inputs, so that would give you your inputs in just 2 chips (plus a couple extra to bump the native 6 inputs to the full 8); and a bonus of 16 outputs.

If you use one instance of an AudioInputTDM, and one of AudioInputTDM2 (connected to the I2S2 pins), that would allow you to run your 2 off PCM1864 parts; I don't know if anyone's written code for a PCM1864.

Where you may have more issues is the inter-Teensy link, as I don't think there's anything wider than 2-channel audio implemented with the Teensy as slave. It should be possible, though. I think...
 
Technically speaking, I think it is only because the Teensy Audio library is based around 16bit depth per channel that the TDM object has a total of 16 channel. If I am not mistaken a single I2S data line running in TDM fs256 mode can carry a total of 8x32bit channels. Inside the Teensy Audio library, I think this is being interpreted as 2x16bit ch in each 32bit block within the 256 bit frame. The Teensy can pretty much demux however it likes once it pulls the bits off the wire. In fact the I2S hardware in the Teensy even has tri-state capability on the TX lines, so in theory some pretty funky things could be tried in term of multiplexing, but I digress. The ADCs however are usually a bit more limited and from what I have seen in the past, LJ or I2S mode support determines exactly where the ADC hardware places each bit and which bits are stuffed within each 32bit block of the I2S TDM frame.

In my case I do not want to achieve maximum channel density from the ADCs. What is important is modularity. Therefore each ADC IC must have a dedicated I2S data line. Consequently each Teensy that is acting as the concentration point for 2 ADC IC must be able to offer a dedicated hardware port to each ADC IC. I2S DOUT from each ADC must terminate on a dedicated I2S DIN on the Teensy.

I think we describe the function of a TX RX pair as an SAI peripheral. That is to say the single I2S module of the Teensy 4.0 is composed of 2 SAI peripherals. However from a brief check and from some past experience (Though I am rusty, its been a few years), I think they will also operate asynchronously in terms of audio master clock. However again we might be digressing here.

So to summarise my question again, hopefully a little more clearly. I am trying to understand/confirm that the AudioInputTDM/AudioOutputTDM library functions currently only have access to 1 of the 2 SAI peripherals within the Teensy I2S module? That is to say they can only make use of a single physical TX/RX line pair. Furthermore which one and why?


With respect, I am not sure why you might suggest creating a second AudioInputTDM object. I quote the library documentation,

"Only one TDM input and one TDM output object may be used. The I2S hardware is used by TDM, so TDM objects may not be used together with I2S, SPDIF or PT8211."


BTW, you are correct, I will need to write the driver function for the TI ADCs and probably DACs as well. There are probably good reason for doing this and I accept this will be work, if I continue in this direction.

This is why I posted on the 'Project Guidance' board. I am trying to understand just exactly how much work I am cooking up for myself.


Having said all this, I think Paul has been up to some pretty funky stuff with the Cirrus logic chips anyway. muxing 2 codec onto one line. Currently I'm trying to understand exactly what he has already done.

https://hackaday.io/project/176368/logs
 
Last edited:
You asked...
With respect, I am not sure why you might suggest creating a second AudioInputTDM object. I quote the library documentation,

"Only one TDM input and one TDM output object may be used. The I2S hardware is used by TDM, so TDM objects may not be used together with I2S, SPDIF or PT8211."
...but I actually said
If you use one instance of an AudioInputTDM, and one of AudioInputTDM2 (connected to the I2S2 pins), that would allow you to run your 2 off PCM1864 parts; I don't know if anyone's written code for a PCM1864.
(emphasis added for ... er ... emphasis :confused:) You can find "tdm2" in the Design Tool just below the "tdm" object. The info pane doesn't tell you what it conflicts with, but it's the "obvious" objects that also try to claim I2S2.

The Teensy 4.x chips have three SAI peripherals, two of which are available for use as I²S, TDM etc. Typically, any audio I/O object whose name ends in 2 is using SAI2, can be used with a similar one (with no numerical ending) without conflict (no warning triangle in the Design Tool), and is shown in the info pane as only available on Teensy 4.x. I think a lot of the documentation stems from Teensy 3.x days when there was only one SAI module available, and never got updated to say "by the way, there's a second copy of this for the other I²S port, if you have a Teensy 4.x".

SAI1 actually supports 5 data lines: in I²S mode these can be configured from 4 in + 1 out to 1 out + 4 in, though the library currently only supports the first of these options as far as I know. It would be good for your purposes if it could be configured to use two input lines for TDM, but I've no idea if that's feasible. Using both available SAI modules in TDM mode is feasible, though of course then there's the challenge of achieving sample-accurate sync between them, if that's important to you.

I think Paul's project to get two CS42448 boards to stack has been stalled for a year, probably due to having more pressing matters to attend to. If you look at the link I previously posted, his ambition was to get 32 input and 32 output channels possible by stacking 2 boards (8 I/O each) on each of the two I²S ports.
 
The Teensy 4.x chips have three SAI peripherals

Thank you and apologies. I certainly went off a bit half-cock. Now that I actually downloaded the correct reference manual for the Teensy 4.0 uC what I say MIGHT make more sense. And, yes, I am stuck in Teensy 3.2 mode. I do not yet have a Teensy 4.0. I have been determinedly trying to squeeze every last cycle out of the older hardware, but alas, there are limits, so time for a new design and some modularity.

So I get it. No excuses, I had made assumptions and now I see exactly what you mean by TDM2. I kinda expected the second port to be a instantiation option for the TDM object.

At this stage I don't think sample sync actually matters. You might have realised from my initial description, this is a design for a pro-audio mixer. I use the term 'pro' in a loose sense. In that it is live sound that I am handling (me and my band mates). My Teensy 3.2 version has been operating in this role with a total of 4 separate channels, 2 reverbs, pseudo compression and EQ from the SGTL5000 and has been doing this faithfully for a few years. But the channel count is limited and the ADCs from the SGTL5000 are very noisy (single ended only) and the Teensy 3.2 is most definitely out of steam and its only doing the reverb.

So the requirements for my new design are driven by my experiences so far. Reducing ADC noise, pre-amping as much as possible in analog and ease of interfacing with the outside world. I don't want to re-invent the wheel so I am taking a really close look at the CS42448. Having said this the PCM1864 has twice the RMS input voltage range in differential mode and more flexible input gain stages. But of course I need to write the driver.

So I am taking a long slow careful look at all the options before I jump and importantly I do not want to run out of DSP power this time. So I really do want to spread the load as much as possible. This is important, because currently I am making use of multi-band EQ and auto volume (compression) within the SGTL5000. If I move away from this codec and its integrated DSP features. I will place the EQ and compression DSP load on the Teensy. So yet more work for the Teensy 4.0. Plus I want the ability to place these compression and EQ functions both pre and post mix. So a LOT more DSP power needed.

Sure it might be possible technically to get 32 channels through a single Teensy 4.0 but I would sooner have 8/12 channels of really clean audio lots of dynamic range on the ADC side without dropping into the noise floor and plenty of headroom in the DSP domain.

Thanks for your help so far.
 
No problem!

That sounds like a good architecture for keeping things modular and distributed - you just need to grab a few Teensy 4.0 when they become available, any time soon I believe... though you could use Teensy 4.1 for prototyping. Need more DSP? Just chain another Teensy in (though it will add to the latency, of course). The other advantage of the Teensy 4.1 is the ability to put PSRAM on it if you want long delays.

The AudioControl object shouldn't be too hard, you "just" need to wade through the registers on the PCM1864 and get every one exactly right. TDM slave mode might be harder, but I think if you compare TDM master vs I2S master vs I2S slave, and look at the IMXRT1060 reference manual, you should get there. I did a few days ago, trying to sync the I2S master clock to incoming SPDIF - took a while, but it seems OK.
 
Back
Top