Audio Board and stereo recording

Status
Not open for further replies.

inimidi

Member
Hello world,

This is my first post on this forum~ :eek:

I am about to embark on a new project involving stereo audio recording.
I was looking at the audio board and noticed only a connection for a single microphone.
However, there are two for line-in. . . so this got me wondering:

Will MEMs microphones work on the line-in?
Can I use the ports for line in to connect two microphones (with amplifiers) and record stereo?
Do I require some in-between electronics to successfully connect the mics to the line-in?

Or am I way off?

Kind regards,

imimidi
 
Last edited:
Hello,

Yes, use the L & R through holes (you can see them labeled on the underside of the board) on the SGTL-5000. The mics also need a ground, you can use the two grounds next to the R & L if you like.

I know from experience that you can use amplified microphones (I used Adafruit 9814). You can use mems mics with those line ins, but you want use mics that have analog outs. A digitial output would be something like an I2C mic.

If you need any "in between" electronics that would be in instructions from the mic vendor. You need a mic with built in amplification (eg: you can't just salvage a mic out of an old telephone headset). Typically there is some kind of thing you do to the mic to set the set the gain. Also you can put a small 100uF capacitor inline with the line out from the mic to clean up the signal (bias) -- but again, that would be something the mic vendor would have instructions on.

Have Fun!
QC
 
Thank you so much for the quick response :D

I got held up with some "side-quests" at work, but will start building today~
 
Hello,

Yes, use the L & R through holes (you can see them labeled on the underside of the board) on the SGTL-5000. The mics also need a ground, you can use the two grounds next to the R & L if you like.


Have Fun!
QC

Dear qcarver,

I managed to get the board up and running and record some audio. I connected two similar adafruit microphones to the audio shield and tried to do some audio recording.

However, the result was mono and suffered from some noise.

Did you encounter similar issues?

My code (practically the example code with millis timers so I didn't have to install buttons):

Code:
// Record sound as raw data to a SD card, and play it back.
//
// Requires the audio shield:
//   http://www.pjrc.com/store/teensy3_audio.html
//
// Three pushbuttons need to be connected:
//   Record Button: pin 0 to GND
//   Stop Button:   pin 1 to GND
//   Play Button:   pin 2 to GND
//
// This example code is in the public domain.

#include <Bounce.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputI2S            i2s2;           //xy=105,63
AudioAnalyzePeak         peak1;          //xy=278,108
AudioRecordQueue         queue1;         //xy=281,63
AudioPlaySdRaw           playRaw1;       //xy=302,157
AudioOutputI2S           i2s1;           //xy=470,120
AudioConnection          patchCord1(i2s2, 0, queue1, 0);
AudioConnection          patchCord2(i2s2, 0, peak1, 0);
AudioConnection          patchCord3(playRaw1, 0, i2s1, 0);
AudioConnection          patchCord4(playRaw1, 0, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=265,212
// GUItool: end automatically generated code

// Bounce objects to easily and reliably read the buttons
Bounce buttonRecord = Bounce(0, 8);
Bounce buttonStop =   Bounce(1, 8);  // 8 = 8 ms debounce time
Bounce buttonPlay =   Bounce(2, 8);


// which input on the audio shield will be used?
const int myInput = AUDIO_INPUT_LINEIN;
//const int myInput = AUDIO_INPUT_MIC;


// Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN    10
#define SDCARD_MOSI_PIN  7
#define SDCARD_SCK_PIN   14

// Use these with the Teensy 3.5 & 3.6 SD card
//#define SDCARD_CS_PIN    BUILTIN_SDCARD
//#define SDCARD_MOSI_PIN  11  // not actually used
//#define SDCARD_SCK_PIN   13  // not actually used

// Use these for the SD+Wiz820 or other adaptors
//#define SDCARD_CS_PIN    4
//#define SDCARD_MOSI_PIN  11
//#define SDCARD_SCK_PIN   13


// Remember which mode we're doing
int mode = 0;  // 0=stopped, 1=recording, 2=playing

// The file where data is recorded
File frec;

void setup() {
  // Configure the pushbutton pins
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);

  // 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
  sgtl5000_1.enable();
  sgtl5000_1.inputSelect(myInput);
  sgtl5000_1.volume(0.5);

  // Initialize the SD card
  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN))) {
    // stop here if no SD card, but print a message
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
}


