Realtime Audio Streaming using Teensy 3.2

Status
Not open for further replies.
Hi, I have been thinking of setting up a realtime wireless(read Wifi) stereo audio streaming using Teensy3.2 board, so that i can hear what my TV plays even in the kitchen :p
(I'd refrain from using using off the shelf Bluetooth modules as I also want this to be a learning exercise)

Disclaimer: The premise on which I ascertained it to be feasible is that even a sampling rate of 44Khz @10bit depth we are talking of data rates of 440Kbps which I believe should be achievable.


Brief: The idea is to sample the stereo audio from the headphone jack connected to phone/TV etc. using the Teensy 3.2 (read it has twin ADC channels) post voltage conditioning and level shifting.
Now, the digital data will be sent over a wifi link (ESP8266 or NodeMCU) to another MCU with similar ESP/NodeMCU frontend, where it will be converted back to Analog stereo signal and fed through the stereo jack to another set of speakers. I came across various projects which are sampling mono channel audio and saving it or playing an saved audio file using an arduino uno/ equivalent, but none come close to my requirements

Now my questions to the informed members here:-
a) Does it sound feasible?
b) Is Teensy 3.2 an overkill
c) What should be the preferred wireless module of choice? ESP series(8266-01 or NodeMCU with 12E) or Nordic NRF24L01+?
d) Is it advisable to use the Arduino Due at the receiving end as it has Two DAC outputs? (Recommendations on minimum MCU required to achieve it)


I have not dwelled upon the following issues, which I am aware of, but not knowledgeable about:

a) The effect on performance due to latencies involved in transferring data at both ends from RF frontend to MCUs? Should I use SPI or Serial? As the data will be send very frequently the number of transfers will be large IMO with small payloads
b) Limited SRAM of the MCU to buffer the sampled signal/ received data.
c) ADC sampling rate achievable from the MCU.

I understand that a lot of complexities (probably) have been left untouched so I'd request the members here to enlighten.
 
A few quick points:
Definitely should be do able
at $20 dollars a pop who cares about overkill? The teensy isn't going to be the price driver here (I think). Though importanly teensy 3.2 has two ADCs that can be used symulataneously which is good for stereo, I dont know if the smaller/lower versions do.
You will need something with a pair of DACs at the other end, teensy 3.5 has a pair if you like. Keeping it all teensy will make it much easier, it will allow you to directly use the audio library. I'm sure you can use it with arduino, but I'm also sure there'll be more headaches.

The latency might be insufferable, bluetooth headphones are a thing so clearly wireless audio can be send fast enough, but it doesn't take much delay to ruin your watching. You'll have to think carefully about how the data is transfered, you'll probably want to prefer to broadcast the data without any acknoledgement for example as you'd rather loose sound for 1 second than be 1 second behind for the rest of the film (cumalative!).
 
at $20 dollars a pop who cares about overkill? The teensy isn't going to be the price driver here (I think).

As much as I agree with you, but for me one of the motivations of a DIY project is to achieve similar results (maybe marginally inferior) as that of commercial off the shelf item with lesser cost. With two $25 (yes it costs me that much with duties etc ) teensys and accessories the project cost shoots to about $65. Now with that price point there is Chromecast 2 and other similar products. Agreed, it doesnt do exactly what i need but that concept also involves receiving and decoding video as well audio data. (Wonder how it does it).

The latency might be insufferable, bluetooth headphones are a thing so clearly wireless audio can be send fast enough,

I wasn't referring to the wireless transmission latency. What I am more concerned about is the SPI or Serial data latency between the wifi module and the teensy (mcu) at both ends. Or maybe I am just overthinking.


Anywho, I was expecting a little more technical insight along with feasibility analysis(which Edward has already done, Thanks for that) by some experienced members here.
Thanking in anticipation!!!
 
Last edited:
As much as I agree with you, but for me one of the motivations of a DIY project is to achieve similar results (possibly marginally inferior) as that of commercial off the shelf item with lesser cost. With two $25 (yes it costs me that much with duties etc ) teensys and accessories the project cost shoots to about $65. Now with that price point there is Chromecast 2 and other similar products. Agreed, it doesnt do exactly what i need but that concept also involves receiving and decoding video as well audio data. (Wonder how it does it).

