Teensy 3.1 audio output advice

Status
Not open for further replies.

tanml

Member
Hey guys,

So I'm working on a project that's looking to use the teensy 3.1 to receive audio from a Bluetooth receiver, and looking to output that audio through a speaker. I'm pretty sure the teensy audio shield will be able to do what I need, but I'm a little unsure of how to go about it.

Basically, how would I hook up the Bluetooth module to the teensy using the audio shield, and then connect it to an audio amplifier to a speaker.

I'm using the Bluesmirf silver module from Sparkfun https://www.sparkfun.com/products/12577

And the DTA-100a amplifier from Dayton Audio. http://www.parts-express.com/dayton-audio-dta-100a-class-t-digital-mini-amplifier-50-wpc--300-383

I'm not entirely sure where to hook up the output of the Bluetooth module on the Teensy. As for outputting to the audio amplifier, does the audio shield have a headphone out jack on it?
 
You'll need to hook up the bluetooth module to the TX and RX of the Teensy 3.1 and they should be connected cross ways like the TX of bluetooth to RX of Teensy and RX of bluetooth to TX of teensy. Now first, I would suggest to check if the bluetooth is working fine for that you need to send packets from the transmitter.
After you are able to do this. I think you'll have to look into how the packets are being transffered over Bluetooth protocol for mp3 audio and I think you will not require the DTA-100a audio amplifier as the audio shield that Teensy has is itself just an amplifier, I mean in case of arduino the processor is incapable of decoding the MP3 but Teensy processor is very powerful and able to decode it itself , So in case of arduino you require a MP3 shield to decode it and then a audio amplifier to amplify the sound being created but in case of teensy you just need the Amplifire.
I would ask you to first get enough knowledge on MP3 and Bluetooth then proceed towards this project and if possible read a book, there is nice book by Tom Igoe named "Making things Talk" by O'Reilly publication. Its a very nice book and will help in this project a lot. Thought its on Arduino, all the same is applicable to Teensy also.(You can download it from any torrent site)
And Audio shield is not having any Jack but it is having pin out for same. So you need to attach a TRS Jack to it. Also The audio libarary that Paul has made is extracting data from SD card, I am not sure how will Library work over real time data transfer over Bluetooth. Or maybe you 1st try and tranfer a mp3 file from bluetooth to SD card and try it play and then finally go over realtime mp3 through bluetooth.
Right now, I have very little info on MP3/Audio decoding being done on Teensy but shall get back to you with more details once, I have more knowledge on it.
 
Does the BlueSMiRF Silver actually handle audio data? From Sparkfun's description, it seems to be designed for Bluetooth serial, not audio.

Perhaps this could be made to work, for low quality audio, if a Bluetooth-enabled PC (or Mac) runs software that reads audio, converts to a low bitrate that can be transported by the limited 11 bytes/sec speed, and then sends as Bluetooth serial. Then you'd need to add an object in the audio library that can receive the serial stream and upsample to 44.1 kHz. The memory player object is probably the closest, since it has lossy u-law decoding and 11.025 to 44.1 upsampling by linear interpolation. That would get you right into the upper limit of standard serial baud rates. But CD quality mono is 8X faster, and stereo is 16X faster than can be transmitted with 115200 baud 8N1 format serial.

At some point I would like to add support in the audio library for a wireless audio module. Does anyone know of such a module that's easy to use and actually supports Bluetooth audio profile (interoperable with Bluetooth stuff like speakers and headsets), rather than merely Bluetooth serial?
 
Hi Paul,
I would also like to mention that there are chips like CC2500 series that are capable of transmitting at 2.5 Ghz which after writing significant amount of code(Witing the bluetooth protocols) can be made compatible with Bluetooth . These are cheap as compared to the bluetooth modules mentioned above. This will make the project cost effective as well.
I am not sure of this solution though. I mean can any device that is able to tranmit at a frequency of 2.5Ghz be made compatible to bluetooth after coding the significant protocols.
 