void loop() {
  // First, read the buttons
  buttonRecord.update();
  buttonStop.update();
  buttonPlay.update();

  if (millis() > 5000 && mode == 0) {

    startRecording();

  }

  if (mode == 1) {
    continueRecording();
  }

  if (millis() > 15000 && mode == 1) {

    stopRecording();
    mode = 5;
  }

  // when using a microphone, continuously adjust gain
  if (myInput == AUDIO_INPUT_MIC) adjustMicLevel();
}


void startRecording() {
  Serial.println("startRecording");
  if (SD.exists("RECORD.RAW")) {
    // The SD library writes new data to the end of the
    // file, so to start a new recording, the old file
    // must be deleted before new data is written.
    SD.remove("RECORD.RAW");
  }
  frec = SD.open("RECORD.RAW", FILE_WRITE);
  if (frec) {
    queue1.begin();
    mode = 1;
  }
}

void continueRecording() {
  if (queue1.available() >= 2) {
    byte buffer[512];
    // Fetch 2 blocks from the audio library and copy
    // into a 512 byte buffer.  The Arduino SD library
    // is most efficient when full 512 byte sector size
    // writes are used.
    memcpy(buffer, queue1.readBuffer(), 256);
    queue1.freeBuffer();
    memcpy(buffer + 256, queue1.readBuffer(), 256);
    queue1.freeBuffer();
    // write all 512 bytes to the SD card
    elapsedMicros usec = 0;
    frec.write(buffer, 512);
    // Uncomment these lines to see how long SD writes
    // are taking.  A pair of audio blocks arrives every
    // 5802 microseconds, so hopefully most of the writes
    // take well under 5802 us.  Some will take more, as
    // the SD library also must write to the FAT tables
    // and the SD card controller manages media erase and
    // wear leveling.  The queue1 object can buffer
    // approximately 301700 us of audio, to allow time
    // for occasional high SD card latency, as long as
    // the average write time is under 5802 us.
    //Serial.print("SD write, us=");
    //Serial.println(usec);
  }
}

void stopRecording() {
  Serial.println("stopRecording");
  queue1.end();
  if (mode == 1) {
    while (queue1.available() > 0) {
      frec.write((byte*)queue1.readBuffer(), 256);
      queue1.freeBuffer();
    }
    frec.close();
  }
  mode = 0;
}


void startPlaying() {
  Serial.println("startPlaying");
  playRaw1.play("RECORD.RAW");
  mode = 2;
}

void continuePlaying() {
  if (!playRaw1.isPlaying()) {
    playRaw1.stop();
    mode = 0;
  }
}

void stopPlaying() {
  Serial.println("stopPlaying");
  if (mode == 2) playRaw1.stop();
  mode = 0;
}

void adjustMicLevel() {
  // TODO: read the peak1 object and adjust sgtl5000_1.micGain()
  // if anyone gets this working, please submit a github pull request :-)
}

Here is a link to my drive with pictures and made recordings:

https://drive.google.com/drive/folders/0B1a3jS4gGIPxN2lLdXV3aGUtMHc?usp=sharing
 
I'm perhaps old and blind, but I see no setting of lineInLevel() for the SGTL5000 control object...

Thanks for the quick reply :D
I can confirm that your eye-sight is perfectly fine. I do not feel it is my place to judge one's age ;)

Found some documentation on the right hand side here:
https://www.pjrc.com/teensy/gui/?info=AudioControlSGTL5000

However, linelevel will only change the loudness of the incoming signal? I mean; the recordings will remain in mono with some noise?
Or is the lineInLevel() object to make sure the recording is done in stereo?
 
With the lineInLevel() you set the sensitivity high enough to avoid or at least to reduce the noise. That's one construction site.
The mono/stereo problem is another one. Let's do things systematically step by step...
 
Second step: Actually, you are only using the left channel output of your i2s2 object. The right channel output is unconnected. How would you expect a correct stereo recording with that?
 
This
Code:
AudioConnection          patchCord3(playRaw1, 0, i2s1, 0);
AudioConnection          patchCord4(playRaw1, 0, i2s1, 1);
is the instruction for mono output (same signal to left and right)
 
fixed the lineInLevel() using:

Code:
sgtl5000_1.lineInLevel(2,2);

so that's one down :)

