Multi channel audio and I2S ?

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
Hello,

It is more an intellectual personal challenge than a real project, but I try to fill the gap between evaluation boards like RPi and OrangePi and Full Digital amps like those developped by TI and ST, in the context of multi amplified speakers (with Crossover function in soft DSP).

I2S is the common input for the FDA chips. My understanding is that I2S can only address 2 audio channels, and this is a roadblock on my way.How to control several I2S inputs from one single board (RPi or other) ?

I have not seen additional modules to add more I2S connections. I have not seen ways to multiplex more than 2 channels on one I2S...

With USB, it often looks like RPi USB => USB decoder=>SPDIF=>I2S (and only 2 channels...): lot of transformations, risks of time mismatch, lots of cables for 8 channels (ex of 2 x 4 ways speakers)...

I'm surprised as many applications are now 7.1. HDMI has 8 channels...

Do I work with wrong assumptions? Do I take the problem in the wrong way? Other ways to explore?

Thanks for your help.

JMF
 
Last edited:
Thank you for the info about the USBStreamer product.

That is exactly what I was looking for. It is unfortunate that the price is that high. It is incredible how things can be at unbelievable low prices when they are massively produced, and how prices can raise fast when it is more specific applications, like in that case.

A chip like the TMS320C5533 can do the job and cost $6 (for one). Hiowever, I recognize that some engineering is required to have a full product easy to use.

I would be happy to find a cheaper design for my architecture, which means using more mainstream bricks.

JMF
 
Or get multiple stereo USB receivers hooked to the same USB controller - you can easily join them to create a single multichannel card in linux alsa http://www.diyaudio.com/forums/pc-based/93315-linux-audio-way-go-205.html#post3336980

They can have I2S output (e.g. those legacy pcm2706) feeding a DAC chip of your choice.

And DSP can be done in software.

Works fine, thanks!

I have been testing today the following 2.1 system with 3 usb devices:

HW: RPI2 with 1 PCM2702 based USB T-AMP to main speakers
1 PCM2902 based UCA202 usb card to Subwoofer
( both arranged as 4 channels virtual multi by.asoundrc)
1 CM6206 based 7.1 USB card for line input

SW: Brutefir 2ch->4ch 44100 / 16 with 32.768 taps filters.

No problem!:cool:
 
Or get multiple stereo USB receivers hooked to the same USB controller - ...http://www.diyaudio.com/forums/pc-based/93315-linux-audio-way-go-205.html#post3336980 They can have I2S output (e.g. those legacy pcm2706) feeding a DAC chip of your choice.

Yes, that is true and cost effective. The USB Audio Class 2 (UAC2) fills all the Santa Claus list, but there are no cheap products to implement it. So, as you propose, the option is to pull two USB cables and plug two 2706, to get 4 I2S outputs.

Best regards,

JMF
 
1 CM6206 based 7.1 USB card for line input

Typically even inexpensive USB audio v.1 cards run the input stream in async mode - the case of CM6206 too [alsa-devel] CM6206 S/PDIF trouble - see the Endpoint 5 IN section in lsusb ). Implementing async mode in input stream is simple since there is no control feedback involved (the incoming frames can contain any number of audio samples, the PC collects them as they arrive).

Therefore you are still having two clock domains - input soundcard clock and output USB controller clock. However, there are usually large buffers involved within the whole processing chain and it can take a long time for the miniscule clock difference to cause buffer over/underruns.
 
Therefore you are still having two clock domains - input soundcard clock and output USB controller clock.

Ok, missed that point, though for the moment never experienced the fatal broken pipe issue with brutefir. Just a few hours of continuous flawless convolution, not too bad i think.

Btw, i added the line capture feature in this set up basically to get measurements done, adjust filters, levels and so on, but then kept using it for listening purpose...
 
Last edited:
This morning i tried PCM2902 ( from UCA202) as Line Capture device for Brutefir Input instead of CM6206 i successfully tried yesterday.

It also happens to work... about 10 minutes only though, till the broken pipe error happens and brutefir aborts...:mad:

So, why CM6206 worked fine and PCM2902 did not?

Because i have been lucky enough with the crystal used with my CM6206 card and not so in the case of my UCA202?

Because these 2 chips behave in different ways for input?

According to their datasheets:

PCM2902 is clearly specified as Adaptative for output, and Asynchrous for input.

CM9206 is globally specified as adaptative, so that it might work in adaptive mode for input.

This might explain why Brutefir is stable with CM6206 and not so with PCM2902 when used in duplex ?

