Encoding multiple lower sampling rate audio signals in 44100 (over usb audio)

Status
Not open for further replies.
I'd like to send more audio signals over usb then 2 (I need 18 actually) and they can be lower sampling rate, so I've though of a way to packet (encode, decode) audio samples sequentially into one audio stream.

Let's say I have a 44100 signal, and I want to decode 3 signals at 14700 sampling rate from it, I would alternate samples serially from each channel and use 1 amplitude as a starting marker (1 will be filtered out from the source encoded signals) to count which sample is which signal, so in the incoming samples it would be:
sample 0 (value 1 -> seperator, means next sample si the first signal), sample 1 (value variable -> signal 1's first sample), sample 2 (value variable -> signal 2's first sample), sample 3 (value variable -> signal 3's first sample), sample 4 (value 1 -> seperator, means next sample si the first signal), sample 5 (value variable -> signal 1's second sample)
... etc

How would I go about coding this kind of seperation with teensy audio? any starting leads? I'm gonna look into coding custom

I know how to encode the signals on the computer side but I'm not sure how to efficiently code the decoding on the teensy.

Might actually be easier to do it in serial...
 
First, I'm going to assume "encode the signals on the computer side" and "decoding on the teensy" means you're sending data from PC to Teensy, but not from Teensy to PC. In USB lingo, this is called "OUT" direction. In the Teensy USB code, you'll see it called "receive".

To make this work, you've got pretty much 3 steps...

1: First, you'll need to edit the USB descriptors to tell the PC about your sample rate, number of channels, and the isochronous endpoint size. This is harder than it may seem, because the drivers on Windows, Mac and Linux don't actually support everything you could possibly describe. Also be aware most versions of Windows only support the older 1.0 USB class audio spec (dated March 18, 1998), so if you go download the USB specs at www.usb.org, make sure you're looking at the older version.

2: When you have the descriptors correct, the USB host will send you data on the isochronous endpoint. You always get 1ms of data per packet. If you've said 6 channels in the descriptors, the data will be interleaved in 1 big packet (of course, the desciptors have to specify this packet size). Sometimes the packet will have 1 extra set of the 6 samples, if the same rate isn't a perfect integer division of 1 kHz. You also need to occasionally transmit asychronous rate feedback to the PC. The code in usb_audio.cpp and usb_deb.c already does this, using a small buffer and a PI control strategy based on the difference between the actual buffered data and the ideal of the buffer being half full. You'll probably need to edit it slightly for your different sample rate.

3: After you get the 6 data streams into that buffer, you'll need to do *something* with them. The current code pulls the 2 interleaved data streams from the buffer, packs them into 2 audio blocks, and then sends them into the audio library. Maybe you'll edit the audio lib to run at a different speed? Or maybe you'll write your own code to use the data?

The reality is none of these are beginner level programming tasks.
 
Hi Paul,

I'm currently trying to modify the core to get any number of channels working on usb input/outputs, at any sample rates... And as you said, that's not an easy task...

Anyway, while I'm still not sure to understand all the code you've written, I think I've found a bug, line 333 of usb_audio.cpp :

Code:
[COLOR=#005CC5][FONT=SFMono-Regular]memset[/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular](usb_audio_transmit_buffer + len, [/FONT][/COLOR][COLOR=#005CC5][FONT=SFMono-Regular]0[/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular], num * [/FONT][/COLOR][COLOR=#005CC5][FONT=SFMono-Regular]4[/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular]);[/FONT][/COLOR]

Should not this line be ? :
Code:
[COLOR=#005CC5][FONT=SFMono-Regular]memset[/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular](usb_audio_transmit_buffer + len*2, [/FONT][/COLOR][COLOR=#005CC5][FONT=SFMono-Regular]0[/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular], num * [/FONT][/COLOR][COLOR=#005CC5][FONT=SFMono-Regular]4[/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular]);[/FONT][/COLOR]
or
Code:
[COLOR=#005CC5][FONT=SFMono-Regular]memset[/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular]([/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular]([/FONT][/COLOR][COLOR=#005CC5][FONT=SFMono-Regular]uint32_t[/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular] *)[/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular]usb_audio_transmit_buffer + len, [/FONT][/COLOR][COLOR=#005CC5][FONT=SFMono-Regular]0[/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular], num * [/FONT][/COLOR][COLOR=#005CC5][FONT=SFMono-Regular]4[/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular]);[/FONT][/COLOR]

this would be more coherent with the line 343 where you copy the buffers.
Is this correct ?
 
in other words (couldn't edit the last message after 2 hours...) :

Code:
[COLOR=#005CC5][FONT=SFMono-Regular]memset[/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular]([/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular]usb_audio_transmit_buffer + len*num_channels, [/FONT][/COLOR][COLOR=#005CC5][FONT=SFMono-Regular]0[/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular], num [/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular]* num_channels [/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular]* num_bytes_per_channels[/FONT][/COLOR][COLOR=#24292E][FONT=SFMono-Regular]);[/FONT][/COLOR]
 
Yes, looks like that may indeed be a bug. It probably should be len*2, or len*num_channels.

Will put this on my list of stuff to investigate. Realistically, it may be months until I look at this and fix it. Focusing on new hardware right now.
 
Status
Not open for further replies.
Back
Top