Regarding the i2s2 object:
Actually, you are only using the left channel output of your i2s2 object. The right channel output is unconnected.
Does this reference the physical connections and wiring of the microphones or the digital wiring from the different programming blocks of the 'audio system design tool' ( https://www.pjrc.com/teensy/gui/?info=AudioInputI2S )? In case it refers to the physical wiring; the ground of one mic is connected to the other and then routed to the ground.

The code that I posted above was based on an example code that I handled directly in the IDE.

code from pjrc.jpg

This is what it looks like if I import it in the design tool. However it doesn't let me add the second channel to the queue nor peak. Instead it requires me to construct a separate queue and peak for the other channel. This to me looks like it will generate two files :confused:

If I look at these lines of code:

Code:
AudioInputI2S            i2s2;           //xy=105,63

AudioConnection          patchCord1(i2s2, 0, queue1, 0);
AudioConnection          patchCord2(i2s2, 0, peak1, 0);

AudioControlSGTL5000     sgtl5000_1;     //xy=265,212

I assume that the syntax is as following:
AudioConnection patchCord[INDEX]([SENDER BLOCK], [SENDER BLOCK CONNECTION], [RECEIVER BLOCK], [RECEIVER BLOCK CONNECTION]);
By this "logic" could the code be something like:

Code:
AudioConnection          patchCord5(i2s2, 1, queue2, 0);
AudioConnection          patchCord6(i2s2, 1, peak2, 0);

And then copy all the code that addresses queue1 and peak1 and make a duplicate with queue2 and peak2?
 
Last edited:
This
Code:
AudioConnection          patchCord3(playRaw1, 0, i2s1, 0);
AudioConnection          patchCord4(playRaw1, 0, i2s1, 1);
is the instruction for mono output (same signal to left and right)

Hey WMXZ you replied as I was still typing away new hypothesises I had :p

I am not playing from the audio board (I take out the SD card and edit them in audacity). The code regarding playRaw and everything 'audio out' is basically appendix code that came with the example code that I haven't cut of yet :)
 
Hi inimidi,

I am using the Teensy 3.2 instead of the 3.5/3.6, but I suspect this code will work with it as well. I assume the recording process does not take up much RAM space on the Teensy except for some buffering since it is recording audio directly to the SD card. I noticed that the program has to erase a previously recorded file before it can record a new one. Has anyone figured out a way to record multiple files by assigning a new name. I suppose that might take fairly advanced code that sort of creates a file structure on the SD card. What I would like to figure out is how to record music files from the audio input line onto the SD card for later playback. I know that Paul has created his audio lab examples using pre-recorded SD files with different names and then cycling through them using a push-button. In any case, it would be nice if recording on the SD card could be done from an audio input line from a computer, CD/DVD player or cell phone. What do you think?
 
A little while back, I connected two Adafruit MEMS microphones to the Teensy Audio Board. It worked decently well, though I was always had to be careful with my wiring to keep the noise down.

Here's a write up showing how I wired it together:

http://openaudio.blogspot.com/2016/11/a-teensy-hearing-aid.html

In my wiring diagram (from the post above...also copied below) note how I connect each microphone to the Audio board's line in...note that I bring both the microphone output ("AC") and the microphone ground ("Gnd") back to the Audio board's line in.

Components.jpg

Regarding this ground...you might think that you could bring the mic's Gnd back to some other place on the Teensy or on the Audio board. Don't do that. When I tried to use any other ground, the noise got really bad. But, when I connected each microphone's ground to the grounds at the line input, it sounded OK. Learn from my mistakes!

Also, if you still have a noise problem, you should consider disabling the Audio board's highpass filter. In my experience (and others), the highpass filter adds a ton of noise. In my setup, when I disabled the filter, the background noise dropped by 15-20 dB. That's a lot. I have a discussion of that here:

http://openaudio.blogspot.com/2017/03/teensy-audio-board-self-noise.html

To disable the highpass filter, add the following command somewhere towards the end of your setup() function:

Code:
adcHighPassFilterDisable();

Good luck!

Chip
 
Dear qcarver,

I managed to get the board up and running and record some audio....Here is a link to my drive with pictures and made recordings:

https://drive.google.com/drive/folders/0B1a3jS4gGIPxN2lLdXV3aGUtMHc?usp=sharing

Hello,

Sorry it has been a long time since you asked for my response. My apologies. The two audio files from early November actually sound very good to me. I'm not sure what the dialog is, it sounds far off, but I don't hear any popping or clicking or buzzing.

One thing I did notice in your pictures, I think that the amplified microphone output should be the positive leg of the electrolytic cap. I believe the positive leg will be the one with the stripe down the outside of the "can". I often get these things backwards though, so check here and here and decide for yourself.

Have Fun,
QC
 
Status
Not open for further replies.
Back
Top