Recording at 192khz freezes



  • Has anyone managed to record in high res for more than a couple of minutes - I have a recorder that records for a period of time (in my test 15 seconds ) then creates a new file and uses the gnss time stamp to give it a name - it records two or three files then seems to get stuck whilst looping - I’ve debugged it with print statements to check it’s not getting stuck in a function where I call the gnss but it’s definitely while looping - I’m using a simple timer to define the period of time for which a file records watching millis- not sure if that could be a cause
    I don’t get an error jut a freeze

    any sense of what that might be

    Thanks

    B


  • DeveloperWorld

    Hi @Ben-eaton

    Would you like to share your code maybe I could have a look?

    BR



  • hey @TE-KarlKomierowski

    thanks here it is below - a bit messy as its still in development - so some stuff that doesn't work or isnt' implemented yet

    at the moment i am toggling the recorder on and off between writing to file and getting a new name which was to try and solve an overflow error i was getting - not sure if this is partly the culprit - but tried to run the code without the on/off toggling and i had the same error

    i also have a problem where sometimes it doesn't name a file correctly instead it truncates the name given to it from the GNSS to the firstt couple of numbers and makes it a .WAV as opposed to a .wav - i wondered if the size of the usec data was to blame

    thanks for having a look

    #include <Audio.h>
    #include <arch/board/board.h>
    #include <GNSS.h>
    #include <SDHCI.h>
    #include <Arduino.h>
    #include <File.h>
    #include <Storage.h>
    #define STRING_BUFFER_SIZE  200       /**< %Buffer size */
    #define RESTART_CYCLE       (60 * 5)  /**< positioning test term */
    AudioClass *theAudio;
    SDClass theSD;
    File myFile;
    
    File myLog;
    
    /*CHANGE THESE VARIABLES FOR DIFFERENT SITUATIONS*/
    
    /*VAR FOR GAIN - TO BE PLUMBED INTO A POT OR A SLIDER*/
    float vol = -0.5;
    /*how long do we want a file to be in minutes*/
    long fileLength = 1;
    /*stereo or 4Ch TRUE or FALSE */
    bool stereo = FALSE;
    /*monitor audio TRUE or FALSE*/
    bool monitorThrough=FALSE;
    
    
    
    
    
    
    //time vars
    long chunkLength = 6000;
    long currentMillis = 0;
    long startMillis = 0;
    char filename;
    bool ErrEnd = false;
    
    /*do we still need these?*/
    static const int32_t recoding_frames = 50000;
    static const int32_t recoding_size = recoding_frames*3072; /* 2ch, 16bit, 768sample */
    
    
    /*satelitte business change depending on where are recording*/
    static SpGnss Gnss; /**< SpGnss object */
    SpNavData NavData;
    
    enum ParamSat {
      eSatGps,            /**< GPS                     World wide coverage  */
      eSatGlonass,        /**< GLONASS                 World wide coverage  */
      eSatGpsSbas,        /**< GPS+SBAS                North America        */
      eSatGpsGlonass,     /**< GPS+Glonass             World wide coverage  */
      eSatGpsQz1c,        /**< GPS+QZSS_L1CA           East Asia & Oceania  */
      eSatGpsGlonassQz1c, /**< GPS+Glonass+QZSS_L1CA   East Asia & Oceania  */
      eSatGpsQz1cQz1S,    /**< GPS+QZSS_L1CA+QZSS_L1S  Japan                */
    };
    /* Set this parameter depending on your current region. */
    static enum ParamSat satType =  eSatGpsGlonass;
    
    static void audio_attention_cb(const ErrorAttentionParam *atprm)
    {
      puts("Attention!");
      
      if (atprm->error_code >= AS_ATTENTION_CODE_WARNING)
        {
          ErrEnd = true;
       }
    }
    
    void setup() {
      puts("initialization Audio Library");
    
    
      theAudio = AudioClass::getInstance();
      theAudio->begin(audio_attention_cb);
    
      if(stereo){
    //lets go fast so we can record at 192
      theAudio->setRenderingClockMode(AS_CLKMODE_HIRES);
    theAudio->setRecorderMode(AS_SETRECDR_STS_INPUTDEVICE_MIC);
    theAudio->initRecorder(AS_CODECTYPE_WAV,"/mnt/spif/BIN",AS_SAMPLINGRATE_192000,AS_BITLENGTH_24,AS_CHANNEL_STEREO);
      puts("Init Recorder: stereo FAST");
      }
      else{
    
    theAudio->setRecorderMode(AS_SETRECDR_STS_INPUTDEVICE_MIC);
    theAudio->initRecorder(AS_CODECTYPE_WAV,"/mnt/spif/BIN",AS_SAMPLINGRATE_48000,AS_BITLENGTH_24,AS_CHANNEL_4CH);
      puts("Init Recorder: 4 Channels");    
        
        }
    
      /*AUDIO THROUGH TO MONITOR THE VOLUME AND SOUND OF MICS - TBC IN TERMS OF EXTRA DRAW - UNCOMMENT AS NEEDED -DOESNT WORK YET*/
    
    if(monitorThrough){
    theAudio->setThroughMode(AudioClass::MicIn, AudioClass::Mixer, true, vol, AS_SP_DRV_MODE_LINEOUT);
    }
       int error_flag = 0;
    
      
      /* Set serial baudrate. */
     Serial.begin(115200);
      
      /* Wait HW initialization done. */
      sleep(3);
      int result;
      
      
      
      /* Activate GNSS device */
      result = Gnss.begin();
      if (result != 0)
      {
        puts("Gnss begin error!!");
        error_flag = 1;
      }
      else
      {
        /* Setup GNSS.
        */
        switch (satType)
        {
        case eSatGps:
          Gnss.select(GPS);
          break;
        case eSatGpsSbas:
          Gnss.select(GPS);
          Gnss.select(SBAS);
          break;
        case eSatGlonass:
          Gnss.select(GLONASS);
          break;
        case eSatGpsGlonass:
          Gnss.select(GPS);
          Gnss.select(GLONASS);
          break;
        case eSatGpsQz1c:
          Gnss.select(GPS);
          Gnss.select(QZ_L1CA);
          break;
        case eSatGpsQz1cQz1S:
          Gnss.select(GPS);
          Gnss.select(QZ_L1CA);
          Gnss.select(QZ_L1S);
          break;
        case eSatGpsGlonassQz1c:
        default:
          Gnss.select(GPS);
          Gnss.select(GLONASS);
          Gnss.select(QZ_L1CA);
          break;
        }
        /* Start positioning */
        result = Gnss.start(WARM_START);
        if (result != 0)
        {
          puts("Gnss start error!!");
          error_flag = 1;
        }
        else
        {
          puts("Gnss setup OK");
        }
      }
    
    
    //begin the creation of an audio file:
       myFile = theSD.open("InitFile.wav", FILE_WRITE);
      /* Verify file open */
      if (!myFile)
        {
          printf("File open error at init\n");
          exit(1);
        }
    
    //do the maths to calculate the length of a file (min to ms)
    chunkLength= fileLength*60000;
      puts("recording audio in segments of:");  
      Serial.println(chunkLength);
      theAudio->writeWavHeader(myFile);
      puts("Write Header!");
      theAudio->startRecorder();
      puts("Recording Start!");
    
    
    }
    /**
     * position  handling and file naming
     */
    static void print_pos(SpNavData *pNavData)
    {
    
    
    //  char StringBuffer[STRING_BUFFER_SIZE];
      /* print time */
     // snprintf(StringBuffer, STRING_BUFFER_SIZE, "%02dH_%02dM_%02dS_%03duS.wav", pNavData->time.hour, pNavData->time.minute, pNavData->time.sec, pNavData->time.usec);
      //Serial.print(StringBuffer);
      String Time = String(String(pNavData->time.hour)+"-"+String( pNavData->time.minute)+"-"+String( pNavData->time.sec)+"-"+String( pNavData->time.usec)+".wav");
        myFile = theSD.open(Time, FILE_WRITE);
        
     if (!myFile)
        {
          puts  ("File open error in nameing\n");
          exit(1);
        }
        
        /*START THE RECORDER AGAIN ONCE THE FILE IS CREATED/..... MAYBE?*/
           
        theAudio->startRecorder();
        theAudio->writeWavHeader(myFile);
        startMillis = millis();
      //  loop();
    }
    
    
    
    void loop()
    {
      /* put your main code here, to run repeatedly: */
      err_t err;
    
      /* Read frames to record in file */
      err = theAudio->readFrames(myFile);
      if (err != AUDIOLIB_ECODE_OK)
        {
          puts("File End! ");
          theAudio->stopRecorder();
          goto exitRecording;
        }
      if (ErrEnd)
        {
          puts("Error End\n");
          theAudio->stopRecorder();
          goto exitRecording;
        }
    
      static int LoopCount = 0;
      static int LastPrintMin = 0;
      
      currentMillis = millis()-startMillis;
      Serial.println(currentMillis);
      if(currentMillis >= chunkLength){
        puts("record section");
      theAudio->stopRecorder();
      sleep(0.1);
      err = theAudio->readFrames(myFile);
      myFile.close();
    /* Get NaviData. */
        Gnss.getNavData(&NavData);
    /*call function to name new file with start time*/    
        print_pos(&NavData);
     
      }
    return;
    
    
      exitRecording:
      puts("exited");
    
      
      theAudio->closeOutputFile(myFile);
      myFile.close();
    
    /*log when we exited if we did*/
    Gnss.getNavData(&NavData);
    print_exit(&NavData);
    
      
      theAudio->setReadyMode();
      theAudio->end();
      
      puts("End Recording");
      exit(1);
    }
    
    
    
    /*a function to let us know if we exited and when - NOT WORKING YET*/
    static void print_exit(SpNavData *pNavData){
    char StringBuffer[STRING_BUFFER_SIZE];
     snprintf(StringBuffer, STRING_BUFFER_SIZE, "%02d-%02d-%02d:%02dH_%02dM_%02dS_%03duS.wav", pNavData->time.year, pNavData->time.month,pNavData->time.day,pNavData->time.hour, pNavData->time.minute, pNavData->time.sec, pNavData->time.usec);
      myLog = Storage.open("/mnt/sd0/dir/log.txt", FILE_WRITE);
    
      /* If the file opened okay, write to it */
      if (myLog) {
        myLog.println("exited at:");
        myLog.print(StringBuffer);
        /* Close the file */
        myLog.close();
     }
    }
    


  • hi again @TE-KarlKomierowski

    the following code records at 48khz seemingly with no issue on 4channels - but if i toggle to 2 channel and 192khz then it freezes up after a couple of minutes - is there some memory handling or something that i should be doing that i am not or something like that...

    #include <Audio.h>
    #include <arch/board/board.h>
    #include <GNSS.h>
    #include <SDHCI.h>
    #include <Arduino.h>
    #include <File.h>
    #include <Storage.h>
    #define STRING_BUFFER_SIZE  200       /**< %Buffer size */
    #define RESTART_CYCLE       (60 * 5)  /**< positioning test term */
    AudioClass *theAudio;
    SDClass theSD;
    File myFile;
    
    File myLog;
    
    /*CHANGE THESE VARIABLES FOR DIFFERENT SITUATIONS*/
    
    /*VAR FOR GAIN - TO BE PLUMBED INTO A POT OR A SLIDER*/
    float vol = -0.5;
    /*how long do we want a file to be in minutes*/
    long fileLength = 1;
    /*stereo or 4Ch TRUE or FALSE */
    bool stereo = FALSE;
    /*monitor audio TRUE or FALSE*/
    bool monitorThrough=FALSE;
    
    
    
    
    
    
    //time vars
    long chunkLength = 6000;
    long currentMillis = 0;
    long startMillis = 0;
    char filename;
    bool ErrEnd = false;
    
    /*do we still need these*/
    static const int32_t recoding_frames = 50000;
    static const int32_t recoding_size = recoding_frames*3072; /* 2ch, 16bit, 768sample */
    
    
    /*satelitte business change depending on where are recording*/
    static SpGnss Gnss; /**< SpGnss object */
    SpNavData NavData;
    
    enum ParamSat {
      eSatGps,            /**< GPS                     World wide coverage  */
      eSatGlonass,        /**< GLONASS                 World wide coverage  */
      eSatGpsSbas,        /**< GPS+SBAS                North America        */
      eSatGpsGlonass,     /**< GPS+Glonass             World wide coverage  */
      eSatGpsQz1c,        /**< GPS+QZSS_L1CA           East Asia & Oceania  */
      eSatGpsGlonassQz1c, /**< GPS+Glonass+QZSS_L1CA   East Asia & Oceania  */
      eSatGpsQz1cQz1S,    /**< GPS+QZSS_L1CA+QZSS_L1S  Japan                */
    };
    /* Set this parameter depending on your current region. */
    static enum ParamSat satType =  eSatGpsGlonass;
    
    static void audio_attention_cb(const ErrorAttentionParam *atprm)
    {
      puts("Attention!");
      
      if (atprm->error_code >= AS_ATTENTION_CODE_WARNING)
        {
          ErrEnd = true;
       }
    }
    
    void setup() {
      puts("initialization Audio Library");
    
    
      theAudio = AudioClass::getInstance();
      theAudio->begin(audio_attention_cb);
    
      if(stereo){
    //lets go fast so we can record at 192
      theAudio->setRenderingClockMode(AS_CLKMODE_HIRES);
    theAudio->setRecorderMode(AS_SETRECDR_STS_INPUTDEVICE_MIC);
    theAudio->initRecorder(AS_CODECTYPE_WAV,"/mnt/spif/BIN",AS_SAMPLINGRATE_192000,AS_BITLENGTH_24,AS_CHANNEL_STEREO);
      puts("Init Recorder: stereo FAST");
      }
      else{
    
    theAudio->setRecorderMode(AS_SETRECDR_STS_INPUTDEVICE_MIC);
    theAudio->initRecorder(AS_CODECTYPE_WAV,"/mnt/spif/BIN",AS_SAMPLINGRATE_48000,AS_BITLENGTH_24,AS_CHANNEL_4CH);
      puts("Init Recorder: 4 Channels");    
        
        }
      /*AUDIO THROUGH TO MONITOR THE VOLUME AND SOUND OF MICS - TBC IN TERMS OF EXTRA DRAW - UNCOMMENT AS NEEDED -DOESNT WORK YET*/
    
    if(monitorThrough){
    theAudio->setThroughMode(AudioClass::MicIn, AudioClass::Mixer, true, vol, AS_SP_DRV_MODE_LINEOUT);
    }
       int error_flag = 0;
    
      
      /* Set serial baudrate. */
     Serial.begin(115200);
      
      /* Wait HW initialization done. */
      sleep(3);
      int result;
      
      
      
      /* Activate GNSS device */
      result = Gnss.begin();
      if (result != 0)
      {
        puts("Gnss begin error!!");
        error_flag = 1;
      }
      else
      {
        /* Setup GNSS
         *  It is possible to setup up to two GNSS satellites systems.
         *  Depending on your location you can improve your accuracy by selecting different GNSS system than the GPS system.
         *  See: https://developer.sony.com/develop/spresense/developer-tools/get-started-using-nuttx/nuttx-developer-guide#_gnss
         *  for detailed information.
        */
        switch (satType)
        {
        case eSatGps:
          Gnss.select(GPS);
          break;
        case eSatGpsSbas:
          Gnss.select(GPS);
          Gnss.select(SBAS);
          break;
        case eSatGlonass:
          Gnss.select(GLONASS);
          break;
        case eSatGpsGlonass:
          Gnss.select(GPS);
          Gnss.select(GLONASS);
          break;
        case eSatGpsQz1c:
          Gnss.select(GPS);
          Gnss.select(QZ_L1CA);
          break;
        case eSatGpsQz1cQz1S:
          Gnss.select(GPS);
          Gnss.select(QZ_L1CA);
          Gnss.select(QZ_L1S);
          break;
        case eSatGpsGlonassQz1c:
        default:
          Gnss.select(GPS);
          Gnss.select(GLONASS);
          Gnss.select(QZ_L1CA);
          break;
        }
        /* Start positioning */
        result = Gnss.start(WARM_START);
        if (result != 0)
        {
          puts("Gnss start error!!");
          error_flag = 1;
        }
        else
        {
          puts("Gnss setup OK");
        }
      }
    
    
    //begin the creation of an audio file:
       myFile = theSD.open("InitFile.wav", FILE_WRITE);
      /* Verify file open */
      if (!myFile)
        {
          printf("File open error at init\n");
          exit(1);
        }
    //do the maths to calculate the length of a file (min to ms)
    chunkLength= fileLength*60000;
      puts("recording audio in segments of:");  
      Serial.println(chunkLength);
      theAudio->writeWavHeader(myFile);
      puts("Write Header!");
      theAudio->startRecorder();
      puts("Recording Start!");
    
    
    }
    /**
     * @brief %Print position information.
     */
    static void print_pos(SpNavData *pNavData)
    {
    
    
    //  char StringBuffer[STRING_BUFFER_SIZE];
      /* print time */
     // snprintf(StringBuffer, STRING_BUFFER_SIZE, "%02dH_%02dM_%02dS_%03duS.wav", pNavData->time.hour, pNavData->time.minute, pNavData->time.sec, pNavData->time.usec);
      //Serial.print(StringBuffer);
      String Time = String(String(pNavData->time.hour)+"-"+String( pNavData->time.minute)+"-"+String( pNavData->time.sec)+".wav");
        myFile = theSD.open(Time, FILE_WRITE);
         if (!myFile)
        {
          puts  ("File open error in nameing\n");
          exit(1);
        }
        
        /*START THE RECORDER AGAIN ONCE THE FILE IS CREATED/..... MAYBE?*/
           
        theAudio->startRecorder();
        theAudio->writeWavHeader(myFile);
        startMillis = millis();
      //  loop();
    }
    
    
    
    void loop()
    {
      /* put your main code here, to run repeatedly: */
      err_t err;
    
      /* Read frames to record in file */
      err = theAudio->readFrames(myFile);
      if (err != AUDIOLIB_ECODE_OK)
        {
          puts("File End! ");
          theAudio->stopRecorder();
          goto exitRecording;
        }
      if (ErrEnd)
        {
          puts("Error End\n");
          theAudio->stopRecorder();
          goto exitRecording;
        }
    
      static int LoopCount = 0;
      static int LastPrintMin = 0;
      
      currentMillis = millis()-startMillis;
      //Serial.println(currentMillis);
      if(currentMillis >= chunkLength){
       // puts("record section");
      theAudio->stopRecorder();
      sleep(1);
      err = theAudio->readFrames(myFile);
      myFile.close();
    /* Get NaviData. */
        Gnss.getNavData(&NavData);
    /*call function to name new file with start time*/    
        print_pos(&NavData);
     
      }
    return;
    
    
      exitRecording:
      puts("exited");
    
      
      theAudio->closeOutputFile(myFile);
      myFile.close();
    
    
    
      
      theAudio->setReadyMode();
      theAudio->end();
      
      puts("End Recording");
      exit(1);
    }
    
    
    
    
    

    thanks
    B



  • Hi @TE-KarlKomierowski
    sorry to push this but we can't seem to get a reliable implementation of 192khz audio working and even sketches that seem to be working on 48khz over time throw errore as well and its costing us a lot of hardware development time - we have taken things back to the simplest looping recorder that records audio in chunks and names the clips based on a counter

    this seems to run happily for over an hour on - however switching to 192khz and it throws an error very quickly.

    we feel like we are doing some pretty basic stuff here but there is perhaps some handling of the memory or stream that is not being handled properly - do you have a working example of audio running at 192khz

    as soon as we try and record multiple clips over a period of a couple of minutes the board crashes

    this sketch for example gradually fails in both modes (48khz and 192khz) but i can't undersatnd based on the documentation why that is:

    /*
     *  recorder_wav.ino - Recorder example application for WAV(PCM)
     *  Copyright 2018 Sony Semiconductor Solutions Corporation
     *
     *  This library is free software; you can redistribute it and/or
     *  modify it under the terms of the GNU Lesser General Public
     *  License as published by the Free Software Foundation; either
     *  version 2.1 of the License, or (at your option) any later version.
     *
     *  This library is distributed in the hope that it will be useful,
     *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     *  Lesser General Public License for more details.
     *
     *  You should have received a copy of the GNU Lesser General Public
     *  License along with this library; if not, write to the Free Software
     *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     */
    
    #include <SDHCI.h>
    #include <Audio.h>
    #include <GNSS.h>
    
    #include <arch/board/board.h>
    
    SDClass theSD;
    AudioClass *theAudio;
    int counter = 0;
    File myFile;
    
    bool ErrEnd = false;
    
    
    
    
    
    
    /**
     * @brief Audio attention callback
     *
     * When audio internal error occurc, this function will be called back.
     */
    
    static void audio_attention_cb(const ErrorAttentionParam *atprm)
    {
      puts("Attention!");
      
      if (atprm->error_code >= AS_ATTENTION_CODE_WARNING)
        {
          ErrEnd = true;
       }
    }
    
    /**
     * @brief Setup recording of mp3 stream to file
     *
     * Select input device as microphone <br>
     * Initialize filetype to stereo wav with 48 Kb/s sampling rate <br>
     * Open "Sound.wav" file in write mode
     */
    
    static const int32_t recoding_frames = 2000;
    static const int32_t recoding_size = recoding_frames*3072; /* 2ch, 16bit, 768sample */
    
    void setup()
    {
    
      
      theAudio = AudioClass::getInstance();
    
      theAudio->begin(audio_attention_cb);
    
      puts("initialization Audio Library");
    
      /* Select input device as microphone */
      //theAudio->setRenderingClockMode(AS_CLKMODE_HIRES);
        theAudio->setRecorderMode(AS_SETRECDR_STS_INPUTDEVICE_MIC);
        theAudio->initRecorder(AS_CODECTYPE_WAV,"/mnt/spif/BIN",AS_SAMPLINGRATE_48000,AS_BITLENGTH_24,AS_CHANNEL_STEREO);
      puts("Init Recorder!");
    
      /* Open file for data write on SD card */
      myFile = theSD.open("Sound.wav", FILE_WRITE);
      /* Verify file open */
      if (!myFile)
        {
          printf("File open error\n");
          exit(1);
        }
    
      theAudio->writeWavHeader(myFile);
      puts("Write Header!");
    
     Serial.begin(115200);
    
      theAudio->startRecorder();
      puts("Recording Start!");
    
    }
    
    void loop() 
    {
     // puts("err");
      err_t err;
      /* recording end condition */
      //puts("check size");
      if (theAudio->getRecordingSize() > recoding_size)
        {
          theAudio->stopRecorder();
          sleep(0.1);
          err = theAudio->readFrames(myFile);
    
      theAudio->closeOutputFile(myFile);
      myFile.close();
        puts("Recording");
    counter++;
          goto exitRecording;
        }
    
      /* Read frames to record in file */
     err = theAudio->readFrames(myFile);
    
    
      if (err != AUDIOLIB_ECODE_OK)
        {
          printf("File End! =%d\n",err);
          theAudio->stopRecorder();
          goto exitRecording;
        }
    
      if (ErrEnd)
        {
          printf("Error End\n");
          theAudio->stopRecorder();
          goto exitSketch;
        }
    
      /* This sleep is adjusted by the time to write the audio stream file.
         Please adjust in according with the processing contents
         being processed at the same time by Application.
      */
    //  usleep(10000);
    
      return;
    
    exitRecording:
    
        myFile = theSD.open(String(counter)+".wav", FILE_WRITE);
    
     puts("write header");
        theAudio->writeWavHeader(myFile);
      puts("start recorder");
      theAudio->startRecorder();
      puts("Recording Start again!");
      return;
     // exit(1);
    exitSketch:
     exit(1);
    
    }
    
    
    
    
    
    
    

    thanks

    b


  • DeveloperWorld

    Hi @Ben-eaton

    In the last code the ErrEnd will be set true when you get an error, if you instead of executing goto exitSketch just stop and restart the recording things shouldn't freeze. I have not verified this to 100% but I got this information from a college.

    @Ben-eaton said in Recording at 192khz freezes:

    if (ErrEnd)
    {
    printf("Error End\n");
    theAudio->stopRecorder();
    goto exitSketch;
    }

    I know that this issue have been discussed via email and our ambition is to post a conclusion in this thread once we have a final answer for you and the rest of the forum readers.