Ogg Recording Audio Skipping/Jumping

Hello,

I have a project that records a 5 second audio clip every 15 minutes.

To record I have the VS1053 Codec + MicroSD Breakout + Adafruit MAX9814 (microphone):


I am using a particle E-Series:
https://docs.particle.io/datasheets/cellular/e-series-datasheet/

I am using the following libraries:


To test things out I modified the attached example code ogg_record from Adafruit_VS1053 Library:

The code uses the millis() function instead of a button to determine when to start/stop recording as shown on the first if-statement in the loop() function.

Here’s the code being used:

#include "Particle.h"
#include <Adafruit_VS1053.h>
#include <stdio.h>
#include <SdFat.h>
SdFat SD;
File recording;
#define RESET D3         // VS1053 reset pin (output)
#define CS D5            // VS1053 chip select pin (output)
#define DCS D2           // VS1053 Data/command select pin (output)
#define CARDCS A2        // Card chip select pin
#define DREQ D4          // VS1053 Data request, ideally an Interrupt pin
#define RECBUFFSIZE 512
Adafruit_VS1053_FilePlayer musicPlayer(RESET, CS, DCS, DREQ, CARDCS);

uint8_t recording_buffer[RECBUFFSIZE];
// The length of the recording
int period = 7000;
// Check if appropriate amount of time have passed
unsigned long t_now = 0;
int recordNumber; //EEPROM Variable
// Backup name for recording file in case the first one gets corrupted somehow
char filename2[17];
void setup() {
    Serial.begin(9600);
    delay(2000);
    Serial.println("Adafruit VS1053 Ogg Recording Test");

    // initialise the music player
    if (!musicPlayer.begin()) {
        Serial.println("VS1053 not found");
        while (1){
        }  // don't do anything more
    }

    musicPlayer.sineTest(0x44, 500);    // Make a tone to indicate VS1053 is working 
 
    if (!SD.begin(CARDCS)) {
        Serial.println("SD failed, or not present");
        while (1){
        }  // don't do anything more
    }
    Serial.println("SD OK!");
  
    // Set volume for left, right channels. lower numbers == louder volume!
    musicPlayer.setVolume(10,10);
  
    // load plugin from SD card! We'll use mono 44.1KHz, high quality
    if (! musicPlayer.prepareRecordOgg("v44k1q05.img")) { 
        Serial.println("Couldn't load plugin!");
        while (1);    
    }
}

uint8_t isRecording = false;
void loop() {
    char filename[17];
    if (!isRecording && millis() - t_now >= period) {
        Serial.println("Begin recording");
        isRecording = true;
    
    // Check if the file exists already
        int i;
        strcpy(filename, "RECORD0000.OGG");
        i = EEPROM.read(recordNumber);
        EEPROM.put(recordNumber, EEPROM.read(recordNumber) + 1);
        Serial.print("EEPROM i value = ");
        Serial.println(i);
        while(SD.exists(filename)){
            if(i < 100){
                filename[6] = '0' + i/1000;
                filename[7] = '0' + i/100;
                filename[8] = '0' + i/10;
                filename[9] = '0' + i%10;
            }
            else if(i >= 100 && i < 1000){
                filename[6] = '0' + i/1000;
                filename[7] = '0' + i/100;
                filename[8] = '0' + ((i/10)%10);
                filename[9] = '0' + i%10;
            }
            else{
                filename[6] = '0' + i/1000;
                filename[7] = '0' + ((i/100)%10);
                filename[8] = '0' + ((i/10)%10);
                filename[9] = '0' + i%10;
            }
            Serial.print("i = ");
            Serial.println(i);
            i += 256;
        }
        Serial.print("Recording to "); 
        Serial.println(filename);
        strcpy(filename2, filename);
        recording = SD.open(filename, FILE_WRITE);
        if (!recording) {
            Serial.println("Couldn't open file to record!");
            while (1);
        }
    musicPlayer.startRecordOgg(true); // use microphone (for linein, pass in 'false')
    t_now = millis();
    }
    
    if (isRecording)
        saveRecordedData(isRecording);
        
    if (isRecording && millis() - t_now >= period) {
        t_now = millis();
        Serial.println("End recording");
        musicPlayer.stopRecordOgg();
        isRecording = false;
        
        // flush all the data!
        saveRecordedData(isRecording);
        
        // close it up
        recording.close();
        delay(2000);
        System.sleep(SLEEP_MODE_DEEP, 900);
    }
}

uint16_t saveRecordedData(boolean isrecord) {
    uint16_t written = 0;
  
    // read how many words are waiting for us
    uint16_t wordswaiting = musicPlayer.recordedWordsWaiting();
  
    // try to process 256 words (512 bytes) at a time, for best speed
    while (wordswaiting > 256) {
        // for example 128 bytes x 4 loops = 512 bytes
        for (int x=0; x < 512/RECBUFFSIZE; x++) {
        // fill the buffer!
            for (uint16_t addr=0; addr < RECBUFFSIZE; addr+=2) {
                uint16_t t = musicPlayer.recordedReadWord();
                //Serial.println(t, HEX);
                recording_buffer[addr] = t >> 8; 
                recording_buffer[addr+1] = t;
            }
        if (!recording.write(recording_buffer, RECBUFFSIZE)) {
            Serial.print("Couldn't write "); 
            Serial.println(RECBUFFSIZE); 
            while (1);
            }
        }
        // flush 512 bytes at a time
        recording.flush();
        written += 256;
        wordswaiting -= 256;
    }
  
    wordswaiting = musicPlayer.recordedWordsWaiting();
    if (!isrecord) {
        Serial.print(wordswaiting); 
        Serial.println(" remaining");
        // wrapping up the recording!
        uint16_t addr = 0;
        for (int x=0; x < wordswaiting-1; x++) {
            // fill the buffer!
            uint16_t t = musicPlayer.recordedReadWord();
            recording_buffer[addr] = t >> 8; 
            recording_buffer[addr+1] = t;
        if (addr > RECBUFFSIZE) {
            if (! recording.write(recording_buffer, RECBUFFSIZE)) {
                Serial.println("Couldn't write!");
                while (1);
            }
        recording.flush();
        addr = 0;
        }
    }
    if (addr != 0) {
        if (!recording.write(recording_buffer, addr)) {
            Serial.println("Couldn't write!"); 
            while (1);
        }
        written += addr;
    }
    musicPlayer.sciRead(VS1053_SCI_AICTRL3);
    if (!(musicPlayer.sciRead(VS1053_SCI_AICTRL3) & _BV(2))) {
        recording.write(musicPlayer.recordedReadWord() & 0xFF);
        written++;
        }
    recording.flush();
    }

    return written;
}

The issue is that the audio seems to play for 1-2 seconds, stop for 1-2 seconds and then play again for another 1-2 seconds. This happens whenever I listen to the .ogg file via Mozilla Firefox or VLC media player. However, when I try to open the audio clip on an audio editing software (WavePad, Sonic Visualiser), the audio clip seem to be just fine.

Also, regarding the length of the audio clip, when opened on Firefox/VLC, the length of the audio clip would be around 6-7, but opening it on an audio editing software, length reduces to 4-5 seconds.

This issue doesn’t occur ALL the time, there are a few times where there are no jumps/skips of audio when listened to using any type of software. It has been tested with different microphones and codecs resulting in the same situation.

Any idea why that’s the case? Should I be worried that the data will be distorted\corrupted when trying to convert the file to different file types (such as OGG to WAV, etc…)? Or if it’s being used in data analysis?

Thank you.

@ParticleD, or @mstanley are you able to assist?