/// <summary> /// Plays the given sound. /// </summary> /// <param name="soundFile">The sound file to be played.</param> /// <param name="volume">The volume of the sound to be played.</param> public async Task PlaySoundAsync(CachedSoundFile soundFile, float volume = 1f) { soundFile.EnsureNotNullOrDisposed(nameof(soundFile)); volume.EnsurePositive(nameof(volume)); if (!m_xaudioDevice.IsLoaded) { return; } // Play the sound on the device using (var sourceVoice = new XA.SourceVoice(m_xaudioDevice.Device, soundFile.Format, true)) { // Register the created voice m_playingVoices.Add(sourceVoice); // Start voice playing TaskCompletionSource<object> complSource = new TaskCompletionSource<object>(); sourceVoice.SubmitSourceBuffer(soundFile.AudioBuffer, soundFile.DecodedPacketsInfo); sourceVoice.SetVolume(volume); sourceVoice.BufferEnd += (pointer) => { complSource.TrySetResult(null); }; sourceVoice.Start(); // Await finished playing await complSource.Task; // Destroy the voice object // A NullReference is raised later, if we forget this call sourceVoice.DestroyVoice(); // Remove the created voice finally m_playingVoices.Remove(sourceVoice); } }
/// <summary> /// Loads a sound file from the given resource. /// </summary> /// <param name="resource">The resource to load.</param> public static async Task <CachedSoundFile> FromResourceAsync(ResourceLink resource) { resource.EnsureNotNull(nameof(resource)); CachedSoundFile result = new CachedSoundFile(); using (Stream inStream = await resource.OpenInputStreamAsync()) using (SDXM.SoundStream stream = new SDXM.SoundStream(inStream)) { await Task.Factory.StartNew(() => { // Read all data into the adio buffer SDXM.WaveFormat waveFormat = stream.Format; XA.AudioBuffer buffer = new XA.AudioBuffer { Stream = stream.ToDataStream(), AudioBytes = (int)stream.Length, Flags = XA.BufferFlags.EndOfStream }; // Store members result.m_decodedPacketsInfo = stream.DecodedPacketsInfo; result.m_format = waveFormat; result.m_audioBuffer = buffer; }); } return(result); }
/// <summary> /// Plays the given sound. /// </summary> /// <param name="resource">The file to be played.</param> public async Task PlaySoundAsync(ResourceLink resource) { resource.EnsureNotNull(nameof(resource)); using (CachedSoundFile cachedSoundFile = await CachedSoundFile.FromResourceAsync(resource)) { await PlaySoundAsync(cachedSoundFile); } }