PDA

View Full Version : Problem of how to get the raw value from microphone?



hang
06-15-2016, 12:05 PM
Hello,

I'm using teensy 3.2 with the audio adaptor.
The audio signal come into the mic port of audio adaptor, which has the voltage around 0 volt (positive or negative).
But the input range of ADC on teensy is 0 to 3.3V which means we can't get the signal when it is negative.
Is there some way to get the raw data from the microphone?
Maybe to use an external circuit to improve the DC level of signal is a choice. But is there some other ways?
I need to do some signal processing with the data from microphone, and I need to do the signal processing immediately after it comes into the audio board.

Thanks.

Ben
06-15-2016, 12:35 PM
Are you using the Mic input to feed in a ground referenced line signal? Use the Line In pins instead, these are AC coupled. Depending on your application, maybe omitting the audio shield and using an analog input on the Teensy will also work? Use a resistive voltage divider to bias the Pin to half the supply voltage and use a capacitor to couple in your signal. Or, if AC coupling is not an option for you, you can use an operational amplifier to add an offset to your signal so the Teensy can read it.

Theremingenieur
06-15-2016, 12:37 PM
The MIC input of the audio adaptor is NOT connected to the Teensy's ADC but to the Mic input pin of the SGTL5000 which then cares about amplifying and biasing, so that you get the optimal resolution, dynamics and naturally both, the positive and the negative half of the signal fed into the SGTL5000's internal ADC. The audio library will then allow you to catch that raw data and to process it, either with the existing audio library objects or with those you will write for your specific purpose.

hang
06-15-2016, 12:59 PM
Thank you.

I tried to use the operational amplifier to add the offset and it works well.
Now I'm just thinking about is there some other ways to get the signal and process it.

Thanks for your help!

hang
06-15-2016, 01:07 PM
The MIC input of the audio adaptor is NOT connected to the Teensy's ADC but to the Mic input pin of the SGTL5000 which then cares about amplifying and biasing, so that you get the optimal resolution, dynamics and naturally both, the positive and the negative half of the signal fed into the SGTL5000's internal ADC. The audio library will then allow you to catch that raw data and to process it, either with the existing audio library objects or with those you will write for your specific purpose.

Thanks for your reply.

To catch the raw data using the audio library, which object I can use?
For example if I want to display the raw data in the serial monitor of arduino with a high resolution like the ADC of teensy did, which object I can use?
The first step of my project is to get the peak to peak voltage of the signal from mic input in millivolt which means a high resolution requirement. So that's why I want to use the ADC of teensy.

Thanks.

hang
06-15-2016, 01:40 PM
The MIC input of the audio adaptor is NOT connected to the Teensy's ADC but to the Mic input pin of the SGTL5000 which then cares about amplifying and biasing, so that you get the optimal resolution, dynamics and naturally both, the positive and the negative half of the signal fed into the SGTL5000's internal ADC. The audio library will then allow you to catch that raw data and to process it, either with the existing audio library objects or with those you will write for your specific purpose.

The signal fed into the SGTL5000's internal ADC..
Is it possible to get the digital value from the internal ADC?

Thanks

Ben
06-15-2016, 02:34 PM
Thank you.

I tried to use the operational amplifier to add the offset and it works well.
Are you still using the MIC input or did you switch to the LINE IN inputs on the Audio Board, or did you switch to an analog input pin on the Teensy?

Printing all incoming samples to the Serial Monitor is probably a bit too much. But first we need to know how exactly you connect the signal to the Teensy/Shield.

hang
06-15-2016, 02:48 PM
Are you still using the MIC input or did you switch to the LINE IN inputs on the Audio Board, or did you switch to an analog input pin on the Teensy?

Printing all incoming samples to the Serial Monitor is probably a bit too much. But first we need to know how exactly you connect the signal to the Teensy/Shield.

With the operational amplifier I can add an offset to the signal.
My connection is :

Connect the signal which has the offset to the ADC of teensy.
And also connect the signal without any offset to mic input of audio board.

The first connection is to do the peak to peak calculation with higher resolution.
The second connection is used to do some FFT by the audio library.

I want to know if there is some ways to use ADC of teensy but without any external circuits like operational amplifier we used.
For example, is it possible to get the output value of the internal ADC of SGTL5000?

Thanks!

Theremingenieur
06-15-2016, 03:06 PM
I want to know if there is some ways to use ADC of teensy but without any external circuits like operational amplifier we used.
For example, is it possible to get the output value of the internal ADC of SGTL5000?
Thanks!

A microphone can NOT be connected directly to the Teensy ADC without additional circuitry. That's why it is preferable to use the the SGTL5000 on the audio board which has auto biasing, controllable gain, and a higher resolution.

And yes, you can access the raw ADC data for p2p calculation. Just read the audio library documentation and look at Paul's great video tutorial.

Ben
06-15-2016, 03:18 PM
Connect the signal which has the offset to the ADC of teensy.
Good. You can use AudioInputAnalog adc1(pin); in the Audio Library to create an input with this connection.

And also connect the signal without any offset to mic input of audio board.
Not good. The Microphone input is really only good for microphones! If you want to use the Audio Adaptor Board's ADC, you MUST use the LINE IN connection.



The first connection is to do the peak to peak calculation with higher resolution.
The second connection is used to do some FFT by the audio library.
You don't need the Audio Adaptor Board to make use of the Audio Library. All computation is done on the Teensy. So both peak detection and FFT can be done from the signal you get from the Teensy ADC.




I want to know if there is some ways to use ADC of teensy but without any external circuits like operational amplifier we used.
As I said, If you are ok with AC coupling you can replace the op amp by a resistive devider and a capacitor. If you need DC coupling, you can use resistor networks, but that will degrade signal strength. Since you already have an OP implemented, I'd leave it in.