Any idea?
 
So, why CM6206 worked fine and PCM2902 did not?

Very likely your PCM2902 clock is farther away from the USB controller output clock than the clock of your CM6206, resulting in faster buffer fault.

CM9206 is globally specified as adaptative, so that it might work in adaptive mode for input.

That lsusb printout clearly shows CM6206 uses async input endpoint.

The actual mode is listed by the driver debug output in /proc/asound/cardX/stream0 while capturing.

Example from my dirt-cheap 5.1 usb card: for playback the card offers two configurations (altsets) - altset 1 stereo, altset 2 5.1, both adaptive, playback not running now. For capture the card offers only one altset stereo async, this one is currently running.

Code:
pavel@probook ~ $ cat /proc/asound/Audio/stream0 
USB Audio at usb-0000:00:14.0-1, full speed : USB Audio

Playback:
  Status: Stop
  Interface 1
    Altset 1
    Format: S16_LE
    Channels: 2
    Endpoint: 1 OUT (ADAPTIVE)
    Rates: 48000
  Interface 1
    Altset 2
    Format: S16_LE
    Channels: 6
    Endpoint: 1 OUT (ADAPTIVE)
    Rates: 48000

Capture:
  Status: Running
    Interface = 2
    Altset = 1
    Packet Size = 200
    Momentary freq = 48000 Hz (0x30.0000)
  Interface 2
    Altset 1
    Format: S16_LE
    Channels: 2
    Endpoint: 2 IN (ASYNC)
    Rates: 48000

Similarly for playback the corresponding altset is chosen:

2 channel playback ( aplay -c 2 ):

Code:
aplay -v  -D plughw:Audio,0 -f S16_LE -c 2 -r 48000  -t raw - < /dev/zero

Playback:
  Status: Running
    Interface = 1
    Altset = 1
    Packet Size = 200
    Momentary freq = 48000 Hz (0x30.0000)
  Interface 1
    Altset 1
    Format: S16_LE
    Channels: 2
    Endpoint: 1 OUT (ADAPTIVE)
    Rates: 48000
  Interface 1
    Altset 2
    Format: S16_LE
    Channels: 6
    Endpoint: 1 OUT (ADAPTIVE)
    Rates: 48000

Capture:
  Status: Stop
  Interface 2
    Altset 1
    Format: S16_LE
    Channels: 2
    Endpoint: 2 IN (ASYNC)
    Rates: 48000

For 6 channel (i.e. 5.1) playback the altset 2 is automatically used:

Code:
aplay -v  -D plughw:Audio,0 -f S16_LE -c 6 -r 48000  -t raw - < /dev/zero

Playback:
  Status: Running
    Interface = 1
    Altset = 2
    Packet Size = 600
    Momentary freq = 48000 Hz (0x30.0000)
  Interface 1
    Altset 1
    Format: S16_LE
    Channels: 2
    Endpoint: 1 OUT (ADAPTIVE)
    Rates: 48000
  Interface 1
    Altset 2
    Format: S16_LE
    Channels: 6
    Endpoint: 1 OUT (ADAPTIVE)
    Rates: 48000
....

Also notice the increased USB Packet Size - 6 channels take 3 times more data than 2 channels.

Linux audio is no black box, we do not have to guess what is going on :)
 
Last edited:
Thanks, more than an answer, your post is an unvaluable how-to for dummies like me!:cool:

Now hooked a TE7022L based Ministreamer instead as capture device.

Apart from the bonus 24/96 capability, with this one your "cat /proc/asound/... " check shows adaptative behaviour for capture mode too.
 
Last edited:
It works fine, thanks!

My ministreamer is connected as capture device to the spdif out of a cd player and brutefir to a "multi" 4 channels playback device.

3 USB devices team working!

Brutefir I/O:


# I/O:

input "in_L", "in_R" {
device: "alsa" {device: "hw:miniStreamer"; };
channels: 2/0,1;
sample: "S16_LE"; # jugar con esto
};

output "out_L", "out_R", "L_2", "R_2" {
device: "alsa" {device: "multi"; };
channels: 4/0,1,2,3;
sample: "S16_LE";
dither: true; # opcional
};

miniDSP Ltd miniStreamer at usb-bcm2708_usb-1.3, full speed : USB Audio

Playback:
Status: Stop
Interface 3
Altset 1
Format: S16_LE
Channels: 2
Endpoint: 3 OUT (ADAPTIVE)
Rates: 8000, 16000, 32000, 44100, 48000, 96000
Interface 3
Altset 2
Format: S24_3LE
Channels: 2
Endpoint: 3 OUT (ADAPTIVE)
Rates: 8000, 16000, 32000, 44100, 48000, 96000

