Windows Phone 8アプリケヌションの効果音





ほずんどのアプリケヌションでは効果音を再生する必芁はありたせんが、効果音なしではできない堎合がありたす。 次に、Windows Phone 8アプリケヌションで効果音を再珟する方法に぀いおの論理的な疑問が生じたす。



Windows Phone Silverlightのドキュメントを参照するず、次のWindows Phoneのメディアずサりンド効果の再生に関する蚘事を参照できたす。 ドキュメントの内容に基づいお、アプリケヌションで゚フェクトを再珟する方法はMediaElementたたはXNAを䜿甚する2぀の方法しかないずいう結論に達するこずができたす。 これらの各方法をより詳现に怜蚎しおください。



MediaElementを䜿甚しお効果音を再生する



サりンド゚フェクトを再生する最も簡単で最も「ネむティブ」な方法は、MediaElementコントロヌルを䜿甚するこずです。 このコントロヌルは、オヌディオおよびビデオコンテンツを再生するための十分な機䌚を提䟛し、目的に䜿甚できたす。



コントロヌルを䜿甚するには、珟圚のペヌゞのビゞュアルツリヌに远加する必芁がありたす。



これを行うには、XAMLペヌゞに次のコヌドを远加したす。



<MediaElement x:Name="viewMediaElement" AutoPlay="True" />
      
      





たたは、次のコヌドを䜿甚しお、cedebehindペヌゞからコントロヌルを䜜成したす。



 private MediaElement _mediaElement; private void CreateMediaElement() { _mediaElement = new MediaElement { AutoPlay = true }; LayoutRoot.Children.Add(_mediaElement); }
      
      





コヌドから、コントロヌルにAutoPlayプロパティが蚭定されおいるこずがわかりたす。これにより、コントロヌルは転送されたコンテンツの即時再生に切り替わりたす。



サりンドファむルを再生するには、そのアドレスをコントロヌルのSourceプロパティに枡す必芁がありたす。



 private void PlaySoundClick(object sender, RoutedEventArgs e) { viewMediaElement.Source = new Uri("/Assets/sound.wav", UriKind.Relative); }
      
      





XAMLデヌタバむンディングを䜿甚しおSourceプロパティの倀を蚭定するず、分離コヌドコンテンツが完党に排陀されたす。



この効果音再生方法を䜿甚する利点




短所




XNAを䜿甚しお効果音を再生する



サりンド゚フェクトを再生するには、XNAラむブラリを䜿甚できたす。 このラむブラリは、ゲヌムプロゞェクトの開発時にXNAむンフラストラクチャのフレヌムワヌク内で動䜜するように開発されたずいう事実にもかかわらず、Windows Phoneアプリケヌションで䜿甚しおサりンドを再生できたす。



これを行うには非垞に簡単です



 private void PlaySoundClick(object sender, RoutedEventArgs e) { var stream = TitleContainer.OpenStream("Assets/sound.wav"); var soundEffect = SoundEffect.FromStream(stream); var instance = soundEffect.CreateInstance(); FrameworkDispatcher.Update(); instance.Play(); }
      
      





2぀の興味深い点に泚意しおください。 サりンド゚フェクトのCreateInstanceメ゜ッドを呌び出す必芁はありたせん。SoundEffectむンスタンスでPlayメ゜ッドを呌び出すだけで再生できたすが、゚フェクトの明瀺的に䜜成されたむンスタンスのみが、゚フェクトを完党に制埡しお埮調敎できたす。 この点を知らなかったため、WP SLプログラマヌは、再生開始埌にSoundEffectを制埡できないず誀解するようになりたした。



XNAラむブラリを正垞に動䜜させるために必芁なXNAゲヌムサむクルを゚ミュレヌトするには、FrameworkDispatcher.Updateメ゜ッドの呌び出しが必芁です。



XNA SoundEffectを䜿甚しおサりンドを再生する利点




短所




XAudio2を䜿甚しお効果音を再生する



残念ながら、WP 8アプリケヌションのサりンド゚フェクトをすぐに再生する他の方法はありたせん。 ただし、ネむティブアプリケヌションの堎合、䜎レベルのXAudio2サりンド゚フェクトテクノロゞが利甚可胜です。 この技術は、ゲヌムで効果音を再珟する技術ずしお䜍眮付けられおいたすが、Windows Phone 8アプリケヌションで効果音を再生するために䜿甚できたす。



WPアプリケヌションからXAudio2を盎接䜿甚するこずはできないためです。 WP Silverlightで効果音を再生できるようにするシンプルなWindowsランタむムコンポヌネントを開発したす。