Fair enough, I mean - hard to do but good to try. I usually pick up my teensy's when ordering PCBs from OSH park, they're about $20 and shipping included - if you're doing PCB design at any point it's a nice extra. Maybe that'll help. I've not scoured the entire internet but I think you'd be hard pressed to find a better bang-for-buck than the teensy range, which you can look at here.
Write your code first, and see which it'll fit in. Without a firm idea of what you're going to do/use there's no way to say what's best. Noatably the teensy 3.2 has two ADCs, so you can sample audio directly with that at one end. You could use a 3.5 at the other to use both it's DACs to directly drive your audio circuit at the other - that might get you good (latency) results. But you'll have to compare the different prices for parts and find the most cost effective option.

I wasn't referring to the wireless transmission latency. What I am more concerned about is the SPI or Serial data latency between the wifi module and the teensy (mcu) at both ends. Or maybe I am just overthinking.

I was referring to the whole system, and simply stating that because your project is available in commercial systems it is clearly feasable. Alas no you are not overthinking, the whole thing stacks up to the total latency and one slow process will ruin all the others. Working out the latency of each thing is not that easy as you probably guessed and I'm not aware of a quick way to do it. Buffers can be a big pain in low latency code, you should be able to find the lengths for various interfaces in reference.

Generally your best bet is to outline the system in terms of major components and then eat through data sheets to have a good guess as to the timings. Teensy has built in the object elapsed millis which is good for seeing how fast your main code is running,if you want to investigate something run it mutliple times and then average. If you've got anything lying around you can use to try out ideas before buying parts that will help; if not it's datasheet time!
Outline your system, make an over estimate of the latency, if it's too great find the weakest link and upgrade it.

If you hadn't already found it the audio GUI is a grand place to start. I've noticed there's only options to use USB/I2C for digital audio in/out, so there might some problems there using UART/SPI but it's still a good place to start. Somewhere there's a library for using both ADCs at once wich might interest you, particularly if you decide to transmit raw data rather than encoding it at all.
 
Thanks!! that lifted my spirits a little bit. You are right, I should get started with it and start hitting roadblocks. Having a specific query then might entail more specific responses. Thanks again.
 
Hi, I have been thinking of setting up a realtime wireless(read Wifi) stereo audio streaming using Teensy3.2 board, so that i can hear what my TV plays even in the kitchen :p
(I'd refrain from using using off the shelf Bluetooth modules as I also want this to be a learning exercise)

Disclaimer: The premise on which I ascertained it to be feasible is that even a sampling rate of 44Khz @10bit depth we are talking of data rates of 440Kbps which I believe should be achievable.


Brief: The idea is to sample the stereo audio from the headphone jack connected to phone/TV etc. using the Teensy 3.2 (read it has twin ADC channels) post voltage conditioning and level shifting.
Now, the digital data will be sent over a wifi link (ESP8266 or NodeMCU) to another MCU with similar ESP/NodeMCU frontend, where it will be converted back to Analog stereo signal and fed through the stereo jack to another set of speakers. I came across various projects which are sampling mono channel audio and saving it or playing an saved audio file using an arduino uno/ equivalent, but none come close to my requirements

Now my questions to the informed members here:-
a) Does it sound feasible?
b) Is Teensy 3.2 an overkill
c) What should be the preferred wireless module of choice? ESP series(8266-01 or NodeMCU with 12E) or Nordic NRF24L01+?
d) Is it advisable to use the Arduino Due at the receiving end as it has Two DAC outputs? (Recommendations on minimum MCU required to achieve it)


I have not dwelled upon the following issues, which I am aware of, but not knowledgeable about:

a) The effect on performance due to latencies involved in transferring data at both ends from RF frontend to MCUs? Should I use SPI or Serial? As the data will be send very frequently the number of transfers will be large IMO with small payloads
b) Limited SRAM of the MCU to buffer the sampled signal/ received data.
c) ADC sampling rate achievable from the MCU.

I understand that a lot of complexities (probably) have been left untouched so I'd request the members here to enlighten.

Hi,
My friends and I are trying to do a similar project. Were you successful? Do you know any other websites or tutorials that can give us more information about the hardware connection and software details? Do you think teensy 3.6 will be a better option than teensy 3.2?
Thank you.
 
Solution for Teensy 3.6 (could be used for Teensy 3.2 too)

Hi,
My friends and I are trying to do a similar project. Were you successful? Do you know any other websites or tutorials that can give us more information about the hardware connection and software details? Do you think teensy 3.6 will be a better option than teensy 3.2?
Thank you.

Hi
I'm new here, but I think I have probably a solution for you.
Look at my code and have fun.

