

MP3の音声を繰り返し出力するために、サンプルの「player_objIf.ino」の初期化部分 `thePlayer =
MediaPlayer::getInstance()` から、終了部分 `thePlayer->end()`
までを繰返そうとすると2回目でエラーが発生し再生されません。

初期化部分と終了部分を繰返しループから外せば繰返しできるのですが、他の処理と切り替える為に終了時に完全に解放したいと考えています。  
使用しているのはArduino1.8.13です。

エラーは2回目の初期化時、以下のように表示されます。

**エラーメッセージ:**

[code]

    Attention: module[5][0] attention id[2]/code[16] (objects/output_mixer/output_mix_obj.cpp L654)
    
[/code]

**ソースコード:**

[code]

    #include <SDHCI.h>
    #include <MediaPlayer.h>
    #include <OutputMixer.h>
    #include <MemoryUtil.h>
    
    SDClass theSD;
    
    MediaPlayer *thePlayer;
    OutputMixer *theMixer;
    
    File myFile;
    
    bool ErrEnd = false;
    
    /**
     * @brief Audio attention callback
     *
     * When audio internal error occurc, this function will be called back.
     */
    
    static void attention_cb(const ErrorAttentionParam *atprm)
    {
      puts("Attention!");
      
      if (atprm->error_code >= AS_ATTENTION_CODE_WARNING)
        {
          ErrEnd = true;
       }
    }
    
    /**
     * @brief Mixer done callback procedure
     *
     * @param [in] requester_dtq    MsgQueId type
     * @param [in] reply_of         MsgType type
     * @param [in,out] done_param   AsOutputMixDoneParam type pointer
     */
    static void outputmixer_done_callback(MsgQueId requester_dtq,
                                          MsgType reply_of,
                                          AsOutputMixDoneParam *done_param)
    {
      return;
    }
    
    /**
     * @brief Mixer data send callback procedure
     *
     * @param [in] identifier   Device identifier
     * @param [in] is_end       For normal request give false, for stop request give true
     */
    static void outmixer_send_callback(int32_t identifier, bool is_end)
    {
      AsRequestNextParam next;
    
      next.type = (!is_end) ? AsNextNormalRequest : AsNextStopResRequest;
    
      AS_RequestNextPlayerProcess(AS_PLAYER_ID_0, &next);
    
      return;
    }
    
    /**
     * @brief Player done callback procedure
     *
     * @param [in] event        AsPlayerEvent type indicator
     * @param [in] result       Result
     * @param [in] sub_result   Sub result
     *
     * @return true on success, false otherwise
     */
    static bool mediaplayer_done_callback(AsPlayerEvent event, uint32_t result, uint32_t sub_result)
    {
      printf("mp cb %x %x %x\n", event, result, sub_result);
    
      return true;
    }
    
    /**
     * @brief Player decode callback procedure
     *
     * @param [in] pcm_param    AsPcmDataParam type
     */
    void mediaplayer_decode_callback(AsPcmDataParam pcm_param)
    {
      {
        /* You can process a data here. */
        
        signed short *ptr = (signed short *)pcm_param.mh.getPa();
    
        for (unsigned int cnt = 0; cnt < pcm_param.size; cnt += 4)
          {
            *ptr = *ptr + 0;
            ptr++;
            *ptr = *ptr + 0;
            ptr++;
          }
      }
      
      theMixer->sendData(OutputMixer0,
                         outmixer_send_callback,
                         pcm_param);
    }
    
    /**
     * @brief Setup Player and Mixer
     *
     * Set output device to Speakers/Headphones <br>
     * Initialize main player to decode stereo mp3 stream with 48 kb/s sample rate <br>
     * System directory "/mnt/sd0/BIN" will be searched for MP3 decoder (MP3DEC file)
     * Open "Sound.mp3" file <br>
     * Set volume to -16.0 dB
     */
    void setup()
    {
      /* Initialize memory pools and message libs */
      
      initMemoryPools();
      createStaticPools(MEM_LAYOUT_PLAYER);
      
    }
    
    /**
     * @brief Play audio frames until file ends
     */
    void loop()
    {
    while(1){
      thePlayer = MediaPlayer::getInstance();
      theMixer  = OutputMixer::getInstance();
    
      /* Set rendering clock */
    
      theMixer->setRenderingClkMode(OUTPUTMIXER_RNDCLK_NORMAL);
    
      /* start audio system */
    
      thePlayer->begin();
      theMixer->begin();
      
      puts("initialization Audio Library");
    
      /* Create Objects */
    
      thePlayer->create(MediaPlayer::Player0, attention_cb);
    
      theMixer->create(attention_cb);
    
      /* Activate Player Object */
    
      thePlayer->activate(MediaPlayer::Player0, mediaplayer_done_callback);
    
      /* Activate Mixer Object.
       * Set output device to speaker with 2nd argument.
       * If you want to change the output device to I2S,
       * specify "I2SOutputDevice" as an argument.
       */
    
      theMixer->activate(OutputMixer0, HPOutputDevice, outputmixer_done_callback);
    
      usleep(100 * 1000);
    
      /*
       * Initialize main player to decode stereo mp3 stream with 48 kb/s sample rate
       * Search for MP3 codec in "/mnt/sd0/BIN" directory
       */
      thePlayer->init(MediaPlayer::Player0, AS_CODECTYPE_MP3, "/mnt/sd0/BIN", AS_SAMPLINGRATE_AUTO, AS_CHANNEL_STEREO);
    
      /* Initialize SD */
      while (!theSD.begin())
        {
          /* wait until SD card is mounted. */
          Serial.println("Insert SD card.");
        }
    
      myFile = theSD.open("Sound.mp3");
    
      /* Verify file open */
      if (!myFile)
        {
          printf("File open error\n");
          exit(1);
        }
      printf("Open! %d\n", myFile);
    
      /* Send first frames to be decoded */
      err_t err = thePlayer->writeFrames(MediaPlayer::Player0, myFile);
    
    //  if (err != MEDIAPLAYER_ECODE_OK)
      if ((err != MEDIAPLAYER_ECODE_OK) && (err != MEDIAPLAYER_ECODE_FILEEND))
        {
          printf("File Read Error! =%d\n",err);
          myFile.close();
          exit(1);
        }
    
      puts("Play!");
    
      /* Main volume set to -16.0 dB, Main player and sub player set to 0 dB */
      theMixer->setVolume(-160, 0, 0);
    
      // Start Player
      thePlayer->start(MediaPlayer::Player0, mediaplayer_decode_callback);
    
      while(err != MEDIAPLAYER_ECODE_FILEEND)
      {
        puts("loop!!");
        err = thePlayer->writeFrames(MediaPlayer::Player0, myFile);
        if (err == MEDIAPLAYER_ECODE_FILEEND)
        {   puts("Main player File End!");
        }else if (err != MEDIAPLAYER_ECODE_OK)
        { printf("Main player error codewwwafafeds: %d\n", err);
          goto stop_player;
        }
        if (ErrEnd)  {   puts("Error End");    goto stop_player;  }  
        usleep(40*1000);    //40ms待ち
      }
    
      usleep(40*1000);    //40ms待ち
    
      /*  Tell when player file ends */
      if (err == MEDIAPLAYER_ECODE_FILEEND)
        {
          printf("Main player File End!\n");
        }
    
    stop_player:
      thePlayer->stop(MediaPlayer::Player0);
      myFile.close();
      usleep(3000*1000);  //再生終了まで1秒待つ
      theMixer->deactivate(OutputMixer0);     // 追加
      thePlayer->deactivate(MediaPlayer::Player0);
      theMixer->end();                        // 追加
      thePlayer->end();
      usleep(1000*1000);  //1秒待つ
    //  exit(1);
      }
    }
    
[/code]


CC BY-SA 4.0
2021-07-16T03:06:08.523
78222
2021-07-16T12:38:14.130
2021-07-16T03:18:00.690
3060
44800
question
spresense arduino
Spresenseのオーディオ出力のオブジェクトインターフェースで初期化と終了を繰り返すとエラーになる


Arduinoのオブジェクトインターフェースのソースコードをみると、  
そもそもcreateに対するdelete処理が存在していないようにみえます。

SDKのサンプルコードを参考に、AS_Delete処理を追加してみるのはどうでしょうか。

[code]

    stop_player:
      thePlayer->stop(MediaPlayer::Player0);
      myFile.close();
      usleep(3000*1000);  //再生終了まで1秒待つ
      theMixer->deactivate(OutputMixer0);     // 追加
      thePlayer->deactivate(MediaPlayer::Player0);
      theMixer->end();                        // 追加
      thePlayer->end();
      usleep(1000*1000);  //1秒待つ
      AS_DeletePlayer(AS_PLAYER_ID_0); // 追加★
      AS_DeleteOutputMix(); // 追加★
      AS_DeleteRenderer(); // 追加★
    //  exit(1);
      }
    }
    
[/code]


CC BY-SA 4.0
2021-07-16T12:38:14.130
78234
2021-07-16T12:38:14.130
31378
78222
answer