Sony's Developer World forum

    • Home
    • Forum guidelines

    Upcoming maintenance 

     

    Dear Customers and Partners.

    This website will be undergoing scheduled maintenance on June 14, 2023. Please be aware there may be disruption to the developer portal website and associated services during the scheduled maintenance period.

    This upgrade is essential to ensure the continued performance, reliability, and security of Developer World.

    We apologize for any inconvenience.

     

     

    Recorder_WAV -- Multiple Recordings

    Spresense
    3
    6
    5860
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    This topic has been deleted. Only users with topic management privileges can see it.
    • U
      user1388 last edited by

      Good morning. I've been playing around with my SPRESENSE board and have the RECORDER_WAV example up and running perfectly. Now I'm trying to edit the code to be able to perform multiple recordings...

      Ex) Record a 10 second wav file called Audio_000.wav and save to SD Card. Then record another 10 second wav file called Audio_001.wav and save to SD Card. So on and so on.

      Since the Camera example does something similar with its JPG files, I attempted using the same sort of syntax with my new RECORDER_WAV file, but am running into a sleuth of issues...

      My attempt is pasted below, along with the Serial monitor output. Basically I attempted to use an IF statement to record 10 WAV files. I'm thinking I might be approaching this issue incorrectly. Any help or guidance would be greatly appreciated!

      #include <SDHCI.h>
      #include <Audio.h>
      #include <stdio.h>
      
      #include <arch/board/board.h>
      
      SDClass theSD;
      AudioClass *theAudio;
      
      File myFile;
      int file_count = 0;
      
      bool ErrEnd = false;
      
      static void audio_attention_cb(const ErrorAttentionParam *atprm)
      {
        puts("Attention!");
        
        if (atprm->error_code >= AS_ATTENTION_CODE_WARNING)
          {
            ErrEnd = true;
         }
      }
      
      static const uint32_t recoding_sampling_rate = 48000;
      static const uint8_t  recoding_cannel_number = 4;
      static const uint8_t  recoding_bit_length = 16;
      static const uint32_t recoding_time = 10;
      static const int32_t recoding_byte_per_second = recoding_sampling_rate *
                                                      recoding_cannel_number *
                                                      recoding_bit_length / 8;
      static const int32_t recoding_size = recoding_byte_per_second * recoding_time;
      
      void setup()
      {
        theAudio = AudioClass::getInstance();
      
        theAudio->begin(audio_attention_cb);
      
        puts("initialization Audio Library");
      
        theAudio->setRecorderMode(AS_SETRECDR_STS_INPUTDEVICE_MIC, 210);
      
        theAudio->initRecorder(AS_CODECTYPE_WAV,
                               "/mnt/sd0/BIN",
                               recoding_sampling_rate,
                               recoding_bit_length,
                               recoding_cannel_number);
        puts("Init Recorder!");
      }
      
      void loop() 
      {
        if (file_count < 10)
        {
          char filename[16] = {0};
          sprintf(filename, "Test%03d.wav", file_count);
          myFile = theSD.open(filename, FILE_WRITE);
          
        if (!myFile)
          {
            printf("File open error\n");
            exit(1);
          }
      
        theAudio->writeWavHeader(myFile);
        puts("Write Header!");
      
        theAudio->startRecorder();
        puts("Recording Start!");
      
        file_count++;
      
        err_t err;
        
        if (theAudio->getRecordingSize() > recoding_size)
          {
            theAudio->stopRecorder();
            sleep(1);
            err = theAudio->readFrames(myFile);
      
            goto exitRecording;
          }
      
        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 exitRecording;
          }
        }
        
        return;
      
      exitRecording:
      
        theAudio->closeOutputFile(myFile);
        myFile.close();
        
        theAudio->setReadyMode();
        theAudio->end();
        
        puts("End Recording");
        exit(1);
      }
      
      initialization Audio Library
      Init Recorder!
      Write Header!
      Recording Start!
      Write Header!
      ERROR: Command (0x32) fails. Result code(0xf1) Module id(0x2) Error code(0x1) Error subcode(0x0)
      Recording Start!
      Write Header!
      ERROR: Command (0x32) fails. Result code(0xf1) Module id(0x2) Error code(0x1) Error subcode(0x0)
      Recording Start!
      Write Header!
      ERROR: Command (0x32)up_assert: Assertion failed at file:manager/audio_manager.cpp line: 3274 task: AMNG
      up_dumpstate: sp:     0d056684
      up_dumpstate: IRQ stack:
      up_dumpstate:   base: 0d046a00
      up_dumpstate:   size: 00000800
      up_dumpstate:   used: 000000f0
      up_dumpstate: User stack:
      up_dumpstate:   base: 0d056778
      up_dumpstate:   size: 000007ec
      up_dumpstate:   used: 000002c0
      up_stackdump: 0d056680: 00000000 0d045e14 00000000 0d010a5b 0d056698 000fd340 08f10000 00000001
      up_stackdump: 0d0566a0: 040067b0 00000000 0000e503 0d03de58 0d0567b0 0d0117ff 0d01ff08 0d0567b0
      up_stackdump: 0d0566c0: 0d0567d8 0d010cc5 00000000 00000000 0d0567b0 00000032 0d0566fc 0d010de1
      up_stackdump: 0d0566e0: 0d0567b0 0d0566fc 0d0566fc 00000000 000fd8bc 0d011dbf 00000000 00040032
      up_stackdump: 0d056700: 00000001 00000000 000fd040 00000127 000fd040 0d00e213 000fd040 ffffffff
      up_stackdump: 0d056720: 0d05674c 0d0567b0 00000000 00000001 0d0567b0 00000000 00000001 0d045e14
      up_stackdump: 0d056740: 00000008 0d011f17 000fd040 000fd8bc 0d000245 0d011f8f 00000000 0d011fbf
      up_stackdump: 0d056760: 0d000245 00000000 00000000 0d001b4f 00000000 00000000 deadbeef 0d056784
      up_taskdump: Idle Task: PID=0 Stack Used=0 of 0
      up_taskdump: hpwork: PID=1 Stack Used=584 of 2028
      up_taskdump: lpwork: PID=2 Stack Used=352 of 2028
      up_taskdump: lpwork: PID=3 Stack Used=352 of 2028
      up_taskdump: lpwork: PID=4 Stack Used=352 of 2028
      up_taskdump: init: PID=5 Stack Used=1224 of 8172
      up_taskdump: cxd56_pm_task: PID=6 Stack Used=320 of 996
      up_taskdump: <pthread>: PID=7 Stack Used=320 of 1020
      up_taskdump: AMNG: PID=8 Stack Used=760 of 2028
      up_taskdump: PLY_OBJ: PID=9 Stack Used=320 of 3052
      up_taskdump: SUB_PLY_OBJ: PID=10 Stack Used=320 of 3044
      up_taskdump: OMIX_OBJ: PID=11 Stack Used=328 of 3044
      up_taskdump: RENDER_CMP_DEV0: PID=12 Stack Used=312 of 2020
      up_taskdump: RENDER_CMP_DEV1: PID=13 Stack Used=312 of 2020
      up_taskdump: FED_OBJ: PID=14 Stack Used=552 of 2028
      up_taskdump: REC_OBJ: PID=15 Stack Used=372 of 2028
      up_taskdump: CAPTURE_CMP_DEV0: PID=16 Stack Used=440 of 2012
       fails. Reup_assert: Assertion failed at file:objects/front_end/front_end_obj.cpp line: 119 task: FED_OBJ
      up_dumpstate: sp:     0d05ce54
      up_dumpstate: IRQ stack:
      up_dumpstate:   bassult codeup_assert: Assertion failed at file:objects/front_end/front_end_obj.cpp line: 89 task: CAPTURE_CMP_DEV0
      up_dumpstate: sp:     0d05f0f4
      up_dumpstate: IRQ stack:
      up_dumpstate:   base: 0d046a00
      up_dumpstate:   size: 00000800
      up_dumpstate:   used: 000000f0
      up_dumpstate: User stack:
      up_dumpstate:   base: 0d05f248
      up_dumpstate:   size: 000007dc
      up_dumpstate:   used: 00000320
      up_stackdump: 0d05f0e0: 0d05f104 0d00cfcf 00000000 000fd680 0d05f13c 0d05f200 00000000 0d0161b9
      up_stackdump: 0d05f100: 0d05f13c 000fd680 00006b00 00008000 0d05e230 0d05e240 0d01612f 0d00e851
      up_stackdump: 0d05f120: 00000306 0d00d493 0d05f100 00000000 00000300 00000000 0d039900 00000300
      up_stackdump: 0d05f140: 00000000 00000300 01000000 00000000 0d0872a0 0d087750 0d05e230 0d00fc79
      up_stackdump: 0d05f160: 6c6c6f72 612f7265 6f696475 61000000 0d0df010 00700300 00000000 0d080000
      up_stackdump: 0d05f180: 0d05e230 0d0872a0 0d05e230 0d05e230 0d05f200 0d00fd01 0d03995b 00000306
      up_stackdump: 0d05f1a0: 0d05e230 0d00f507 00000000 0d01018b 00000000 0d00ea59 00000000 00000000
      up_stackdump: 0d05f1c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      up_stackdump: 0d05f1e0: 00000000 0d01a9ab 0d05e230 000fe608 0d05e230 00000006 00000000 0d00e6a7
      up_stackdump: 0d05f200: 00000000 00000000 00000000 00000000 00000000 0d05e230 00000000 00000000
      up_stackdump: 0d05f220: 00000000 0d00f15f 000fd380 000fe608 00000101 0d00f1b1 0d00f18f 0d001b4f
      up_stackdump: 0d05f240: 00000000 00000000 deadbeef 0d05f254 00000000 54504143 5f455255 5f504d43
      up_taskdump: Idle Task: PID=0 Stack Used=0 of 0
      up_taskdump: hpwork: PID=1 Stack Used=584 of 2028
      up_taskdump: lpwork: PID=2 Stack Used=352 of 2028
      up_taskdump: lpwork: PID=3 Stack Used=352 of 2028
      up_taskdump: lpwork: PID=4 Stack Used=352 of 2028
      up_taskdump: init: PID=5 Stack Used=1224 of 8172
      up_taskdump: cxd56_pm_task: PID=6 Stack Used=320 of 996
      up_taskdump: <pthread>: PID=7 Stack Used=320 of 1020
      up_taskdump: AMNG: PID=8 Stack Used=760 of 2028
      up_taskdump: PLY_OBJ: PID=9 Stack Used=320 of 3052
      up_taskdump: SUB_PLY_OBJ: PID=10 Stack Used=320 of 3044
      up_taskdump: OMIX_OBJ: PID=11 Stack Used=328 of 3044
      up_taskdump: RENDER_CMP_DEV0: PID=12 Stack Used=312 of 2020
      up_taskdump: RENDER_CMP_DEV1: PID=13 Stack Used=312 of 2020
      up_taskdump: FED_OBJ: PID=14 Stack Used=760 of 2028
      up_taskdump: REC_OBJ: PID=15 Stack Used=372 of 2028
      up_taskdump: CAPTURE_CMP_DEV0: PID=16 Stack Used=856 of 2012
      e: 0d046a00
      up_dumpstate:   size: 00000800
      up_dumpstate:   used: 000000f0
      up_dumpstate: User stack:
      up_dumpstate:   base: 0d05cf98
      up_dumpstate:   size: 000007ec
      up_dumpstate:   used: 000002f8
      up_stackdump: 0d05ce40: 0d05ce64 0d00cfcf 00000000 00000000 000000fc 00000001 00000000 0d0162d1
      up_stackdump: 0d05ce60: 00000015 000fd680 00006b02 00008000 0d05ce90 0d08b7b0 00000001 00001800
      up_stackdump: 0d05ce80: 0d05cfd0 0d02da0d 0000000e 000ffc01 00000000 00000000 0004000d 00000300
      up_stackdump: 0d05cea0: 00001800 0d000100 00000001 00000000 0d05cfd0 0d015dc3 000ff054 0d00c81b
      up_stackdump: 0d05cec0: 0000000e 00000000 00000000 0004000d 00000300 00001800 00000100 00000000
      up_stackdump: 0d05cee0: 0d05cfd0 00000000 00000000 0d01610d 0004000d 00000000 00000300 00000000
      up_stackdump: 0d05cf00: 00000000 00000000 0004000d 00000300 00000001 0d01a900 000fd680 000fd680
      up_stackdump: 0d05cf20: 00000000 0d016f0f 0d05cfd0 000fd680 0d05cfd0 00000000 00000002 0d045e88
      up_stackdump: 0d05cf40: 00000001 0000001a 00000000 0d016ffb 00000000 00000000 00000000 001b011a
      up_stackdump: 0d05cf60: 0010000d 0000000d 00000000 00000010 00000000 00000000 00000000 00000000
      up_stackdump: 0d05cf80: 00000000 0d017049 00000101 0d001b4f 00000000 00000000 deadbeef 0d05cfa4
      up_taskdump: Idle Task: PID=0 Stack Used=0 of 0
      up_taskdump: hpwork: PID=1 Stack Used=584 of 2028
      up_taskdump: lpwork: PID=2 Stack Used=352 of 2028
      up_taskdump: lpwork: PID=3 Stack Used=352 of 2028
      up_taskdump: lpwork: PID=4 Stack Used=352 of 2028
      up_taskdump: init: PID=5 Stack Used=1224 of 8172
      up_taskdump: cxd56_pm_task: PID=6 Stack Used=320 of 996
      up_taskdump: <pthread>: PID=7 Stack Used=320 of 1020
      up_taskdump: AMNG: PID=8 Stack Used=760 of 2028
      up_taskdump: PLY_OBJ: PID=9 Stack Used=320 of 3052
      up_taskdump: SUB_PLY_OBJ: PID=10 Stack Used=320 of 3044
      up_taskdump: OMIX_OBJ: PID=11 Stack Used=328 of 3044
      up_taskdump: RENDER_CMP_DEV0: PID=12 Stack Used=312 of 2020
      up_taskdump: RENDER_CMP_DEV1: PID=13 Stack Used=312 of 2020
      up_taskdump: FED_OBJ: PID=14 Stack Used=840 of 2028
      up_taskdump: REC_OBJ: PID=15 Stack Used=372 of 2028
      (0xf1) Module id(0x4) Error code(0x1) Error subcode(0x0)
      Recording Start!
      Write Header!
      ERROR: Command (0x32) fails. Result code(0xf1) Module id(0x2) Error code(0x1) Error subcode(0x0)
      Recording Start!
      Attention: module[1][0] attention id[2]/code[3] (dma_controller/audio_dma_drv.cpp L898)
      
      Attention: module[1][0] attention id[2]/code[7] (dma_controller/audio_dma_drv.cpp L774)
      
      Write Header!
      ERROR: Command (0x32) fails. Result code(0xf1) Module id(0x4) Error code(0x1) Error subcode(0x0)
      Recording Start!
      Write Header!
      ERROR: Command (0x32) fails. Result code(0xf1) Module id(0x2) Error code(0x1) Error subcode(0x0)
      Recording Start!
      Write Header!
      
      1 Reply Last reply Reply Quote
      • TE-KarlKomierowski
        TE-KarlKomierowski DeveloperWorld last edited by

        @user1388

        Just took a quick look at your code:

        Isn't it so that if this line err = theAudio->readFrames(myFile); is ok you will exit and enter the loop() function again and start the recorder again without ever have stopped it first.

        
        
        void loop() 
        {
          if (file_count < 10)
          {
            char filename[16] = {0};
            sprintf(filename, "Test%03d.wav", file_count);
            myFile = theSD.open(filename, FILE_WRITE);
            
          if (!myFile)
            {
              printf("File open error\n");
              exit(1);
            }
        
          theAudio->writeWavHeader(myFile);
          puts("Write Header!");
        
          theAudio->startRecorder();
          puts("Recording Start!");
        
          file_count++;
        
          err_t err;
          
          if (theAudio->getRecordingSize() > recoding_size)
            {
              theAudio->stopRecorder();
              sleep(1);
              err = theAudio->readFrames(myFile);
        
              goto exitRecording;
            }
        
          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 exitRecording;
            }
          }
          
          return;
        
        exitRecording:
        
          theAudio->closeOutputFile(myFile);
          myFile.close();
          
          theAudio->setReadyMode();
          theAudio->end();
          
          puts("End Recording");
          exit(1);
        }
        
        
        
        1 Reply Last reply Reply Quote
        • U
          user1388 last edited by

          @TE-KarlKomierowski

          Thanks for the quick response Karl. I actually ended up rewriting my code once I found Ben Eaton's code in the 'Recording at 192khz freezes' thread below, since he seems to be attempting the same this as me.

          My new program works well...for a random amount of time. Eventually it throws up the following error:

          Attention: module[4][0] attention id[1]/code[6] (objects/media_recorder/audio_recorder_sink.cpp L84)
          

          I can't seem to find a pattern for what could be causing this issue.

          Here is my code:

          #include <SDHCI.h>
          #include <Audio.h>
          #include <GNSS.h>
          
          #include <arch/board/board.h>
          
          SDClass theSD;
          AudioClass *theAudio;
          int file_count = 0;
          File myFile;
          
          bool ErrEnd = false;
          
          // When audio internal error occurs, this function will be called back.
          static void audio_attention_cb(const ErrorAttentionParam *atprm)
          {
            puts("Attention!\n");
            
            if (atprm->error_code >= AS_ATTENTION_CODE_WARNING)
              {
                ErrEnd = true;
             }
          }
          
          //Sampling Rate (16000 or 48000)
          static const uint32_t recording_sampling_rate = 48000;
          
          //Input Mic Channels (1, 2, or 4)
          static const uint8_t  recording_channel_number = 4;
          
          //Audio Bit Length (16 or 24)
          static const uint8_t  recording_bit_length = 16;
          
          //Recording Time (Seconds)
          static const uint32_t recording_time = 10;
          
          //Bytes per Second
          static const int32_t recording_byte_per_second = recording_sampling_rate *
                                                          recording_channel_number *
                                                          recording_bit_length / 8;
          //Total WAV File Size
          static const int32_t recording_size = recording_byte_per_second * recording_time;
          
          void setup()
          { 
            theAudio = AudioClass::getInstance();
          
            theAudio->begin(audio_attention_cb);
          
            puts("Initializing the Audio Library...\n");
          
            /* Select input device as microphone */
              theAudio->setRecorderMode(AS_SETRECDR_STS_INPUTDEVICE_MIC, 210); //210 = 21.0 dB Mic Gain
              theAudio->initRecorder(AS_CODECTYPE_WAV,"/mnt/spif/BIN",recording_sampling_rate,recording_bit_length,recording_channel_number);
            puts("Setting up the Recorder...\n");
          
            /* Open file for data write on SD card */
            myFile = theSD.open("Sound.wav", FILE_WRITE);
            /* Verify file open */
            if (!myFile)
              {
                printf("Error opening the WAV file...\n");
                exit(1);
              }
          
            theAudio->writeWavHeader(myFile);
            puts("Writing the WAV File Header...\n");
          
            Serial.begin(115200);
          
            theAudio->startRecorder();
            puts("Recording Started!\n");
          
          }
          
          void loop() 
          {
            err_t err;
            /* recording end condition */
            if (theAudio->getRecordingSize() > recording_size)
              {
                theAudio->stopRecorder();
                sleep(0.1);
                err = theAudio->readFrames(myFile);
          
                theAudio->closeOutputFile(myFile);
                myFile.close();
                
                file_count++;
                
                goto exitRecording;
              }
          
            /* Read frames to record in file */ 
           err = theAudio->readFrames(myFile);
          
            if (err != AUDIOLIB_ECODE_OK)
              {
                printf("File Ended! =%d\n",err);
                theAudio->stopRecorder();
                goto exitRecording;
              }
          
            if (ErrEnd)
              {
                printf("Error End\n");
                theAudio->stopRecorder();
                goto exitSketch;
              }
          
            if (file_count > 10)
              {
                goto exitSketch;
              }
            
            return;
          
          exitRecording:
              
              myFile = theSD.open(String(file_count)+".wav", FILE_WRITE);
          
              puts("Writing the WAV File Header...\n");
              theAudio->writeWavHeader(myFile);
              
              puts("Starting the Recorder...\n");
              
              theAudio->startRecorder();
              puts("Next Recording Started...\n");
              return;
          
          exitSketch:
              exit(1);
          
          }
          

          I really appreciate your help!

          U 1 Reply Last reply Reply Quote
          • U
            user1388 @user1388 last edited by

            I added this snippet you mentioned in another thread with the same error:

            static void audio_attention_cb(const ErrorAttentionParam *atprm)
            {
              puts("Attention!");
            
              switch (atprm->error_code) {
                case AS_ATTENTION_CODE_INFORMATION:
                case AS_ATTENTION_CODE_WARNING    :
                  ErrEnd = false;
                  break;
                case AS_ATTENTION_CODE_ERROR      :
                case AS_ATTENTION_CODE_FATAL      :
                default:
                  ErrEnd = true;
              }
            }
            

            Program ran fine until it got to the 7th file and got this error:

            Attention: module[4][0] attention id[1]/code[6] (objects/media_recorder/audio_recorder_sink.cpp L84)
            Attention!
            

            Then the program froze and I had to manually reset it.

            Also, I am using a 64GB SanDisk Ultra microSD Card.

            Thanks!

            1 Reply Last reply Reply Quote
            • U
              user1388 last edited by

              @TE-KarlKomierowski

              So I've been going through documentation and it looks like I may be running into a "FIFO Overflow" issue: AS_ATTENTION_SUB_CODE_SIMPLE_FIFO_OVERFLOW

              And the error information states:

              Simple fifo between application and sdk became full. Extraction speed
              may be slower than Insertion. Coordinate task priority of application
              to avoid queue remain increaseing.
              

              Also saw recommendations to increase task priority or increase the buffer size.

              I'm a bit lost and am not sure where to go from here. Would really appreciate any guidance anyone can provide...

              Thank you!

              1 Reply Last reply Reply Quote
              • K
                KamilTomaszewski DeveloperWorld last edited by

                @user1388

                Hi,

                This is a known issue. I have found a temporary solution for now. Unfortunately, this requires that you build the Spresense Arduino package again. You can use this: https://github.com/sonydevworld/spresense-arduino-compatible

                Currently, when an error is detected, the Audio module stops working. However, this can be changed and when FIFO OVERFLOW is detected, samples can be dropped instead.

                As a result, the application does not finish recording, but on the other hand does not guarantee that all samples will be saved.

                Solution:

                • Find function bool AudioRecorderSink::write(const AudioRecSinkData_s &param) in the file sdk/modules/audio/objects/media_recorder/audio_recorder_sink.cpp

                • Comment line number 84.

                • Return true instead of false on line number 85.

                After the changes, the function should look like this:

                bool AudioRecorderSink::write(const AudioRecSinkData_s &param)
                {
                  if (param.byte_size > 0) {
                    if (CMN_SimpleFifoGetVacantSize(static_cast<CMN_SimpleFifoHandle *>
                        (m_output_device_hdlr.simple_fifo_handler)) < param.byte_size)
                      {
                        // MEDIA_RECORDER_WARN(AS_ATTENTION_SUB_CODE_SIMPLE_FIFO_OVERFLOW);
                        return true;
                      }
                
                    if (CMN_SimpleFifoOffer(static_cast<CMN_SimpleFifoHandle *>
                        (m_output_device_hdlr.simple_fifo_handler),
                        static_cast<const void*>(param.mh.getVa()), param.byte_size) == 0)
                      {
                        MEDIA_RECORDER_WARN(AS_ATTENTION_SUB_CODE_SIMPLE_FIFO_OVERFLOW);
                        return false;
                      }
                
                    m_output_device_hdlr.callback_function(param.byte_size);
                  }
                  return true;
                }
                

                This is only a temporary solution. If I find other, I will let you know.

                1 Reply Last reply Reply Quote
                • First post
                  Last post
                Developer World
                Copyright © 2021 Sony Group Corporation. All rights reserved.
                • Contact us
                • Legal