-Ben

hang
06-15-2016, 04:14 PM
Thanks for your help, it's really detailed.

But I still have one question.
If I use the ADC of Audio Adaptor, how can I get the digitalized data of the signal? I didn't find it in the audio library.
What I find is an object called "queue" and I think it save the data into an array and I can read it from arduino.
But is there some functions that can be used to get the raw data from ADC of audio adaptor directly?

Thanks!

Ben
06-15-2016, 04:34 PM
If I use the ADC of Audio Adaptor, how can I get the digitalized data of the signal? I didn't find it in the audio library.
What I find is an object called "queue" and I think it save the data into an array and I can read it from arduino.
But is there some functions that can be used to get the raw data from ADC of audio adaptor directly?

Thanks!
The queue object should do the trick. if you don't apply effects or filters to the signal, it will give you exactly what the ADC sampled.

hang
06-15-2016, 04:40 PM
Thanks.

you solved my problem

PaulStoffregen
06-16-2016, 03:23 PM
To catch the raw data using the audio library, which object I can use?


The record queue object does this. See File > Examples > Audio > Recorder for an example of how to use it. This example writes the raw data to a SD card, but of course you can do anything else with the raw data by editing the code.



The first step of my project is to get the peak to peak voltage of the signal from mic input in millivolt which means a high resolution requirement. So that's why I want to use the ADC of teensy.

The audio library has a peak analysis object which performs this function. It's much simpler than acquiring all the raw data.

hang
06-17-2016, 10:29 AM
The record queue object does this. See File > Examples > Audio > Recorder for an example of how to use it. This example writes the raw data to a SD card, but of course you can do anything else with the raw data by editing the code.



The audio library has a peak analysis object which performs this function. It's much simpler than acquiring all the raw data.

Thanks for your reply.
I think the peak analysis in the audio library does not have a very high resolution? Because it returns 0.0 to 1.0. What I want is the Peak value in millivolts so the peak analysis is not enough powerful I guess.

PaulStoffregen
06-17-2016, 10:50 AM
The peak is returned as a 32 bit float, which has more than enough resolution to fully represent the entire 16 bit sample resolution. Please, do yourself a favor and try using the library's features. They can save you a lot of time.

hang
06-17-2016, 12:51 PM
The peak is returned as a 32 bit float, which has more than enough resolution to fully represent the entire 16 bit sample resolution. Please, do yourself a favor and try using the library's features. They can save you a lot of time.

Thanks.

I just tried with this object, and the code is below:

if (peak1.available()) {
float monopeak=peak1.read();
Serial.println(monopeak);
}

The value I get from serial monitor seems like a normalized value?
For example if I get 0.24, what is the real value it should be?
Thank you.

schuchi
01-02-2018, 12:55 PM
Is there any way to get the raw audiodata like analogRead(), when using the teensy audioshield, AUDIO_INPUT_MIC?
I want to to check if my audio signal reached a defined threshold and take out a trigger signal, when it is true. I tried it with the queue but i have undesirable fluctuations while detection.

Theremingenieur
01-02-2018, 12:57 PM
I'd go for peak detection and trigger whatever when the peak value exceeds a predefined threshold.

As a general rule, always try first to imagine how your problem would have been solved before microprocessors existed: Build a model of the analog circuit in your mind or draw it on paper. As soon as you have it theoretically working, try to substitute circuit part by circuit part (or sub-circuit by sub-circuit) with the corresponding library objects.

schuchi
01-03-2018, 12:51 PM
The trigger signal fluctuate about 16ms around the trigger threshold, when I play the identical sound with an audio interface to the teensy audio shield. I think the reason is the queue where a pointer to a 128 sample array of 16 bit integers is returned. With a sample rate of 8kHz the audiodata is held in the queue for 128samples/8kHz = 16ms.

Do you have any idea to fix this problem, to get a higher precision? thanks



#include <Audio.h>
#include <Wire.h> //serielle communication mit arduino
#include <SPI.h>
#include <SerialFlash.h>
#include "fir_filter.h"

// GUItool: begin automatically generated code
AudioInputI2S i2s1; //xy=210.182 receive 16bit audio
AudioFilterFIR fir1; //xy=639.128
AudioRecordQueue queue1; //xy=996.147
AudioOutputI2S i2s2; //xy=1036.76
AudioConnection patchCord1(i2s1, 0, fir1, 0);
AudioConnection patchCord2(fir1, 0, i2s2, 0);
AudioConnection patchCord3(fir1, 0, i2s2, 1);
AudioConnection patchCord4(fir1, queue1);
AudioControlSGTL5000 AudioShield; //xy=437.392
// GUItool: end automatically generated code

const int Trigger_Out = 30;
const int myInput = AUDIO_INPUT_MIC;
int16_t Signal;

void setup() {
Serial.begin(256000);
// Audio connections require memory, and the record queue
// uses this memory to buffer incoming audio.
AudioMemory(60);
// Enable the audio shield, select input, and enable output
AudioShield.enable();
AudioShield.inputSelect(myInput);
AudioShield.volume(0.7);
pinMode(Trigger_Out, OUTPUT);

checkMicgain.begin(controlMicGain, 200000); // function called every 200us
fir1.begin(filterCoeffs, 200);
queue1.begin();
}

void loop() {

if (queue1.available() >= 1) // check if a package is available;
{
Signal = *queue1.readBuffer();

queue1.freeBuffer();
}
if(Signal> treshold)
{
digitalWrite(Trigger_Out,HIGH);
delay(10);
digitalWrite(Trigger_Out,LOW);
}

}