Capture:
Status: Running
Interface = 2
Altset = 1
Packet Size = 224
Momentary freq = 44100 Hz (0x2c.199a)
Interface 2
Altset 1
Format: S16_LE
Channels: 2
Endpoint: 2 IN (ADAPTIVE)
Rates: 8000, 16000, 32000, 44100, 48000, 96000
Interface 2
Altset 2
Format: S24_3LE
Channels: 2
Endpoint: 2 IN (ADAPTIVE)
Rates: 8000, 16000, 32000, 44100, 48000, 96000
 
Last edited:
That USBstreamer looks like a neat product.


Hello,

... My understanding is that I2S can only address 2 audio channels, and this is a roadblock on my way.How to control several I2S inputs from one single board (RPi or other) ?

I have not seen additional modules to add more I2S connections. I have not seen ways to multiplex more than 2 channels on one I2S...

With USB, it often looks like RPi USB => USB decoder=>SPDIF=>I2S (and only 2 channels...): lot of transformations, risks of time mismatch, lots of cables for 8 channels (ex of 2 x 4 ways speakers)...

I'm surprised as many applications are now 7.1. HDMI has 8 channels...

Do I work with wrong assumptions? Do I take the problem in the wrong way? Other ways to explore?

Thanks for your help.

JMF

Had a read through this thread and no one seems to have tackled the original question over I2S with lots of channels. Just thought I would add that a lot of I2S interfaces also support use of left justified, right justified (generally 2 channels) or they support TDM mode.

Cirrus Logic AN301 application note explains about the two ways TDM operates, but in either case it allows use of 2, 4, 8, or 16 (possibly more?) channels using the same interface as I2S with only 1 data line. I did look into the RPi to see if it supports TDM mode, could not find anything, but maybe this is just the lack of driver support.

Given that USBStreamer uses an XMOS device I am a little surprised it does not support TDM data.


Cheers.
 
That USBstreamer looks like a neat product.

...

Given that USBStreamer uses an XMOS device I am a little surprised it does not support TDM data.


Cheers.

I find this device interesting too, especially due to the recent availability of a new firmware allowing ADAT operation, thus TDM, though in a special context.

Features
10 x IN, 10 x OUT multi-channel USB audio interface (8 x I2S I/O + 2 x Toslink)
Native support up to 24bit / 192kHz
USB 2.0 High speed and Audio class 2.0 device
Asynchronous USB synchronization
Thesycon ASIO Win driver provided with support for Win10 (signed drivers)
Driverless support under Mac OSx. Sound card aggregate mode allows combining of multiple units
Buffered 8 ch I2S in&out signals on 2mm header
Toslink (optical) transmitter and receiver
Flexible board powering option: USB powered or External DC input power
Tiny form factor of 62x42mm

NEW! Updated firmware now supports ADAT transfer for up to 8channels @ 48/44.1k (In/Out) on optical connector. See your user downloads for the custom firmware.
 
From what I see in the docs the ministreamer has 4 x I2S in/outputs (i.e. 8 channels in/out).

Yes it has. One pair of each are used to provide spdif I/O, and the other pair for I2S connections.

Cannot tell you if all 4 work toghether, don't have any i2s ADC nor DAC at hand. Only use SPDIF I/O.

But i tried to change my brutefir_confir using the miniStreamer as 4 channels output device...

# I/O:

input "in_L", "in_R" {
device: "alsa" {device: "hw:miniStreamer"; };
channels: 2/0,1;
sample: "S16_LE"; # jugar con esto
};

output "out_L", "out_R", "L_2", "R_2" {
device: "alsa" {device: "hw:miniStreamer"; };
channels: 4/0,1,2,3;
sample: "S16_LE";
dither: true; # opcional
};

... and no way, it doesn't work!

ALSA I/O: Could not set audio output parameters for "hw:miniStreamer":
Failed to set channel count to 4: Invalid argument.
Failed to init output device.
Failed to initialise digital audio interfaces.

In fact we have 2 devices inside 1 ministreamer:

card 3: miniStreamer [miniStreamer], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 3: miniStreamer [miniStreamer], device 1: USB Audio [USB Audio #1]
Subdevices: 1/1
Subdevice #0: subdevice #0

Maybe it would work building a multi virtual device joining hw:3,0 and hw:3,1 ( 3 in my case, of course). Will try later.
 
Last edited:
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.