That BC127 module (the one on Sparkfun's "Purpletooth Jamboree") looks like it could be a really interesting alternate audio shield.

Sparkfun's PCB looks like it breaks out most or maybe even all of the BC127 pins, but I couldn't find all those pads on their schematic. I wonder if the I2S pins are available? Maybe it could connect to the Teensy 3.1 and run with the audio library?

I also didn't find the docs on the BC127's serial command language, but obviously the info must be available somewhere, since someone wrote this BC127 library. Anyone know where that info might be?
 
I purchased one of the Sparkfun BC127 breakout boards. I have no idea when I'll ever manage to get time to do much with it, but at least it'll be here if I do....
 
Thanks for the insightful replies.

The Bluesmirf silver only supports SPP, but the audio I'm transferring doesn't need to be high quality; I'm planning to sample at 5 kHz from a microphone. In this case, I figured I might be able to get away with using SPP. I wanted to use the RN-52 module that Sparkfun had, but it can only act as a sink for audio. The BC127 module looks pretty promising though, its a shame it wasn't around when I was picking out parts.

I'm planning to use two Bluesmirf/Teensy pairs to transmit and receive audio data. I'm just unsure of how I would send that data over from the Bluesmirf receiver to the Teensy 3.1, and then have the Teensy output that data as audio to a speaker. Since I'm using a 50W speaker, I thought that the DTA-100a audio amplifier was necessary to power the speaker.
 
For sending the data over SPP, you'll need to send data over Serial communication that means you'll have to decode the MP3 using a program(As there is no standard funcationality in windows to send the MP3 data over bluetooth through serial communication) in Windows itself and for that you'll need to write a code to decode the MP3 and send the data packet through serial port to teensy via bluetooth as a medium. Or you could just use FTP to transfer the complete MP3 file and leave the decoding to teensy. Again, I am not sure if any of this has been done previously.
Also there is excellent program that, I think can be used to accomplish this daunting task easily. There is a langauge named Processing on which Arduino was originally made, It also has a serial library that is compatbile for arduino related projects but only difficulty now will be decoding and sending MP3 Packets. I could have written the code but, I have very less time and I just have many exams coming up I,but promise to help you out as soon as I get free till you are on your own.
 
I found the site for streaming and playing MP3 files in Processing

"http://www.tree-axis.com/Ess/mp3_import.html"

Using this we already have a decoder and all the code is made available only a small tweak needs to be done here instead of sending the data to speaker the program must send the data to serial port..
 
Here is another good code

http://jorgecardoso.eu/processing/ID3/ID3.java

that is extracting the ID3 tag out of the MP3 file, Tanml , I would request you to please modify this code a little bit and check if you are able to recieve data on teensy through bluetooth. If this works then, I think we, will need to extract data(Instead of just ID3 tag a loop for EOF) and perform IFFT and that should give us the required data stream(Raw sound bits) and that could be just recieved through Teensy and send to its DAC to get a output.. this shall just b very basic mono sound ouput.. Later it can be modified to get a better sound quality through using the shield that Paul has designed .
 
As far as I know, nobody has tried decoding MP3 actually on Teensy 3. In theory, it might be possible using carefully crafted code. I've heard stories that it's been done, at least in some limited capacity, on some of the NXP ARM microcontrollers. I imagine getting this working would take a lot of effort.

As much as I'd like to do this, I have so many other things planned that the odds of me even looking into MP3 decoding on Teensy in 2014 are pretty much zero.
 
We need not do the MP3 decoding on Teensy3.1 . All we need to do here is just get the packets from Serial communication that will already be decoded . We just need to channlise them to Audio module .
 
I don't think I'll be dealing with MP3s. Basically, I'm just sending a digitized Mic signal through bluetooth to the teensy audio adaptor.

It would be appreciated if someone could help me out programming the Teensy to receive a signal through serial, and then passing that signal to the headphone jack using the audio adaptor. Or, tell me if it's even possible. I'm pretty new to programming.
 
I think it would be better that before going directly to sending the data from a digitized mic through bluetooth to the teensy audio adapter. It would better if you could send them serially from your computer to the Teensy using UART communication then we can move to sending the same through bluetooth.
 
For now, I've settled on simply using analog read in combination with interval timer to obtain signal from the microphone at a desired sampling rate. I've also managed to send it over bluetooth by simply using Serial1.print. Paul mentioned that I need to modify the audio library to receive from the serial stream. Any idea on how I would go about doing this?
 
Actually, after hooking up the output of the receiving teensy using analogwrite and a oscilloscope, I've realized something is going wrong during the bluetooth serial transfer. I'm using analogRead with InterruptTimer to read in a sine wave at the transmitting end, using Serial.write to send it to the receiving bluetooth. The receiving bluetooth is hooked up to another teensy, and using using analogWrite to create an analog signal from Serial1.read doesn't give me the expected results. Instead of getting a sinewave, I'm getting what appears to be distorted square waves. Any idea how to solve this? I've attached my code for the transmitter and receiver.

Code:
//Transmitter
//Program for continous analog input at desired sampling rate
//First, define our variables
int led = 13; //Power led 
int SAMPLE_RATE_HZ = 8000; //Sampling rate
int val; //Variable for microphone input
const int AUDIO_INPUT_PIN = 14; //The signal will feed into pin 14
const int ANALOG_READ_RESOLUTION = 12; //12 bit resolution
const int ANALOG_READ_AVERAGING = 16;

IntervalTimer samplingTimer; //Set up the interval timer, which lets us specify sampling rate

void setup()
{
  pinMode(led, OUTPUT); //Turn on power led
  digitalWrite(led, HIGH);
  pinMode(AUDIO_INPUT_PIN, INPUT);
  analogReadResolution(ANALOG_READ_RESOLUTION);
  analogReadAveraging(ANALOG_READ_AVERAGING);
  analogWriteResolution(12);
  
  Serial.begin(115200); //Open communications with the USB port if necessary
  Serial1.begin(115200); //Open communications with the Bluetooth module
  delay(3000);
  Serial1.print("$"); //Place Transceiver in command mode
  Serial1.print("$");
  Serial1.print("$");
  delay(100);
  Serial1.println("C"); //Tell it to connect to receiver
  delay(5000);
  samplingBegin(); //Begin reading audio immediately
  
}

void loop()
{
  noInterrupts();
  int val_copy = val; //Can't access the data when it's in use by the interrupt, so must temporarily stop it.
  interrupts();
  
  Serial1.write(val_copy); //Send the data to bluetooth module
  
  
}

void samplingBegin() //Set up sampling rate
{
  samplingTimer.begin(samplingCallback, 1000000/SAMPLE_RATE_HZ);
}

void samplingCallback() //Continously read in analog input (noise if no input)
{
  val = analogRead(AUDIO_INPUT_PIN);
}

Code:
//Receiver code
int led = 13; //Power led 

IntervalTimer samplingTimer; //Set up the interval timer, which lets us specify sampling rate

void setup()
{
  pinMode(led, OUTPUT); //Turn on power led
  digitalWrite(led, HIGH);
  pinMode(AUDIO_INPUT_PIN, INPUT);
  analogWriteResolution(12);
  
  Serial.begin(115200); //Open communications with the USB port if necessary
  Serial1.begin(115200); //Open commmunications with bluetooth

  
}

void loop()
{

 int val= Serial1.read();
 analogWrite(A14, val);

}
 
Just a quick update.

I may have figured out how to write the actual voltages that are being produced by the microphone using the receiver. I had to send the voltage signals using print and adding characters that mark the beginning and end of the integer to be reassembled by the receiver. This ensures that if the transmitter sends a value of 3134, the receiver is able to receive exactly 3134 and store it in an int to be used with analogWrite. However, I'm not sure if I solved the issue of having the signal reproduced temporally at the receiving end, which is necessary for reproducing frequency.

This leaves me with two issues still. One is how to actually get the audio adapter to output the wirelessly received microphone signal through the head phone jack. I've figured I might be able to get away with the teensy analogWriting the signal, and routing that to the microphone input of the audio adapter, then using the passThrough example. Would that work?

Second, it appears that if I send signals at too high of a sample rate (over 2000 Hz), it'll stream fine for a minute, then just stop streaming. The Bluesmirfs are still connected to eachother as indicated by their LEDs. I'm only able to fix this by power cycling one of the Bluesmirfs. Does it seem like this issue can be solved by increasing the baud rate on the Bluesmirfs? They're capable of much higher than 115200. Or is it an issue with the serial functions of the teensy?

I've attached the code I have so far, just in case anyone wants to take a look at it.

Code:
//Transmitter side
int led = 13; //Power led 
int SAMPLE_RATE_HZ = 2000; //Sampling rate
volatile int val; //Variable for microphone input
const int AUDIO_INPUT_PIN = 14; //The signal will feed into pin 14
const int ANALOG_READ_RESOLUTION = 12; //12 bit resolution
const int ANALOG_READ_AVERAGING = 16;
IntervalTimer samplingTimer; //Set up the interval timer, which lets us specify sampling rate

void setup()
{
  pinMode(led, OUTPUT);
  digitalWrite(led, HIGH); //Turn on the LED o the Teensy
  Serial.begin(115200);
  Serial1.begin(115200); //Begin serial communications with the Bluetooth and the USB if necessary
  analogReadResolution(ANALOG_READ_RESOLUTION);
  analogReadAveraging(ANALOG_READ_AVERAGING); //Set Analog read resolution and averaging
  
  delay(100);

  samplingBegin(); //Begin reading audio immediately

}

void loop() //Do nothing, the interrupt timers handle data acquisition and sending
{ 

}

void samplingBegin() //Set up sampling rate
{
  samplingTimer.begin(samplingCallback, 1000000/SAMPLE_RATE_HZ);
}

void samplingCallback() //Continously read in analog input (noise if no input)
{
  val = analogRead(AUDIO_INPUT_PIN);
  
  Serial1.print('<'); //Send the entire integer, with a marker for start and end to be recognized by the receiver.
  Serial1.print(val);
  Serial1.print('>');
}

Code:
//Receiver side, analogWrite not written in yet.
int led = 13;
char input;
void setup()
{
  pinMode(led, OUTPUT);
  Serial.begin(115200);
  Serial1.begin(115200);
}

void loop()
{ 
  if(Serial1.available())
  {
    while(Serial1.findUntil("<", ">"))
    {
      int val = Serial1.parseInt();
      Serial.println(val);
    }
  }

}
 
Hey guys, just a quick question if anyone would be able to help me out.

So, I think the cause of my streaming stopping after a few seconds is due to buffer overflow on the Bluesmirf. In that case, I think I could just hook up the RTS line from the Bluesmirf to a pin on the teensy, and just have it stop sending until the pin is pulled back low. Does this seem like a reasonable approach? Also, there's no way it could be the Teensy's buffers overflowing, right? I'm only acquiring/sending samples at 8000 Hz.
 
Status
Not open for further replies.
Back
Top