//******************************************************************************************************
// Transmitter program to transmit 16 bit audio data (audio streaming) from LINEIN of Teensy Audio board
// to nrf24l01+ module with a Teensy 3.6 (selected CPU speed = 180 MHz)
//******************************************************************************************************
// used Hardware components:
// Teensy 3.6 board, Teensy Audio board, nrf24l01+ RF module
// wiring connections:
//
// From Teensy 3.6 to Teensy Audio board only a few pins are connected, (only 9 pins are wired)
// the others from Audio board are not connected:
// Teensy 3.6 pin GND (left pin of pin 0) wired to pin GND of Audio board (1:1)
// Teensy 3.6 pin 9 wired to pin BCLK of Audio board (1:1)
// Teensy 3.6 pin 11 wired to pin MCLK of Audio board (1:1)
// Teensy 3.6 pin 13 wired to pin RX of Audio board (1:1)
// Teensy 3.6 pin 18 wired to pin SDA of Audio board (1:1)
// Teensy 3.6 pin 19 wired to pin SCL of Audio board (1:1)
// Teensy 3.6 pin 22 wired to pin TX of Audio board (1:1)
// Teensy 3.6 pin 23 wired to pin LRCLK of Audio board (1:1)
// Teensy 3.6 pin 3.3V (left pin of pin 23) wired to pin +3.3V of Audio board (1:1)
//
// From Teensy 3.6 to nrf24l01+ module the following pins are connected:
// Teensy 3.6 pin 7 wired to pin MOSI of nrf24l01+
// Teensy 3.6 pin 8 wired to pin MISO of nrf24l01+
// Teensy 3.6 pin 3.3V (right pin of pin 12) wired to pin 3.3V of nrf24l01+
// Teensy 3.6 pin GND (right pin of pin 13) wired to pin GND of nrf24l01+
// Teensy 3.6 pin 14 wired to pin SCK of nrf24l01+
// Teensy 3.6 pin 15 wired to pin CSN of nrf24l01+
// Teensy 3.6 pin 21 wired to pin CE of nrf24l01+
// pin IRQ of nrf24l01+ is not connected
//
// 3.5mm or 6.3mm audio jack wired to LINEIN of Teensy Audio board for analog audio source
//******************************************************************************************************

#include <Audio.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define audiobuffersize 128 // one block in audio library has 128 values of 2 byte

RF24 radio(21, 15); // Teensy 3.6 pin 21=CE, Teensy 3.6 pin 15=CSN

const uint64_t pipeaddress = 0xFA51AA55AFLL; //nrf24 pipe address must be the same for transmitter and receiver

// GUItool: begin automatically generated code
// defs for audio library
AudioInputI2S i2s1;
AudioRecordQueue queue1;
AudioConnection patchCord1(i2s1, 0, queue1, 0);
AudioConnection patchCord2(i2s1, 1, queue1, 1);
AudioControlSGTL5000 sgtl5000_1;
// GUItool: end automatically generated code

uint8_t bufr[audiobuffersize * 2]; //buffer to hold 256 byte of audio data
uint8_t errorcount; //error counter for nrf24 transfer errors

void setup()
{
//Serial.begin(9600);
//Serial.println("Start Transmitter");
errorcount = 0;

AudioMemory(64); //give the Audio Library some memory to work with

// use alternate SPI pins for nrf24
SPI.setMOSI(7);
SPI.setMISO(8);
SPI.setSCK(14);
SPI.begin();

// Setup the SGTL5000 AIC
//sgtl5000_1.enable(); //activate AIC
sgtl5000_1.enable(); //Enable the SGTL5000
sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN); //which input to use LINEIN
sgtl5000_1.lineInLevel(3);
sgtl5000_1.adcHighPassFilterDisable();

radio.begin();
radio.setPayloadSize(32); //this is the maximum payload size for a packet transfer of nrf24
radio.setAutoAck(false); // no Ack
radio.disableCRC(); // no CRC
radio.setPALevel(RF24_PA_MAX);
radio.setDataRate(RF24_2MBPS);
delay(50);

radio.openWritingPipe(pipeaddress);
radio.stopListening(); // switch to transmit mode
delay(50);

queue1.begin();
}

void loop()
{
if (queue1.available())
{
memcpy(bufr, queue1.readBuffer(), audiobuffersize * 2); // copy 256 byte audio data from audio library buffer to bufr
queue1.freeBuffer();

// send audio data in 8 packages a 32 byte to the FIFO buffers
for (int i=0; i<8; i++)
{
if (!radio.writeFast(&bufr[i * 32],32)) errorcount++;
}
if (errorcount > 0)
{
//Serial.print("Errors: ");
//Serial.println(errorcount);
errorcount = 0;
}
}
}

