Hi all,
I would like to do a simple record project which is recording an audio, saving the file to an sd card and playing the recorded file. Therefor I am using a Teensy 4.0 and Audio Shield.
I have an electret microphone directly connected to the audio shield. I am supplying the Teensy by an external power supply.
The overall setup looks like this:
This is the code I am using:
The Problem is that I am always getting high noise which is sounding terrible.
The frequency spectrum from Audacity looks like this:
It seems like I have Problems with 172Hz and multiple frequencies.
This is exactly the frequency for the SD Card Write operations. Every 5802µs...
I am using a SanDisk Ultra 16Gb Class 10 Micro SD.
Any Ideas what I am doing wrong and how I can get rid of these frequencies?
I already tired to power the teensy from a battery. This is only reduicing the 50Hz and multiple Frequencies from the mains, but has no significant impact on the hearable noise.
Saw a similar issue in this thread but could not find a solution there:
https://forum.pjrc.com/threads/41706-Teensy-Microphone-Module/page6
I would like to do a simple record project which is recording an audio, saving the file to an sd card and playing the recorded file. Therefor I am using a Teensy 4.0 and Audio Shield.
I have an electret microphone directly connected to the audio shield. I am supplying the Teensy by an external power supply.
The overall setup looks like this:
This is the code I am using:
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 <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
AudioPlaySdWav playWav1; //xy=302,157
AudioOutputI2S i2s1; //xy=470,120
AudioConnection patchCord1(i2s2, 0, queue1, 0);
AudioConnection patchCord2(i2s2, 0, peak1, 0);
//AudioConnection patchCord3(playWav1, 0, i2s1, 0);
AudioConnection patchCord4(playWav1, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=265,212
// GUItool: end automatically generated code
// For a stereo recording version, see this forum thread:
// https://forum.pjrc.com/threads/46150?p=158388&viewfull=1#post158388
// A much more advanced sound recording and data logging project:
// https://github.com/WMXZ-EU/microSoundRecorder
// https://github.com/WMXZ-EU/microSoundRecorder/wiki/Hardware-setup
// https://forum.pjrc.com/threads/52175?p=185386&viewfull=1#post185386
const int myInput = AUDIO_INPUT_MIC;
//const int myInput = AUDIO_INPUT_LINEIN;
//write wav
unsigned long ChunkSize = 0L;
unsigned long Subchunk1Size = 16;
unsigned int AudioFormat = 1;
unsigned int numChannels = 1;
unsigned long sampleRate = 44100;
unsigned int bitsPerSample = 16;
unsigned long byteRate = sampleRate*numChannels*(bitsPerSample/8);// samplerate x channels x (bitspersample / 8)
unsigned int blockAlign = numChannels*bitsPerSample/8;
unsigned long Subchunk2Size = 0L;
unsigned long recByteSaved = 0L;
unsigned long NumSamples = 0L;
byte byte1, byte2, byte3, byte4;
elapsedMicros usec = 0;
unsigned int lastTime=0;
unsigned int enableSerial=0;
// Use these for the Audio Shield
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 11
#define SDCARD_SCK_PIN 12
// 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() {
if(enableSerial>0)
{
Serial.begin(9600);
}
// Audio connections require memory, and the record queue
// uses this memory to buffer incoming audio.
AudioMemory(60);
sgtl5000_1.enable();
sgtl5000_1.inputSelect(myInput);
sgtl5000_1.volume(0.5);
sgtl5000_1.micGain(36);
// 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) {
if(enableSerial>0)
{
Serial.println("Unable to access the SD card");
}
delay(500);
}
}
}
int timeLast = millis();
int state=1;
void loop()
{
int TimeWait=1000; // Wait time before Record starts
int TimeRecord=2000; // Time to record
int TimeWaitBeforePlaying=200; // Wait Time to record
int TimePlay=2500; // Playback Time
int ActTime=millis();
if ((ActTime-timeLast)>TimeWait+TimeRecord+TimeWaitBeforePlaying+TimePlay && state==4)
{
timeLast=millis()-TimeWait-TimeRecord;
if (mode == 2) stopPlaying();
state=3;
}
else if ((ActTime-timeLast)>TimeWait+TimeRecord+TimeWaitBeforePlaying && state==3)
{
if (mode == 1) stopRecording();
if (mode == 0) startPlaying();
if(enableSerial>0) Serial.println(ActTime);
state=4;
}
else if ((ActTime-timeLast)>TimeWait+TimeRecord && state==2)
{
if (mode == 1) stopRecording();
if (mode == 2) stopPlaying();
if(enableSerial>0) Serial.println(ActTime);
state=3;
}
else if((ActTime-timeLast)>TimeWait && state==1)
{
if (mode == 2) stopPlaying();
if (mode == 0) startRecording();
if(enableSerial>0) Serial.println(ActTime);
state=2;
}
// If we're playing or recording, carry on...
if (mode == 1)
{
continueRecording();
}
if (mode == 2)
{
continuePlaying();
}
}
void startRecording() {
if(enableSerial>0) Serial.println("startRecording");
if (SD.exists("RECORD.WAV")) {
// 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.WAV");
}
frec = SD.open("RECORD.WAV", FILE_WRITE);
if (frec) {
queue1.begin();
mode = 1;
recByteSaved = 0L;
}
}
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
frec.write(buffer, 512);
recByteSaved += 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-lastTime);
lastTime=usec;
}
}
void stopRecording() {
if(enableSerial>0) Serial.println("stopRecording");
queue1.end();
if (mode == 1) {
while (queue1.available() > 0) {
frec.write((byte*)queue1.readBuffer(), 256);
queue1.freeBuffer();
recByteSaved += 256;
}
writeOutHeader();
frec.close();
}
mode = 0;
}
void startPlaying() {
if(enableSerial>0) Serial.println("startPlaying");
playWav1.play("RECORD.WAV");
mode = 2;
}
void continuePlaying() {
if (!playWav1.isPlaying()) {
playWav1.stop();
mode = 0;
}
}
void stopPlaying() {
if(enableSerial>0) Serial.println("stopPlaying");
if (mode == 2) playWav1.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 :-)
}
void writeOutHeader() { // update WAV header with final filesize/datasize
// NumSamples = (recByteSaved*8)/bitsPerSample/numChannels;
// Subchunk2Size = NumSamples*numChannels*bitsPerSample/8; // number of samples x number of channels x number of bytes per sample
Subchunk2Size = recByteSaved;
ChunkSize = Subchunk2Size + 36;
frec.seek(0);
frec.write("RIFF");
byte1 = ChunkSize & 0xff;
byte2 = (ChunkSize >> 8) & 0xff;
byte3 = (ChunkSize >> 16) & 0xff;
byte4 = (ChunkSize >> 24) & 0xff;
frec.write(byte1); frec.write(byte2); frec.write(byte3); frec.write(byte4);
frec.write("WAVE");
frec.write("fmt ");
byte1 = Subchunk1Size & 0xff;
byte2 = (Subchunk1Size >> 8) & 0xff;
byte3 = (Subchunk1Size >> 16) & 0xff;
byte4 = (Subchunk1Size >> 24) & 0xff;
frec.write(byte1); frec.write(byte2); frec.write(byte3); frec.write(byte4);
byte1 = AudioFormat & 0xff;
byte2 = (AudioFormat >> 8) & 0xff;
frec.write(byte1); frec.write(byte2);
byte1 = numChannels & 0xff;
byte2 = (numChannels >> 8) & 0xff;
frec.write(byte1); frec.write(byte2);
byte1 = sampleRate & 0xff;
byte2 = (sampleRate >> 8) & 0xff;
byte3 = (sampleRate >> 16) & 0xff;
byte4 = (sampleRate >> 24) & 0xff;
frec.write(byte1); frec.write(byte2); frec.write(byte3); frec.write(byte4);
byte1 = byteRate & 0xff;
byte2 = (byteRate >> 8) & 0xff;
byte3 = (byteRate >> 16) & 0xff;
byte4 = (byteRate >> 24) & 0xff;
frec.write(byte1); frec.write(byte2); frec.write(byte3); frec.write(byte4);
byte1 = blockAlign & 0xff;
byte2 = (blockAlign >> 8) & 0xff;
frec.write(byte1); frec.write(byte2);
byte1 = bitsPerSample & 0xff;
byte2 = (bitsPerSample >> 8) & 0xff;
frec.write(byte1); frec.write(byte2);
frec.write("data");
byte1 = Subchunk2Size & 0xff;
byte2 = (Subchunk2Size >> 8) & 0xff;
byte3 = (Subchunk2Size >> 16) & 0xff;
byte4 = (Subchunk2Size >> 24) & 0xff;
frec.write(byte1); frec.write(byte2); frec.write(byte3); frec.write(byte4);
frec.close();
if(enableSerial>0) Serial.println("header written");
if(enableSerial>0) Serial.print("Subchunk2: ");
if(enableSerial>0) Serial.println(Subchunk2Size);
}
The Problem is that I am always getting high noise which is sounding terrible.
The frequency spectrum from Audacity looks like this:
It seems like I have Problems with 172Hz and multiple frequencies.
This is exactly the frequency for the SD Card Write operations. Every 5802µs...
I am using a SanDisk Ultra 16Gb Class 10 Micro SD.
Any Ideas what I am doing wrong and how I can get rid of these frequencies?
I already tired to power the teensy from a battery. This is only reduicing the 50Hz and multiple Frequencies from the mains, but has no significant impact on the hearable noise.
Saw a similar issue in this thread but could not find a solution there:
https://forum.pjrc.com/threads/41706-Teensy-Microphone-Module/page6
Last edited: