How to Creating a multiple Rec0000.WAV files

hi , my project is recording voice samples using electret condenser microphone

I have used the MAX9814 microphone amplifier board to record the voices and Arduino mega2560 board

I have given button interupts for start rec (pin D6) & stop rec (pin D5)

My intention is to create new rec.wav file for each and every voice samples (ex: creting the LOG files log00 to log99)

#include <SdFat.h>

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

SdFat sd;
SdFile rec;

const unsigned int darBufSize = 128;
const unsigned int totalBuf = darBufSize * 8;
const unsigned int bufSplit_1 = darBufSize;
const unsigned int bufSplit_2 = darBufSize * 2;
const unsigned int bufSplit_3 = darBufSize * 3;
const unsigned int bufSplit_4 = darBufSize * 4;
const unsigned int bufSplit_5 = darBufSize * 5;
const unsigned int bufSplit_6 = darBufSize * 6;
const unsigned int bufSplit_7 = darBufSize * 7;

const int chipSelect = 4;
unsigned long fileSize = 0L;
unsigned long waveChunk = 16;
unsigned int waveType = 1;
unsigned int numChannels = 1;

//------------ SET SAMPLE RATE HERE --------------------
unsigned long sampleRate = 48000;
//------------ SET SAMPLE RATE HERE --------------------

unsigned long bytesPerSec = sampleRate;
unsigned int blockAlign = 1;
unsigned int bitsPerSample = 8;
unsigned long dataSize = 0L;
unsigned long recByteCount = 0L;
unsigned long recByteSaved = 0L;
const int btnStart = 6;
const int btnStop = 5;
const int ledStart = 2;
const int ledStop = 3;
int recPressed = 0;
int stopPressed = 0;
unsigned long oldTime = 0L;
unsigned long newTime = 0L;
byte buf00[darBufSize]; // buffer array 1
byte buf01[darBufSize]; // buffer array 2
byte buf02[darBufSize]; // buffer array 3
byte buf03[darBufSize]; // buffer array 4
byte buf04[darBufSize]; // buffer array 4
byte buf05[darBufSize]; // buffer array 4
byte buf06[darBufSize]; // buffer array 4
byte buf07[darBufSize]; // buffer array 4
byte byte1, byte2, byte3, byte4;
unsigned int bufByteCount;
byte bufWrite;
byte lastBuf = 7;
byte valOCR2A = 16000000/(8*sampleRate);

void setup() { // THIS RUNS ONCE

  Setup_timer2();
  Setup_ADC();
  pinMode(10, OUTPUT);
  pinMode(ledStart, OUTPUT);
  pinMode(ledStop, OUTPUT);
  pinMode(btnStop, INPUT_PULLUP);
  pinMode(btnStart, INPUT_PULLUP);
  
  if (sd.begin(chipSelect, SPI_FULL_SPEED)) { // initialise card on SPI to 8MHz SPI bus speed
    for (int dloop = 0; dloop < 4; dloop++) {
      digitalWrite(ledStart,!digitalRead(ledStart));
      delay(100);
    }
  } else { // if error, flash LED twice per second, until reset
    while(1) {
      digitalWrite(ledStart,!digitalRead(ledStart));
      digitalWrite(ledStop,!digitalRead(ledStop));
      delay(500);
    }
  }

}

void loop() { // THIS RUNS LOTS!

  if (digitalRead(btnStart) == LOW && recPressed == 0) {
    StartRec(); // launch StartRec method
  }
  if (digitalRead(btnStop) == LOW && recPressed == 1) {
    StopRec(); // launch StopRec method
  }
  
  if (recPressed == 1) {
    if (recByteCount % totalBuf > bufSplit_1 && lastBuf == 7) { 
      rec.write(buf00,darBufSize); lastBuf = 0; recByteSaved += darBufSize; 
    } else if (recByteCount % totalBuf > bufSplit_2 && lastBuf == 0) {
      rec.write(buf01,darBufSize); lastBuf = 1; recByteSaved += darBufSize; 
    } else if (recByteCount % totalBuf > bufSplit_3 && lastBuf == 1) { 
      rec.write(buf02,darBufSize); lastBuf = 2; recByteSaved += darBufSize; 
    } else if (recByteCount % totalBuf > bufSplit_4 && lastBuf == 2) { 
      rec.write(buf03,darBufSize); lastBuf = 3; recByteSaved += darBufSize; 
    } else if (recByteCount % totalBuf > bufSplit_5 && lastBuf == 3) { 
      rec.write(buf04,darBufSize); lastBuf = 4; recByteSaved += darBufSize; 
    } else if (recByteCount % totalBuf > bufSplit_6 && lastBuf == 4) { 
      rec.write(buf05,darBufSize); lastBuf = 5; recByteSaved += darBufSize; 
    } else if (recByteCount % totalBuf > bufSplit_7 && lastBuf == 5) { 
      rec.write(buf06,darBufSize); lastBuf = 6; recByteSaved += darBufSize; 
    } else if (recByteCount % totalBuf < bufSplit_1 && lastBuf == 6) { 
      rec.write(buf07,darBufSize); lastBuf = 7; recByteSaved += darBufSize; 
    }
  }  
}

void StartRec() { // begin recording process

  digitalWrite(ledStart,HIGH);
  digitalWrite(ledStop,LOW);
  recByteCount = 0;
  bufByteCount = 0;
  recByteSaved = 0;
  bufWrite = 0;
  recPressed = 1; // recording button has been pressed
  stopPressed = 0;
  writeWavHeader();
  sbi (TIMSK2, OCIE2A); // enable timer interrupt, start grabbing audio

}

void StopRec() { // stop recording process, update WAV header, close file
    
  cbi (TIMSK2, OCIE2A); // disable timer interrupt
  writeOutHeader();
  digitalWrite(ledStart,LOW); // turn off recording LED
  digitalWrite(ledStop,HIGH); // light stop LED
  recPressed = 0;
  
}
  
void writeOutHeader() { // update WAV header with final filesize/datasize

  rec.seekSet(4);
  byte1 = recByteSaved & 0xff;
  byte2 = (recByteSaved >> 8) & 0xff;
  byte3 = (recByteSaved >> 16) & 0xff;
  byte4 = (recByteSaved >> 24) & 0xff;  
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  rec.seekSet(40);
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  rec.close();
  
}

void writeWavHeader() { // write out original WAV header to file

  recByteSaved = 0;
  rec.open("rec00000.wav", O_CREAT | O_TRUNC | O_RDWR);
  rec.write("RIFF");
  byte1 = fileSize & 0xff;
  byte2 = (fileSize >> 8) & 0xff;
  byte3 = (fileSize >> 16) & 0xff;
  byte4 = (fileSize >> 24) & 0xff;  
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  rec.write("WAVE");
  rec.write("fmt ");
  byte1 = waveChunk & 0xff;
  byte2 = (waveChunk >> 8) & 0xff;
  byte3 = (waveChunk >> 16) & 0xff;
  byte4 = (waveChunk >> 24) & 0xff;  
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  byte1 = waveType & 0xff;
  byte2 = (waveType >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2); 
  byte1 = numChannels & 0xff;
  byte2 = (numChannels >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2); 
  byte1 = sampleRate & 0xff;
  byte2 = (sampleRate >> 8) & 0xff;
  byte3 = (sampleRate >> 16) & 0xff;
  byte4 = (sampleRate >> 24) & 0xff;  
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  byte1 = bytesPerSec & 0xff;
  byte2 = (bytesPerSec >> 8) & 0xff;
  byte3 = (bytesPerSec >> 16) & 0xff;
  byte4 = (bytesPerSec >> 24) & 0xff;  
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  byte1 = blockAlign & 0xff;
  byte2 = (blockAlign >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2); 
  byte1 = bitsPerSample & 0xff;
  byte2 = (bitsPerSample >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2); 
  rec.write("data");
  byte1 = dataSize & 0xff;
  byte2 = (dataSize >> 8) & 0xff;
  byte3 = (dataSize >> 16) & 0xff;
  byte4 = (dataSize >> 24) & 0xff;  
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);

}

void Setup_timer2() {

  TCCR2B = _BV(CS21);  // Timer2 Clock Prescaler to : 8
  TCCR2A = _BV(WGM21); // Interupt frequency  = 16MHz / (8 x 62 + 1) ~= 32000Hz
  OCR2A = valOCR2A; // Compare Match register set to 62

}

void Setup_ADC() {

  ADMUX = 0x65; // set ADC to read pin A5, ADLAR to 1 (left adjust)
  cbi(ADCSRA,ADPS2); // set prescaler to 3 / ADC clock = 4MHz
  sbi(ADCSRA,ADPS1);
  sbi(ADCSRA,ADPS0);

}

