donperryjm
Well-known member
My setup:
Audio --> Biquad-->amp -->record & USB
Symptom is as described:
when recording an input I can hear the audio properly coming in on the USB but the file is not saving everything. Only a portion of the file is being saved on the SD. Almost like it's fast forwarded.
I'm going to post the code I'm using:
audio record code:
Audio --> Biquad-->amp -->record & USB
Symptom is as described:
when recording an input I can hear the audio properly coming in on the USB but the file is not saving everything. Only a portion of the file is being saved on the SD. Almost like it's fast forwarded.
I'm going to post the code I'm using:
Code:
#include <Arduino.h>
#include <Audio.h>
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <memcpy_audio.h>
//You may substitute the is2stereoIn for your audioboard or other i2s device
AudioInputI2S is2stereoIn; //xy=84,1033
AudioAmplifier amp1R; //xy=292,1087
AudioAmplifier amp1L; //xy=295,962
AudioFilterBiquad biquad1L; //xy=447,799
AudioFilterBiquad biquad1R; //xy=522,1103
AudioMixer4 mixerL; //xy=738,834
AudioMixer4 mixerR; //xy=739,1155
AudioAnalyzePeak peakR; //xy=899,1230
AudioAnalyzePeak peakL; //xy=924,707
AudioOutputUSB usb2; //xy=969,987
AudioRecordQueue record1; //xy=1005,849
AudioRecordQueue record2; //xy=1005,849
AudioConnection patchCord1(is2stereoIn, 0, amp1L, 0);
AudioConnection patchCord2(is2stereoIn, 1, amp1R, 0);
AudioConnection patchCord3(amp1R, biquad1R);
AudioConnection patchCord4(amp1L, biquad1L);
AudioConnection patchCord5(biquad1L, 0, mixerL, 0);
AudioConnection patchCord8(biquad1R, 0, mixerR, 0);
AudioConnection patchCord9(mixerL, 0, usb2, 0);
AudioConnection patchCord10(mixerL, peakL);
AudioConnection patchCord11(mixerL, 0, record1, 0);
AudioConnection patchCord12(mixerR, 0, usb2, 1);
AudioConnection patchCord13(mixerR, peakR);
AudioConnection patchCord14(mixerR, 0, record2, 0);
#define SDCARD_CS_PIN 254
#define SDCARD_MOSI_PIN 7
#define SDCARD_SCK_PIN 14
bool sdSetupCalled = false;
void SDsetup() {
// 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
delay(600);
}
else
{
sdSetupCalled = true;
// queue1.
}
// startRecording();
}
//write wav
unsigned long ChunkSize = 0L;
unsigned long Subchunk1Size = 16;
unsigned short AudioFormat = 1;
unsigned short numChannels = 1;
unsigned long sampleRate = 44100;
unsigned short bitsPerSample = 16;
unsigned long byteRate = sampleRate * numChannels * (bitsPerSample / 8);// samplerate x channels x (bitspersample / 8)
unsigned short blockAlign = numChannels * bitsPerSample / 8;
unsigned long Subchunk2Size = 0L;
unsigned long recByteSaved = 0L;
unsigned long NumSamples = 0L;
byte byte1, byte2, byte3, byte4;
elapsedMillis msecs;
// Use these with the Teensy Audio Shield
// Remember which fileMode we're doing
short fileMode = 0; // 0=stopped, 1=recording, 2=playing
const char wav[] PROGMEM = ".wav";
const char _log[] PROGMEM = "Log_";
const char dat[] PROGMEM = ".dat";
// The file where data is recorded
File f_rec;
File f_log;
File f_cfg;
void RecordingLoop();
void startPlaying();
void continuePlaying();
void writeOutHeader();
void stopPlaying();
void startRecording();
void continueRecording();
void stopRecording();
uint32_t VolumeSize();
uint32_t SDFreeSpace();
elapsedMillis recordPlaybackTimer;
elapsedMillis logFrameTimer; //take frameshot every 20ms
String FormatNumber(long number);
#define RECORD_LENGTH 10 //10 second
String fileName, fileName_log;
void setup()
{
AudioMemory(20);
amp1L.gain(1); //used to be 30
amp1R.gain(1); //u/sed to be 30
biquad1L.setHighpass(0, 200, 1); //1.5 was 2.0
biquad1L.setLowpass(1, 10000, 1); //1.5 was 2.0
biquad1R.setHighpass(0, 200, 1); //1.5 was 2.0
biquad1R.setLowpass(1, 10000, 1); //1.5 was 2.0
}
void loop()
{
if (millis() < RECORD_LENGTH && fileMode == 0)//auto start recording
startRecording();
if (fileMode == 1)
RecordingLoop();
}
void RecordingLoop() {
if (record1.available() && record2.available()&& recordPlaybackTimer < (RECORD_LENGTH * 1000))
continueRecording();
else
stopRecording();
}
inline void stopPlaying()
{
}
void startRecording() {
recordPlaybackTimer = 0;
if (!sdSetupCalled)
{
SDsetup();
}
if (!sdSetupCalled)
return;
if ( fileMode == 1)
return;
short nameIncrement = 0;
fileName = _log + String(nameIncrement) + wav;
//find last file in sequence, create new
while (SD.exists(fileName.c_str())) {
nameIncrement += 1;
fileName = _log + String(nameIncrement) + wav;
//fileName_log = _log+ String(nameIncrement) + dat;
}
recByteSaved = 0;
f_rec = SD.open((fileName ).c_str(), FILE_WRITE_BEGIN);
//record.record(f_rec, APW_16BIT_SIGNED, 2);
record1.begin();
record2.begin();
fileMode = 1;
}
void continueRecording() {
int16_t buffer[512]; // data to write
memcpy_tointerleaveLR(buffer, record1.readBuffer(), record2.readBuffer());
record1.freeBuffer(); record2.freeBuffer(); // free buffer
f_rec.write(buffer, 512);
recByteSaved += 512;
}
void stopRecording() {
if (fileMode == 0)
return;
fileMode = 0;
record1.end(); //queue L
record2.end(); //queue R
// buffer arrays for left and right channels,
// and one for LR interleaved
byte bufferL[256];
byte bufferR[256];
byte bufferLR[512];
// Copy one block from each channel into
// a buffer, then free the buffer
while (record2.available() > 0) {
memcpy(bufferL, record1.readBuffer(), 256);
memcpy(bufferR, record2.readBuffer(), 256);
record1.freeBuffer();
record2.freeBuffer();
//Interleave two bytes (one 16bit sample) from the
//left and right buffers one after another
int b = 0;
for (int i = 0; i <= 511; i = i + 4) {
bufferLR[i] = bufferL[b];
bufferLR[i + 1] = bufferL[b + 1];
bufferLR[i + 2] = bufferR[b];
bufferLR[i + 3] = bufferR[b + 1];
b = b + 2;
}
// write all 512 bytes to the SD card
elapsedMicros usec = 0;
f_rec.write(bufferLR, 512);
recByteSaved += 512;
Serial.print("SD write, us=");
Serial.println(usec);
}
writeOutHeader();
f_rec.close();
}
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;
f_rec.seek(0);
f_rec.write("RIFF");
byte1 = ChunkSize & 0xff;
byte2 = (ChunkSize >> 8) & 0xff;
byte3 = (ChunkSize >> 16) & 0xff;
byte4 = (ChunkSize >> 24) & 0xff;
f_rec.write(byte1); f_rec.write(byte2); f_rec.write(byte3); f_rec.write(byte4);
f_rec.write("WAVE");
f_rec.write("fmt ");
byte1 = Subchunk1Size & 0xff;
byte2 = (Subchunk1Size >> 8) & 0xff;
byte3 = (Subchunk1Size >> 16) & 0xff;
byte4 = (Subchunk1Size >> 24) & 0xff;
f_rec.write(byte1); f_rec.write(byte2); f_rec.write(byte3); f_rec.write(byte4);
byte1 = AudioFormat & 0xff;
byte2 = (AudioFormat >> 8) & 0xff;
f_rec.write(byte1); f_rec.write(byte2);
byte1 = numChannels & 0xff;
byte2 = (numChannels >> 8) & 0xff;
f_rec.write(byte1); f_rec.write(byte2);
byte1 = sampleRate & 0xff;
byte2 = (sampleRate >> 8) & 0xff;
byte3 = (sampleRate >> 16) & 0xff;
byte4 = (sampleRate >> 24) & 0xff;
f_rec.write(byte1); f_rec.write(byte2); f_rec.write(byte3); f_rec.write(byte4);
byte1 = byteRate & 0xff;
byte2 = (byteRate >> 8) & 0xff;
byte3 = (byteRate >> 16) & 0xff;
byte4 = (byteRate >> 24) & 0xff;
f_rec.write(byte1); f_rec.write(byte2); f_rec.write(byte3); f_rec.write(byte4);
byte1 = blockAlign & 0xff;
byte2 = (blockAlign >> 8) & 0xff;
f_rec.write(byte1); f_rec.write(byte2);
byte1 = bitsPerSample & 0xff;
byte2 = (bitsPerSample >> 8) & 0xff;
f_rec.write(byte1); f_rec.write(byte2);
f_rec.write("data");
byte1 = Subchunk2Size & 0xff;
byte2 = (Subchunk2Size >> 8) & 0xff;
byte3 = (Subchunk2Size >> 16) & 0xff;
byte4 = (Subchunk2Size >> 24) & 0xff;
f_rec.write(byte1); f_rec.write(byte2); f_rec.write(byte3); f_rec.write(byte4);
f_rec.close();
Serial.println("header written");
Serial.print("recbytesaved ");
Serial.println(recByteSaved);
Serial.print("Subchunk2");
Serial.println(Subchunk2Size);
}
audio record code: