1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: snd_SoundArchivePlayer.h 4 5 Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Revision: 22284 $ 14 *---------------------------------------------------------------------------*/ 15 16 /** 17 * :include nw/snd/snd_SoundArchivePlayer.h 18 * 19 * @file snd_SoundArchivePlayer.h 20 */ 21 22 #ifndef NW_SND_SOUND_ARCHIVE_PLAYER_H_ 23 #define NW_SND_SOUND_ARCHIVE_PLAYER_H_ 24 25 #include <nw/snd/snd_SoundStartable.h> 26 #include <nw/snd/snd_NoteOnCallback.h> 27 #include <nw/snd/snd_SoundArchive.h> 28 #include <nw/snd/snd_BasicSound.h> 29 #include <nw/snd/snd_SequenceSoundPlayer.h> // SequenceUserprocCallback 30 #include <nw/snd/snd_SequenceSound.h> // SequenceSoundInstanceManager 31 #include <nw/snd/snd_WaveSound.h> // WaveSoundInstanceManager 32 #include <nw/snd/snd_StreamSound.h> // StreamSoundInstanceManager 33 #include <nw/snd/snd_Util.h> 34 #include <nw/snd/snd_SoundInstanceManager.h> 35 #include <nw/snd/snd_MmlSequenceTrackAllocator.h> 36 #include <nw/snd/snd_MmlParser.h> 37 38 namespace nw { 39 namespace snd { 40 41 class SoundHandle; 42 class SoundHeap; 43 class SoundActor; 44 class SoundPlayer; 45 class SoundDataManager; 46 47 namespace internal { 48 49 class ExternalSoundPlayer; 50 class Channel; 51 class StreamSound; 52 class WaveSound; 53 class PlayerHeap; 54 55 } 56 57 //! 58 //--------------------------------------------------------------------------- 59 //! @brief サウンドアーカイブ中のサウンドを再生するクラスです。 60 //! 61 //! SoundArchivePlayer で再生したサウンドは、 62 //! ハンドルクラスを用いて操作することができます。 63 //! 64 //! @see SoundHandle クラス 65 //! @see SoundStartable インターフェイス 66 //! 67 //! @date 2010/01/15 初版 68 //--------------------------------------------------------------------------- 69 class SoundArchivePlayer : public SoundStartable 70 { 71 private: 72 static const int DEFAULT_STREAM_BLOCK_COUNT = 5; 73 74 /* ------------------------------------------------------------------------ 75 SeqCallback class 76 ------------------------------------------------------------------------ */ 77 class SequenceNoteOnCallback : public internal::driver::NoteOnCallback 78 { 79 public: SequenceNoteOnCallback(const SoundArchivePlayer & player)80 SequenceNoteOnCallback( const SoundArchivePlayer& player ) : m_pSoundArchivePlayer( player ) { } 81 82 virtual internal::driver::Channel* NoteOn( 83 internal::driver::SequenceSoundPlayer* seqPlayer, 84 u8 bankIndex, 85 const internal::driver::NoteOnInfo& noteOnInfo 86 ); 87 88 private: 89 const SoundArchivePlayer& m_pSoundArchivePlayer; 90 }; 91 friend class SoundArchivePlayer::SequenceNoteOnCallback; 92 93 /* ------------------------------------------------------------------------ 94 WaveSoundCallback class 95 ------------------------------------------------------------------------ */ 96 private: 97 class WaveSoundCallback : public internal::driver::WaveSoundPlayer::WaveSoundCallback 98 { 99 public: WaveSoundCallback(const SoundArchivePlayer & player)100 WaveSoundCallback( const SoundArchivePlayer& player ) : m_pSoundArchivePlayer( player ) { } 101 102 virtual bool GetWaveSoundData( 103 internal::WaveSoundInfo* info, 104 internal::WaveSoundNoteInfo* noteInfo, 105 internal::WaveInfo* waveData, 106 const void* waveSoundData, 107 int index, 108 int noteIndex, 109 u32 userData 110 ) const; 111 112 private: 113 const SoundArchivePlayer& m_pSoundArchivePlayer; 114 }; 115 116 /* ------------------------------------------------------------------------ 117 class member 118 ------------------------------------------------------------------------ */ 119 public: 120 //---------------------------------------- 121 //! @name コンストラクタ/デストラクタ 122 //@{ 123 //--------------------------------------------------------------------------- 124 //! @brief コンストラクタです。 125 //! 126 //! @date 2010/01/15 初版 127 //--------------------------------------------------------------------------- 128 SoundArchivePlayer(); 129 130 //--------------------------------------------------------------------------- 131 //! @brief デストラクタです。 132 //! 133 //! @date 2010/01/15 初版 134 //--------------------------------------------------------------------------- 135 virtual ~SoundArchivePlayer(); 136 //@} 137 138 //---------------------------------------- 139 //! @name 初期化 140 //@{ 141 //--------------------------------------------------------------------------- 142 //! @brief 初期化に必要なメモリのサイズを取得します。 143 //! 144 //! @param[in] arc プレイヤーで使用するサウンドアーカイブです。 145 //! 146 //! @return 初期化に必要なメモリサイズを返します。 147 //! 148 //! @see Initialize 149 //! 150 //! @date 2010/02/01 関数名変更 (Setup → Initialize) にともなう文言の調整 151 //! @date 2010/01/15 初版 152 //--------------------------------------------------------------------------- 153 size_t GetRequiredMemSize( const SoundArchive* arc ); 154 155 //--------------------------------------------------------------------------- 156 //! @brief 初期化に必要なストリームバッファのサイズを取得します。 157 //! 158 //! @ref Initialize に渡すストリームバッファの最小サイズを取得します。 159 //! この関数で取得した値より大きいサイズのバッファを渡す必要があります。 160 //! 161 //! @param[in] arc プレイヤーで使用するサウンドアーカイブです。 162 //! 163 //! @return 初期化に必要なストリームバッファサイズを返します。 164 //! 165 //! @see Initialize 166 //! 167 //! @date 2010/02/01 関数名変更 (Setup → Initialize) にともなう文言の調整 168 //! @date 2010/01/15 初版 169 //--------------------------------------------------------------------------- 170 size_t GetRequiredStreamBufferSize( const SoundArchive* arc ); 171 172 //--------------------------------------------------------------------------- 173 //! @brief サウンドアーカイブプレイヤーを初期化します。 174 //! 175 //! サウンドアーカイブプレイヤーを使用する前に、 176 //! 初期化を行う必要があります。 177 //! 初期化を行うことにより、 178 //! サウンドアーカイブプレイヤーがサウンドアーカイブと 179 //! サウンドデータマネージャ関連付けられ、 180 //! そのサウンドアーカイブ中のデータを再生できるようになります。 181 //! 182 //! サウンドアーカイブプレイヤーが必要とするメモリのサイズは 183 //! @ref GetRequiredMemSize 及び @ref GetRequiredStreamBufferSize 184 //! で取得することができます。 185 //! 186 //! 必要なストリームバッファサイズが 0 の場合、 187 //! ストリームバッファへのポインタ strmBuffer に NULL を渡すことができます。 188 //! 189 //! ストリームバッファを @ref GetRequiredStreamBufferSize 190 //! で取得したサイズより大きく設定すると、 191 //! ストリームサウンドの音途切れが発生しにくくなりますが、 192 //! データをロードしてから実際に再生するまでの遅延時間が大きくなります。 193 //! 194 //! ストリームバッファはデバイスメモリのアドレスを指定する必要があります。 195 //! strmBuffer および strmBuffer + strmBufferSize のアドレスが、 196 //! デバイスメモリに無い場合は、アサートで停止、あるいは、 197 //! false を返します (ビルドターゲットによって挙動が変わります)。 198 //! 199 //! @param[in] arc プレイヤーで使用するサウンドアーカイブです。 200 //! @param[in] manager プレイヤーで使用するサウンドデータマネージャです。 201 //! @param[in] buffer バッファへのポインタです。 202 //! 32 バイトアライメントされている必要があります。 203 //! @param[in] size バッファサイズです。 204 //! @param[in] strmBuffer ストリームバッファへのポインタです。 205 //! 32 バイトアライメントされているデバイスメモリを 206 //! 指定する必要があります。 207 //! @param[in] strmBufferSize ストリームバッファのサイズです。 208 //! 209 //! @return 初期化に成功したら true を、失敗したら false を返します。 210 //! 211 //! @see GetRequiredMemSize 212 //! @see GetRequiredStreamBufferSize 213 //! @see Finalize 214 //! @see IsAvailable 215 //! 216 //! @date 2010/03/05 ストリームバッファがデバイスメモリに無い場合の挙動を追記。 217 //! @date 2010/02/03 buffer のアライメントサイズを変更 (4 → 32) 218 //! @date 2010/02/01 関数名変更 (Setup → Initialize) 219 //! @date 2010/01/15 初版 220 //--------------------------------------------------------------------------- 221 bool Initialize( 222 const SoundArchive* arc, 223 const SoundDataManager* manager, 224 void* buffer, 225 u32 size, 226 void* strmBuffer, 227 u32 strmBufferSize 228 ); 229 230 //--------------------------------------------------------------------------- 231 //! @brief サウンドアーカイブプレイヤーを破棄します。 232 //! 233 //! 破棄は以下のとおり行われます。 234 //! 235 //! ・このサウンドアーカイブプレイヤーを使って再生中のサウンドを停止します。@n 236 //! ・初期化で割り当てたメモリ領域を開放します。@n 237 //! ・初期化されたサウンドアーカイブとの関連が外れます。 238 //! 239 //! @see Initialize 240 //! @see IsAvailable 241 //! 242 //! @date 2010/02/01 関数名変更 (Shutdown → Finalize) 243 //! @date 2010/01/15 初版 244 //--------------------------------------------------------------------------- 245 void Finalize(); 246 247 //--------------------------------------------------------------------------- 248 //! @brief 利用可能な状態かどうかを調べます。 249 //! 250 //! サウンドアーカイブプレイヤーを利用するためには 251 //! @ref Initialize を呼び出して初期化を完了させる必要があります。 252 //! また、@ref Finalize を呼び出すと、 253 //! サウンドアーカイブプレイヤーの終了処理が行われ、 254 //! 利用できない状態になります。 255 //! 256 //! @return サウンドアーカイブプレイヤーが利用可能な状態なら true を、 257 //! そうでなければ false を返します。 258 //! 259 //! @see Initialize 260 //! @see Finalize 261 //! 262 //! @date 2010/02/01 関数名変更 (Setup → Initialize, Shutdown → Finalize) 263 //! にともなう文言の調整 264 //! @date 2010/01/15 初版 265 //--------------------------------------------------------------------------- 266 bool IsAvailable() const; 267 //@} 268 269 //---------------------------------------- 270 //! @name 更新 271 //--------------------------------------------------------------------------- 272 //! @brief サウンドアーカイブプレイヤーの更新処理を行います。 273 //! 274 //! この関数は 1 ゲームフレームに 1 回呼び出してください。 275 //! 276 //! 内部の処理はサウンドスレッドで行われるため、 277 //! 更新処理を 1 ゲームフレームに 1 回呼び出すことができなくても 278 //! 発音が途切れることはありません。 279 //! この関数では、プレイヤーやサウンドに対するパラメータ設定や、 280 //! フェイドイン・フェイドアウトなどの連続的なパラメータ変更を 281 //! 反映するための処理が行われます。 282 //! 283 //! @date 2010/01/15 初版 284 //--------------------------------------------------------------------------- 285 void Update(); 286 //@} 287 288 //---------------------------------------- 289 //! @name その他 290 291 //--------------------------------------------------------------------------- 292 //! @brief プレイヤーに関連付けられているサウンドアーカイブを取得します。 293 //! 294 //! @return プレイヤーに関連付けられているサウンドアーカイブを返します。 295 //! 296 //! @see SoundArchive クラス 297 //! 298 //! @date 2010/01/15 初版 299 //--------------------------------------------------------------------------- 300 const SoundArchive& GetSoundArchive() const; 301 302 //--------------------------------------------------------------------------- 303 //! @brief 指定した ID のサウンドプレイヤーを取得します。 304 //! 305 //! @param[in] playerId プレイヤーの ID です。 306 //! 307 //! @return 指定した ID のサウンドプレイヤーを返します。 308 //! 309 //! @see SoundPlayer クラス 310 //! 311 //! @date 2010/01/15 初版 312 //--------------------------------------------------------------------------- 313 SoundPlayer& GetSoundPlayer( SoundArchive::ItemId playerId ); 314 315 //--------------------------------------------------------------------------- 316 //! @brief 指定した ID のサウンドプレイヤーを取得します。 317 //! 318 //! @param[in] pPlayerName プレイヤーのラベル文字列です。 319 //! 320 //! @return 指定した ID のサウンドプレイヤーを返します。 321 //! 322 //! @see SoundPlayer クラス 323 //! 324 //! @date 2010/01/15 初版 325 //--------------------------------------------------------------------------- 326 SoundPlayer& GetSoundPlayer( const char* pPlayerName ); 327 328 //--------------------------------------------------------------------------- 329 //! @brief サウンドプレイヤーの個数を取得します。 330 //! 331 //! @return サウンドプレイヤーの個数を返します。 332 //! 333 //! @see SoundPlayer クラス 334 //! 335 //! @date 2010/02/01 返り値の型を変更 (unsigned long → u32) 336 //! @date 2010/01/15 初版 337 //--------------------------------------------------------------------------- GetSoundPlayerCount()338 u32 GetSoundPlayerCount() const { return m_SoundPlayerCount; } 339 340 //--------------------------------------------------------------------------- 341 //! @brief 再生可能なシーケンスサウンドの残数を取得します。 342 //! 343 //! 残数が 0 のときに新たにシーケンスサウンドを再生すると、 344 //! 既に再生中の最もプレイヤープライオリティの低いサウンドが停止します。 345 //! ただし、新たに再生するサウンドのほうがプレイヤープライオリティが低い場合は、 346 //! 再生に失敗します。 347 //! 348 //! 再生可能なシーケンスサウンドの総数は、 349 //! サウンドアーカイブに記述されていて、 350 //! @ref Initialize でサウンドアーカイブプレイヤーに設定されます。 351 //! 352 //! @return 再生可能なシーケンスサウンドの残数を返します。 353 //! 354 //! @see Initialize 355 //! 356 //! @date 2010/02/01 関数名変更 (Setup → Initialize) にともなう文言の調整 357 //! @date 2010/01/15 初版 358 //--------------------------------------------------------------------------- GetFreeSequenceSoundCount()359 int GetFreeSequenceSoundCount() const 360 { 361 return m_SequenceSoundInstanceManager.GetFreeCount(); 362 } 363 364 //--------------------------------------------------------------------------- 365 //! @brief 再生可能なウェーブサウンドの残数を取得します。 366 //! 367 //! 残数が 0 のときに新たにウェーブサウンドを再生すると、 368 //! 既に再生中の最もプレイヤープライオリティの低いサウンドが停止します。 369 //! ただし、新たに再生するサウンドのほうがプレイヤープライオリティが低い場合は、 370 //! 再生に失敗します。 371 //! 372 //! 再生可能なウェーブサウンドの総数は、 373 //! サウンドアーカイブに記述されていて、 374 //! @ref Initialize でサウンドアーカイブプレイヤーに設定されます。 375 //! 376 //! @return 再生可能なウェーブサウンドの残数を返します。 377 //! 378 //! @see Initialize 379 //! 380 //! @date 2010/02/01 関数名変更 (Setup → Initialize) にともなう文言の調整 381 //! @date 2010/01/15 初版 382 //--------------------------------------------------------------------------- GetFreeWaveSoundCount()383 int GetFreeWaveSoundCount() const 384 { 385 return m_WaveSoundInstanceManager.GetFreeCount(); 386 } 387 388 //--------------------------------------------------------------------------- 389 //! @brief 再生可能なストリームサウンドの残数を取得します。 390 //! 391 //! 残数が 0 のときに新たにストリームサウンドを再生すると、 392 //! 既に再生中の最もプレイヤープライオリティの低いサウンドが停止します。 393 //! ただし、新たに再生するサウンドのほうがプレイヤープライオリティが低い場合は、 394 //! 再生に失敗します。 395 //! 396 //! 再生可能なストリームサウンドの総数は、 397 //! サウンドアーカイブに記述されていて、 398 //! @ref Initialize でサウンドアーカイブプレイヤーに設定されます。 399 //! 400 //! @return 再生可能なストリームサウンドの残数を返します。 401 //! 402 //! @see Initialize 403 //! 404 //! @date 2010/02/01 関数名変更 (Setup → Initialize) にともなう文言の調整 405 //! @date 2010/01/15 初版 406 //--------------------------------------------------------------------------- GetFreeStreamSoundCount()407 int GetFreeStreamSoundCount() const 408 { 409 return m_StreamSoundInstanceManager.GetFreeCount(); 410 } 411 412 //--------------------------------------------------------------------------- 413 //! @brief シーケンスコマンド 'userproc' で呼び出される 414 //! コールバック関数を登録します。 415 //! 416 //! ここで登録したコールバックは、シーケンスデータ側のシーケンスコマンド 417 //! 'userproc' が処理されたフレームで呼び出されます。 418 //! コールバック関数はサウンドスレッド呼び出されます。 419 //! 420 //! 'userproc' コマンドの詳細については、 421 //! シーケンスデータマニュアルを参照してください。 422 //! 423 //! @param[in] callback 登録するコールバック関数です。 424 //! @param[in] callbackArg コールバック関数に渡されるユーザー引数です。 425 //! 426 //! @ref SequenceUserprocCallback 427 //! 428 //! @date 2010/01/15 初版 429 //--------------------------------------------------------------------------- 430 void SetSequenceUserprocCallback( 431 SequenceUserprocCallback callback, void* callbackArg ); 432 //@} 433 434 435 // StartSound実装 436 //! @details :private 437 StartResult detail_SetupSoundImpl( 438 SoundHandle* handle, 439 u32 soundId, 440 internal::BasicSound::AmbientInfo* ambientArgInfo, 441 SoundActor* actor, 442 bool holdFlag, 443 const StartInfo* startInfo 444 ); 445 //! @details :private detail_GetItemId(const char * pString)446 virtual SoundArchive::ItemId detail_GetItemId( const char* pString ) 447 { 448 NW_NULL_ASSERT( m_pSoundArchive ); 449 return m_pSoundArchive->GetItemId( pString ); 450 } 451 452 453 // 非公開関数 454 //! @details :private detail_SetMmlParser(internal::driver::MmlParser * parser)455 void detail_SetMmlParser( internal::driver::MmlParser* parser ) 456 { 457 if ( parser == NULL ) m_MmlSequenceTrackAllocator.SetMmlParser( &m_MmlParser ); 458 else m_MmlSequenceTrackAllocator.SetMmlParser( parser ); 459 } 460 //! @details :private 461 const void* detail_GetFileAddress( SoundArchive::FileId fileId ) const; 462 463 protected: 464 virtual StartResult detail_SetupSound( 465 SoundHandle* handle, 466 u32 soundId, 467 bool holdFlag, 468 const StartInfo* startInfo 469 ); 470 471 private: 472 473 template< typename Sound, typename Player > 474 Sound* AllocSound( 475 internal::SoundInstanceManager< Sound, Player >* manager, 476 SoundArchive::ItemId soundId, 477 int priority, 478 int ambientPriority, 479 internal::BasicSound::AmbientInfo* ambientArgInfo 480 ); 481 482 StartResult PrepareSeqImpl( 483 internal::SequenceSound* sound, 484 const SoundArchive::SoundInfo* commonInfo, 485 const SoundArchive::SequenceSoundInfo* info, 486 SoundStartable::StartInfo::StartOffsetType startOffsetType, 487 int startOffset, 488 const StartInfo::SeqSoundInfo* externalSeqInfo 489 ); 490 491 StartResult PrepareStreamImpl( 492 internal::StreamSound* sound, 493 const SoundArchive::SoundInfo* commonInfo, 494 const SoundArchive::StreamSoundInfo* info, 495 SoundStartable::StartInfo::StartOffsetType startOffsetType, 496 int startOffset 497 ); 498 499 StartResult PrepareWaveSoundImpl( 500 internal::WaveSound* sound, 501 const SoundArchive::SoundInfo* commonInfo, 502 const SoundArchive::WaveSoundInfo* info, 503 SoundStartable::StartInfo::StartOffsetType startOffsetType, 504 int startOffset 505 ); 506 507 508 internal::PlayerHeap* CreatePlayerHeap( 509 void** ppBuffer, void* pEndAddress, size_t heapSize ); 510 511 // Setup 512 bool SetupMram( const SoundArchive* arc, void* buffer, unsigned long size ); 513 bool SetupSoundPlayer( const SoundArchive* arc, void** buffer, void* endp ); 514 bool SetupSequenceSound( const SoundArchive* arc, int numSounds, void** buffer, void* endp ); 515 bool SetupSequenceTrack( const SoundArchive* arc, int numTracks, void** buffer, void* endp ); 516 bool SetupWaveSound( const SoundArchive* arc, int numSounds, void** buffer, void* endp ); 517 bool SetupStreamSound( const SoundArchive* arc, int numSounds, void** buffer, void* endp ); 518 bool SetupStreamBuffer( const SoundArchive* arc, void* buffer, unsigned long size ); 519 520 void UpdateCommonSoundParam( internal::BasicSound* sound, const SoundArchive::SoundInfo* commonInfo ); 521 522 const SoundArchive* m_pSoundArchive; 523 524 // コールバック 525 SequenceNoteOnCallback m_SequenceCallback; 526 WaveSoundCallback m_WaveSoundCallback; 527 SequenceUserprocCallback m_SequenceUserprocCallback; 528 void* m_pSequenceUserprocCallbackArg; 529 530 // サウンドプレイヤー 531 u32 m_SoundPlayerCount; 532 SoundPlayer* m_pSoundPlayers; 533 534 // マネージャー・アロケータ 535 internal::SequenceSoundInstanceManager m_SequenceSoundInstanceManager; 536 internal::WaveSoundInstanceManager m_WaveSoundInstanceManager; 537 internal::StreamSoundInstanceManager m_StreamSoundInstanceManager; 538 539 internal::driver::SequenceTrackAllocator* m_pSequenceTrackAllocator; 540 internal::driver::MmlSequenceTrackAllocator m_MmlSequenceTrackAllocator; // デフォルトのシーケンストラックアロケータ 541 542 internal::driver::StreamBufferPool m_StreamBufferPool; 543 544 // デフォルトのシーケンスパーサ 545 internal::driver::MmlParser m_MmlParser; 546 547 // バッファ情報記憶 548 void* m_pSetupBufferAddress; 549 u32 m_SetupBufferSize; 550 551 // データマネージャ 552 const SoundDataManager* m_pSoundDataManager; 553 }; 554 555 } // namespace nw::snd 556 } // namespace nw 557 558 559 #endif /* NW_SND_SOUND_ARCHIVE_PLAYER_H_ */ 560 561