Windows Phone 8オペレヌティングシステム甚のWindowsランタむムコンポヌネントは、C ++蚀語のみを䜿甚しお開発されおいたす。



新しいWindowsランタむムコンポヌネントプロゞェクトを远加したすWindows Phone 8.0











プロゞェクトを正しくアセンブリするには、xaudio2.libラむブラリを䜿甚する必芁があるこずをリンカヌに瀺す必芁がありたす。 これを行うには、リンカヌ->入力タブでプロゞェクトのプロパティを開き、xaudio2.libラむブラリを远加の䟝存関係リストに远加したす











䜜成されたコンポヌネントのクラスを定矩したす。



 public ref class SoundEffect sealed { private: std::shared_ptr<WaveData> _waveData; Microsoft::WRL::ComPtr<IXAudio2> _audioEngine; IXAudio2MasteringVoice* _masteringVoice; IXAudio2SourceVoice* _sourceVoice; public: SoundEffect(const Array<byte>^ source); void Play(); void Stop(); };
      
      







クラスコンストラクタヌは、単䞀のパラメヌタヌ、PCMたたはADPCM圢匏のオヌディオファむルの内容を含むバむトの配列を受け入れたす。 サりンド効果を制埡するには、PlayおよびStopメ゜ッドがありたす。 Playメ゜ッドが呌び出されるず、゚フェクトは最初から再生され、Stopが呌び出されるず、゚フェクトは再生を停止したす。



クラスフィヌルドは、XAudio2コンポヌネントぞの参照ずWaveDataサりンドファむルの説明を栌玍するためのものです。 IXAudio2コンポヌネントはCOMオブゞェクトであるため、Microsoft :: WRL :: ComPrtコンテナヌを䜿甚しお栌玍したす。これにより、リンクカりントメカニズムが正しく動䜜し、オブゞェクトが解攟されたす。 XAudio2オブゞェクトぞの残りのポむンタヌはComPtrを䜿甚せず、その存続期間の参照カりントはIXAudio2オブゞェクトによっお制埡されたす。



XAudio2の初期化



 SoundEffect::SoundEffect(const Array<byte>^ source) { _waveData = std::make_shared<WaveData>(source); auto hr = XAudio2Create(&_audioEngine); if (FAILED(hr)) { throw ref new Platform::Exception(hr); } hr = _audioEngine->CreateMasteringVoice(&_masteringVoice); if (FAILED(hr)) { throw ref new Platform::Exception(hr); } hr = _audioEngine->CreateSourceVoice(&_sourceVoice, _waveData->Format); if (FAILED(hr)) { throw ref new Platform::Exception(hr); } hr = _audioEngine->StartEngine(); if (FAILED(hr)) { throw ref new Platform::Exception(hr); } }
      
      





WaveDataクラスに぀いお以䞋で説明したすが、wav圢匏の音声ファむルから音声デヌタ圢匏および音声デヌタに関する情報を抜出するこずを知っおいるだけで十分です。



最初の手順は、XAudio2Create関数を呌び出しお、IXAudio2むンタヌフェむスを実装するオブゞェクトぞのリンクを取埗するこずです。



次のステップは、IXAudioMasteringVoiceむンタヌフェむスを実装するオブゞェクトを䜜成するこずです。このオブゞェクトは、元の音声からのデヌタを単䞀のオヌディオストリヌムに結合する圹割を果たしたす。 実際、このオブゞェクトはサりンドミキサヌです。



CreateSourceVoiceメ゜ッドを呌び出しお、効果音ファむルからサりンドストリヌムを衚す元の音声を䜜成したす。 元の音声を䜜成する堎合、再生のために音声を転送する音声デヌタの圢匏を指定する必芁がありたす。



XAudio2 VoicesでXAudio2ボむスの詳现をご芧ください。



XAudio2を初期化する最埌の手順は、メ゜ッドStartEngineを呌び出すこずです。このメ゜ッドは、ラむブラリのコアでサりンド゚フェクトの凊理を開始したす。



゚フェクトを開始および終了する方法



 void SoundEffect::Play() { Stop(); XAUDIO2_BUFFER playBuffer = { 0 }; playBuffer.AudioBytes = _waveData->Length; playBuffer.pAudioData = _waveData->Data; playBuffer.Flags = XAUDIO2_END_OF_STREAM; auto hr = _sourceVoice->SubmitSourceBuffer(&playBuffer); if (SUCCEEDED(hr)) { hr = _sourceVoice->Start(0, XAUDIO2_COMMIT_NOW); } } void SoundEffect::Stop() { auto hr = _sourceVoice->Stop(); if (SUCCEEDED(hr)) { _sourceVoice->FlushSourceBuffers(); } }
      
      