//***************************************************************************************************
// Receiver program to get 16 bit audio data (audio streaming) from nrf24l01+ module to the headphone
// and LINEOUT of Teensy Audio board with a Teensy 3.6 (selected CPU speed = 180 MHz)
//***************************************************************************************************
// used Hardware components:
// Teensy 3.6 board, Teensy Audio board, nrf24l01+ RF module
// wiring connections:
//
// From Teensy 3.6 to Teensy Audio board only a few pins are connected, (only 9 pins are wired)
// the others from Audio board are not connected:
// Teensy 3.6 pin GND (left pin of pin 0) wired to pin GND of Audio board (1:1)
// Teensy 3.6 pin 9 wired to pin BCLK of Audio board (1:1)
// Teensy 3.6 pin 11 wired to pin MCLK of Audio board (1:1)
// Teensy 3.6 pin 13 wired to pin RX of Audio board (1:1)
// Teensy 3.6 pin 18 wired to pin SDA of Audio board (1:1)
// Teensy 3.6 pin 19 wired to pin SCL of Audio board (1:1)
// Teensy 3.6 pin 22 wired to pin TX of Audio board (1:1)
// Teensy 3.6 pin 23 wired to pin LRCLK of Audio board (1:1)
// Teensy 3.6 pin 3.3V (left pin of pin 23) wired to pin +3.3V of Audio board (1:1)
//
// From Teensy 3.6 to nrf24l01+ module the following pins are connected:
// Teensy 3.6 pin 7 wired to pin MOSI of nrf24l01+
// Teensy 3.6 pin 8 wired to pin MISO of nrf24l01+
// Teensy 3.6 pin 3.3V (right pin of pin 12) wired to pin 3.3V of nrf24l01+
// Teensy 3.6 pin GND (right pin of pin 13) wired to pin GND of nrf24l01+
// Teensy 3.6 pin 14 wired to pin SCK of nrf24l01+
// Teensy 3.6 pin 15 wired to pin CSN of nrf24l01+
// Teensy 3.6 pin 21 wired to pin CE of nrf24l01+
// pin IRQ of nrf24l01+ is not connected
//
// 3.5mm or 6.3mm audio jack wired to LINEOUT of Teensy Audio board or headphone connected to
// headphone jack on Teensy Audio board
//***************************************************************************************************

#include <Audio.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define audiobuffersize 128 // one block in audio library has 128 values of 2 byte

RF24 radio(21, 15); // Teensy 3.6 pin 21=CE, Teensy 3.6 pin 15=CSN

const uint64_t pipeaddress = 0xFA51AA55AFLL; //nrf24 pipe address must be the same for transmitter and receiver

// GUItool: begin automatically generated code
// defs for audio library
AudioPlayQueue queue1;
AudioOutputI2S i2s1;
AudioConnection patchCord1(queue1, 0, i2s1, 0);
AudioConnection patchCord2(queue1, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1;
// GUItool: end automatically generated code

uint8_t bufr[audiobuffersize * 2]; //buffer to hold 256 byte of audio data
uint8_t bufcount; //received nrf24l01+ packet counter

void setup()
{
//Serial.begin(9600);
bufcount = 0;

AudioMemory(64); //give the Audio Library some memory to work with

// use alternate SPI pins for nrf24
SPI.setMOSI(7);
SPI.setMISO(8);
SPI.setSCK(14);
SPI.begin();

// Setup the SGTL5000 AIC
sgtl5000_1.enable(); //Enable the SGTL5000
sgtl5000_1.volume(0.4); //set the headphone volume
sgtl5000_1.lineOutLevel(5, 5);

radio.begin();
radio.setPayloadSize(32); //this is the maximum payload size for a packet transfer of nrf24
radio.setAutoAck(false); //no Ack
radio.disableCRC(); //no CRC
radio.setPALevel(RF24_PA_MAX);
radio.setDataRate(RF24_2MBPS);
delay(100);

radio.openReadingPipe(0, pipeaddress);
delay(50);

radio.startListening();
}

void loop()
{
if (radio.available())
{
// get 8 packets a 32 byte audio data
if ((bufcount >= 0) && (bufcount < 8))
{
// get 32 byte audio packet data
radio.read(&bufr[bufcount * 32], 32);

// test if all 8 packets received
if (bufcount == 7)
{
bufcount = 0;
int16_t *p = queue1.getBuffer();
memcpy(p, &bufr[0], (audiobuffersize * 2));
queue1.playBuffer();
} else bufcount++;
}
}
}
 
Status
Not open for further replies.
Back
Top