ISR(TIMER2_COMPA_vect) {

  sbi(ADCSRA, ADSC); // start ADC sample
  while(bit_is_set(ADCSRA, ADSC));  // wait until ADSC bit goes low = new sample ready
  recByteCount++; // increment sample counter

  if (recByteCount % totalBuf < bufSplit_1) {
    buf00[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_2) { 
    buf01[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_3) {
    buf02[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_4) {
    buf03[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_5) {
    buf04[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_6) {
    buf05[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_7) {
    buf06[recByteCount % darBufSize] = ADCH;
  } else {
    buf07[recByteCount % darBufSize] = ADCH;
  }

}

So what is your exact question?

Have you written that code or just got it at random?

I got it from APC’s May 2023 issue is on sale now! | TechRadar

#include <SdFat.h>

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

SdFat sd;
SdFile rec;

const unsigned int darBufSize = 128;
const unsigned int totalBuf = darBufSize * 8;
const unsigned int bufSplit_1 = darBufSize;
const unsigned int bufSplit_2 = darBufSize * 2;
const unsigned int bufSplit_3 = darBufSize * 3;
const unsigned int bufSplit_4 = darBufSize * 4;
const unsigned int bufSplit_5 = darBufSize * 5;
const unsigned int bufSplit_6 = darBufSize * 6;
const unsigned int bufSplit_7 = darBufSize * 7;

const int chipSelect = 4;
unsigned long fileSize = 0L;
unsigned long waveChunk = 16;
unsigned int waveType = 1;
unsigned int numChannels = 1;

//------------ SET SAMPLE RATE HERE --------------------
unsigned long sampleRate = 48000;
//------------ SET SAMPLE RATE HERE --------------------

unsigned long bytesPerSec = sampleRate;
unsigned int blockAlign = 1;
unsigned int bitsPerSample = 8;
unsigned long dataSize = 0L;
unsigned long recByteCount = 0L;
unsigned long recByteSaved = 0L;
const int btnStart = 6;
const int btnStop = 5;
const int ledStart = 2;
const int ledStop = 3;
int recPressed = 0;
int stopPressed = 0;
unsigned long oldTime = 0L;
unsigned long newTime = 0L;
byte buf00[darBufSize]; // buffer array 1
byte buf01[darBufSize]; // buffer array 2
byte buf02[darBufSize]; // buffer array 3
byte buf03[darBufSize]; // buffer array 4
byte buf04[darBufSize]; // buffer array 4
byte buf05[darBufSize]; // buffer array 4
byte buf06[darBufSize]; // buffer array 4
byte buf07[darBufSize]; // buffer array 4
byte byte1, byte2, byte3, byte4;
unsigned int bufByteCount;
byte bufWrite;
byte lastBuf = 7;
byte valOCR2A = 16000000/(8*sampleRate);

void setup() { // THIS RUNS ONCE

  Setup_timer2();
  Setup_ADC();
  pinMode(10, OUTPUT);
  pinMode(ledStart, OUTPUT);
  pinMode(ledStop, OUTPUT);
  pinMode(btnStop, INPUT_PULLUP);
  pinMode(btnStart, INPUT_PULLUP);
  
  if (sd.begin(chipSelect, SPI_FULL_SPEED)) { // initialise card on SPI to 8MHz SPI bus speed
    for (int dloop = 0; dloop < 4; dloop++) {
      digitalWrite(ledStart,!digitalRead(ledStart));
      delay(100);
    }
  } else { // if error, flash LED twice per second, until reset
    while(1) {
      digitalWrite(ledStart,!digitalRead(ledStart));
      digitalWrite(ledStop,!digitalRead(ledStop));
      delay(500);
    }
  }

}

void loop() { // THIS RUNS LOTS!

  if (digitalRead(btnStart) == LOW && recPressed == 0) {
    StartRec(); // launch StartRec method
  }
  if (digitalRead(btnStop) == LOW && recPressed == 1) {
    StopRec(); // launch StopRec method
  }
  
  if (recPressed == 1) {
    if (recByteCount % totalBuf > bufSplit_1 && lastBuf == 7) { 
      rec.write(buf00,darBufSize); lastBuf = 0; recByteSaved += darBufSize; 
    } else if (recByteCount % totalBuf > bufSplit_2 && lastBuf == 0) {
      rec.write(buf01,darBufSize); lastBuf = 1; recByteSaved += darBufSize; 
    } else if (recByteCount % totalBuf > bufSplit_3 && lastBuf == 1) { 
      rec.write(buf02,darBufSize); lastBuf = 2; recByteSaved += darBufSize; 
    } else if (recByteCount % totalBuf > bufSplit_4 && lastBuf == 2) { 
      rec.write(buf03,darBufSize); lastBuf = 3; recByteSaved += darBufSize; 
    } else if (recByteCount % totalBuf > bufSplit_5 && lastBuf == 3) { 
      rec.write(buf04,darBufSize); lastBuf = 4; recByteSaved += darBufSize; 
    } else if (recByteCount % totalBuf > bufSplit_6 && lastBuf == 4) { 
      rec.write(buf05,darBufSize); lastBuf = 5; recByteSaved += darBufSize; 
    } else if (recByteCount % totalBuf > bufSplit_7 && lastBuf == 5) { 
      rec.write(buf06,darBufSize); lastBuf = 6; recByteSaved += darBufSize; 
    } else if (recByteCount % totalBuf < bufSplit_1 && lastBuf == 6) { 
      rec.write(buf07,darBufSize); lastBuf = 7; recByteSaved += darBufSize; 
    }
  }  
}

void StartRec() { // begin recording process

  digitalWrite(ledStart,HIGH);
  digitalWrite(ledStop,LOW);
  recByteCount = 0;
  bufByteCount = 0;
  recByteSaved = 0;
  bufWrite = 0;
  recPressed = 1; // recording button has been pressed
  stopPressed = 0;
  writeWavHeader();
  sbi (TIMSK2, OCIE2A); // enable timer interrupt, start grabbing audio

}

void StopRec() { // stop recording process, update WAV header, close file
    
  cbi (TIMSK2, OCIE2A); // disable timer interrupt
  writeOutHeader();
  digitalWrite(ledStart,LOW); // turn off recording LED
  digitalWrite(ledStop,HIGH); // light stop LED
  recPressed = 0;
  
}
  
void writeOutHeader() { // update WAV header with final filesize/datasize

  rec.seekSet(4);
  byte1 = recByteSaved & 0xff;
  byte2 = (recByteSaved >> 8) & 0xff;
  byte3 = (recByteSaved >> 16) & 0xff;
  byte4 = (recByteSaved >> 24) & 0xff;  
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  rec.seekSet(40);
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  rec.close();
  
}

void writeWavHeader() { // write out original WAV header to file

  recByteSaved = 0;
  rec.open("rec00000.wav", O_CREAT | O_TRUNC | O_RDWR);
  rec.write("RIFF");
  byte1 = fileSize & 0xff;
  byte2 = (fileSize >> 8) & 0xff;
  byte3 = (fileSize >> 16) & 0xff;
  byte4 = (fileSize >> 24) & 0xff;  
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  rec.write("WAVE");
  rec.write("fmt ");
  byte1 = waveChunk & 0xff;
  byte2 = (waveChunk >> 8) & 0xff;
  byte3 = (waveChunk >> 16) & 0xff;
  byte4 = (waveChunk >> 24) & 0xff;  
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  byte1 = waveType & 0xff;
  byte2 = (waveType >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2); 
  byte1 = numChannels & 0xff;
  byte2 = (numChannels >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2); 
  byte1 = sampleRate & 0xff;
  byte2 = (sampleRate >> 8) & 0xff;
  byte3 = (sampleRate >> 16) & 0xff;
  byte4 = (sampleRate >> 24) & 0xff;  
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  byte1 = bytesPerSec & 0xff;
  byte2 = (bytesPerSec >> 8) & 0xff;
  byte3 = (bytesPerSec >> 16) & 0xff;
  byte4 = (bytesPerSec >> 24) & 0xff;  
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  byte1 = blockAlign & 0xff;
  byte2 = (blockAlign >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2); 
  byte1 = bitsPerSample & 0xff;
  byte2 = (bitsPerSample >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2); 
  rec.write("data");
  byte1 = dataSize & 0xff;
  byte2 = (dataSize >> 8) & 0xff;
  byte3 = (dataSize >> 16) & 0xff;
  byte4 = (dataSize >> 24) & 0xff;  
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);

}

void Setup_timer2() {

  TCCR2B = _BV(CS21);  // Timer2 Clock Prescaler to : 8
  TCCR2A = _BV(WGM21); // Interupt frequency  = 16MHz / (8 x 62 + 1) ~= 32000Hz
  OCR2A = valOCR2A; // Compare Match register set to 62

}

void Setup_ADC() {

  ADMUX = 0x65; // set ADC to read pin A5, ADLAR to 1 (left adjust)
  cbi(ADCSRA,ADPS2); // set prescaler to 3 / ADC clock = 4MHz
  sbi(ADCSRA,ADPS1);
  sbi(ADCSRA,ADPS0);

}

ISR(TIMER2_COMPA_vect) {

  sbi(ADCSRA, ADSC); // start ADC sample
  while(bit_is_set(ADCSRA, ADSC));  // wait until ADSC bit goes low = new sample ready
  recByteCount++; // increment sample counter

  if (recByteCount % totalBuf < bufSplit_1) {
    buf00[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_2) { 
    buf01[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_3) {
    buf02[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_4) {
    buf03[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_5) {
    buf04[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_6) {
    buf05[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_7) {
    buf06[recByteCount % darBufSize] = ADCH;
  } else {
    buf07[recByteCount % darBufSize] = ADCH;
  }

}

This code is creating only one rec.wav file [ rec.open("rec00000.wav", O_CREAT | O_TRUNC | O_RDWR); ]

I want to create a number of new file at Each and every Rec button is pressed

[ // create a new file
char name[] = "LOGGER00.CSV";
for (uint8_t i = 0; i < 100; i++) {
name[6] = i/10 + '0';
name[7] = i%10 + '0';
if (file.open(root, name, O_CREAT | O_EXCL | O_WRITE)) break;
}
]

I am trying to put these instruction in my code , but i dont know how to write

in the writeWavHeader function you insert

void writeWavHeader() { // write out original WAV header to file
recByteSaved = 0;
char name[] = "rec00000.wav";
   name[6] = recordingNumber/10 + '0';
   name[7] = recordingNumber%10 + '0';
   recordingNumber++;
   rec.open(name, O_CREAT | O_TRUNC | O_RDWR);

and remove the line

rec.open("rec00000.wav", O_CREAT | O_TRUNC | O_RDWR);

Then add this line just before the setup function is defined:-

int recordingNumber=0;

This is good for 100 different file names.

:slight_smile: it is working well

and i would like to learn how you have implimented this one

i would like to learn how you have implemented this one

void writeWavHeader() { // write out original WAV header to file
recByteSaved = 0;

char name[] = "rec00000.wav"; // this creates an ASCII array with each element corresponding to a letter


   name[6] = recordingNumber/10 + '0'; // recordingNumber/10 is one tenth of the number so if it were 48 then that expression would return 4. The + '0' bit converts the number to an ASCII character. This is put in the 6th position of the array in place of the zero.


   name[7] = recordingNumber%10 + '0';// recordingNumber%10 is the remainder of the number divided by 10 so if it were 48 then that expression would return 8. The + '0' bit converts the number to an ASCII character. This is put in the 7th position of the array in place of the zero.

   recordingNumber++;  // moves on the recordingNumber variable for next time

   rec.open(name, O_CREAT | O_TRUNC | O_RDWR); // opens a file with your newly created name

yup i got it

and i got to know important of ACSII characters conversion n use of them

It convert a single digit number to ASCII that code uses:-
number + '0'
My preferred method is to use:-
number | 0x30;

Both do the same thing when number is 0 to 9 but they produce different things if the number is outside this range.

it seems you have good knowledge in programming

AND one more suggetion needed for me if you wolud like to answer

I am doing project on Pedometer for step counting AIM: is count the number of steps in a 5 min of time Interval and put the data into a file and close it then this has to be done for 100 files

I have Arduino mage 2560
I have DSPX01 accelerometer sensor ( http://www.dorji.com/docs/data/DSPX01.pdf )
I have RTC1307 real time clock ( http://datasheets.maximintegrated.com/en/ds/DS1307.pdf)
I have microSD card holder

I knew all these step counting , Real time clock, SD card data logging basic programming

I dont how to impliment all these togather

I dont how to impliment all these togather

Basically you don't.
When you tackle a project you take it one tiny step at a time. You do not pile in and wire everything up. You get one aspect going at a time.
Start off with the demo sketches for each piece of hardware and understand what they do. Then make it do what you want it to do.

I would start with the step counter as that is the center of the project. Look at the output from the sensor and see what you need to do to make it detect a step. Only when you have got this bit going can you add the other things.

i will do it