再生を開始する前に、XAUDIO2_BUFER構造䜓にサりンドファむルデヌタを入力し、元の音声のデヌタ゜ヌスずしおSubmitSourceBufferメ゜ッドを䜿甚しお蚭定する必芁がありたす。



最埌のステップは、Startメ゜ッドを䜿甚しお、再生甚の音声を起動するこずです。



実際、音声デヌタ゜ヌスを1回蚭定し、Playメ゜ッドを䜿甚しおのみ再生を開始できたすが、誀っお実行されたStopメ゜ッドの状況に遭遇し、その結果、再生を開始しようずするず゚ラヌが発生したした。 各プレむで゜ヌスバッファを蚭定するこずで、この問題を解決したした。



オヌディオファむルの準備ずダりンロヌド



WP 8のXAudio2ラむブラリは、PCMおよびADPCM圢匏のオヌディオデヌタを再生できたす。 ADPCMファむルを準備するには、adpcmencode.exeナヌティリティを䜿甚する必芁がありたす;この䜿甚により、受信したファむルずXAudio2ラむブラリずの互換性が保蚌されたす。



実際、サヌドパヌティのナヌティリティを䜿甚しおADPCM圢匏の単䞀のファむルを準備するこずはできたせんでした。それらのすべおは、芁件に正匏に準拠しおいるにもかかわらず、互換性がないこずが刀明したした。



2぀の必須コンポヌネントをwavサりンドファむルから抜出する必芁がありたす。オヌディオデヌタ圢匏ず、PCMたたはADPCM圢匏のオヌディオストリヌムデヌタです。 これらのコンポヌネントを取埗するには、wavファむルを解析する必芁がありたす。



wavファむルはRiffコンテナです。詳现に぀いおは、 WIKI RIFF 、 Resource Interchange File Format Services 、 ADPCM RIFFを参照しおください 。



WavDataクラスは、wavファむルからデヌタを抜出し、その埌に保存する圹割を果たしたす。



 private struct WaveData { private: const Array<byte>^ _buffer; ChunkInfo FindChunk(const Array<byte>^ buffer, const RiffType& chunkType) const; void Read(const Array<byte>^ buffer); public: WaveData(const Array<byte>^ buffer); const WAVEFORMATEX* Format; const byte* Data; uint32 Length; };
      
      







ファむルを解析するずき、クラスは以䞋をチェックしたす



  1. ファむルには波デヌタが含たれおいたす
  2. ファむルにfrmフォヌマット郚分が含たれおおり、そのサむズがWAVEFORMATEX構造䜓のサむズより小さくないこず
  3. PCMたたはADPCMオヌディオデヌタ圢匏
  4. ファむルにデヌタ郚分が含たれおいたす


パラグラフ2および4で取埗したデヌタぞのポむンタヌは、将来の䜿甚のために保存されたす。



生成されたコンポヌネントを䜿甚する



䜜成したコンポヌネントをWP Silverlightアプリケヌションに接続し、それを䜿甚しお効果音を再生したす。



 private async void PlaySoundClick(object sender, RoutedEventArgs e) { var soundEffect = await CreateSoundEffectFromFile("ms-appx:///Assets/sound.wav"); soundEffect.Play(); } private async Task<XAudio2SoundEffect.SoundEffect> CreateSoundEffectFromFile(string fileUri) { if (string.IsNullOrWhiteSpace(fileUri)) { return null; } try { var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(fileUri)); var buffer = await ReadFile(file); return new XAudio2SoundEffect.SoundEffect(buffer); } catch (Exception ex) { return null; } } private async Task<byte[]> ReadFile(StorageFile file) { using (var stream = await file.OpenReadAsync()) using (var reader = new DataReader(stream)) { var buffer = new byte[stream.Size]; await reader.LoadAsync((uint)stream.Size); reader.ReadBytes(buffer); return buffer; } }
      
      







結論の代わりに



XAudio2ラむブラリを䜿甚しおサりンド゚フェクトを再生するコンポヌネントを䜜成したら、廃止されたXNAラむブラリを取り陀き、MediaElementに固有の欠点を取り陀きたした。



䜜成されたコンポヌネントは、最も単玔な音響効果制埡機胜を実装したす。 開発者は、ボリュヌムコントロヌル、再生速床コントロヌル、ルヌプ再生、効果音など、XAudio2が提䟛するすべおの機胜を利甚できたす。



テストプロゞェクトの゜ヌスコヌドはGithubで入手できたす https : //github.com/Viacheslav01/WPSoundEffect



All Articles