ã»ãšãã©ã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯å¹æé³ãåçããå¿ èŠã¯ãããŸããããå¹æé³ãªãã§ã¯ã§ããªãå ŽåããããŸãã 次ã«ã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ããããã£ã®å€ãèšå®ãããšãåé¢ã³ãŒãã³ã³ãã³ããå®å šã«æé€ãããŸãã
ãã®å¹æé³åçæ¹æ³ã䜿çšããå©ç¹ïŒ
- å®è£ ãšäœ¿çšã®ãããã
- ãµããŒããããŠãããªãã¬ãŒãã£ã³ã°ã·ã¹ãã 圢åŒã®ãã¡ã€ã«ã³ã³ãã³ããåçãã
çæïŒ
- ã³ã³ãããŒã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ããžã¥ã¢ã«ããªãŒã«è¿œå ããå¿ èŠããããŸãã
- ãã®æ¹æ³ã§ã¯ãäžåºŠã«1ã€ã®ãµãŠã³ãããåçã§ããŸãããããã¥ã¡ã³ãã«ã¯ã1ã€ã®ã³ã³ãããŒã«ããèš±å¯ãããŠããªãããšã瀺ãããŠããŸãã
- ãµãŠã³ãã®åçã¯ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã«é¢é£ä»ããããŠãããUIã¹ããªãŒã ãšã®åæãå¿ èŠã§ãã
- ã·ãŒã ã¬ã¹ã«ãŒãåçãæé ã§ããŸããã
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ã䜿çšããŠãµãŠã³ããåçããå©ç¹ïŒ
- 䜿ããããã
- é³éãé床ãç¹°ãè¿ããªã©ã®å¹æé³ã®é«åºŠãªèšå®
çæïŒ
- ãã€ã¯ããœããã«ãã£ãŠãµããŒããããªããªã£ãéæšå¥šã®ãã¯ãããžãŒã
- 倧éã®ã¡ã¢ãªãæ¶è²»ããPCM圢åŒã®WAVãã¡ã€ã«ã®ã¿ãåçããŸãã
- ã²ãŒã ãµã€ã¯ã«ãšãã¥ã¬ãŒã·ã§ã³ã®åœ¢ã§ã®è¿œå æäœã®å¿ èŠæ§ã
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; };
ãã¡ã€ã«ã解æãããšããã¯ã©ã¹ã¯ä»¥äžããã§ãã¯ããŸãïŒ
- ãã¡ã€ã«ã«ã¯æ³¢ããŒã¿ãå«ãŸããŠããŸã
- ãã¡ã€ã«ã«frmïŒãã©ãŒãããïŒéšåãå«ãŸããŠããããã®ãµã€ãºãWAVEFORMATEXæ§é äœã®ãµã€ãºããå°ãããªãããš
- PCMãŸãã¯ADPCMãªãŒãã£ãªããŒã¿åœ¢åŒ
- ãã¡ã€ã«ã«ããŒã¿éšåãå«ãŸããŠããŸã
ãã©ã°ã©ã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