/// <summary> /// Starts playing specified wave file for the specified number of times. /// </summary> /// <param name="stream">Wave stream.</param> /// <param name="count">Number of times to play.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null reference.</exception> public void Play(Stream stream, int count) { if (stream == null) { throw new ArgumentNullException("stream"); } if (m_IsPlaying) { Stop(); } m_IsPlaying = true; m_Stop = false; ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state){ using (BinaryReader waveFile = new BinaryReader(stream)){ WavReader wavReader = new WavReader(waveFile); if (!string.Equals(wavReader.Read_ChunkID(), "riff", StringComparison.InvariantCultureIgnoreCase)) { throw new ArgumentNullException("Invalid wave file, RIFF header missing."); } RIFF_Chunk riff = wavReader.Read_RIFF(); wavReader.Read_ChunkID(); fmt_Chunk fmt = wavReader.Read_fmt(); using (AudioOut player = new AudioOut(m_pOutputDevice, fmt.SampleRate, fmt.BitsPerSample, fmt.NumberOfChannels)){ long audioStartOffset = waveFile.BaseStream.Position; // Loop audio playing for specified times. for (int i = 0; i < count; i++) { waveFile.BaseStream.Position = audioStartOffset; // Read wave chunks. while (true) { string chunkID = wavReader.Read_ChunkID(); // EOS reached. if (chunkID == null || (waveFile.BaseStream.Length - waveFile.BaseStream.Position) < 4) { break; } // Wave data chunk. else if (string.Equals(chunkID, "data", StringComparison.InvariantCultureIgnoreCase)) { data_Chunk data = wavReader.Read_data(); int totalReaded = 0; byte[] buffer = new byte[8000]; while (totalReaded < data.ChunkSize) { if (m_Stop) { m_IsPlaying = false; return; } // Read audio block. int countReaded = waveFile.Read(buffer, 0, (int)Math.Min(buffer.Length, data.ChunkSize - totalReaded)); // Queue audio for play. player.Write(buffer, 0, countReaded); // Don't buffer more than 2x read buffer, just wait some data played out first. while (m_IsPlaying && player.BytesBuffered >= (buffer.Length * 2)) { Thread.Sleep(10); } totalReaded += countReaded; } } // unknown chunk. else { wavReader.SkipChunk(); } } } // Wait while audio playing is completed. while (m_IsPlaying && player.BytesBuffered > 0) { Thread.Sleep(10); } } } m_IsPlaying = false; })); }
/// <summary> /// Starts playing specified wave file for the specified number of times. /// </summary> /// <param name="stream">Wave stream.</param> /// <param name="count">Number of times to play.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null reference.</exception> public void Play(Stream stream,int count) { if(stream == null){ throw new ArgumentNullException("stream"); } if(m_IsPlaying){ Stop(); } m_IsPlaying = true; m_Stop = false; ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state){ using(BinaryReader waveFile = new BinaryReader(stream)){ WavReader wavReader = new WavReader(waveFile); if(!string.Equals(wavReader.Read_ChunkID(),"riff",StringComparison.InvariantCultureIgnoreCase)){ throw new ArgumentNullException("Invalid wave file, RIFF header missing."); } RIFF_Chunk riff = wavReader.Read_RIFF(); wavReader.Read_ChunkID(); fmt_Chunk fmt = wavReader.Read_fmt(); using(AudioOut player = new AudioOut(m_pOutputDevice,fmt.SampleRate,fmt.BitsPerSample,fmt.NumberOfChannels)){ long audioStartOffset = waveFile.BaseStream.Position; // Loop audio playing for specified times. for(int i=0;i<count;i++){ waveFile.BaseStream.Position = audioStartOffset; // Read wave chunks. while(true){ string chunkID = wavReader.Read_ChunkID(); // EOS reached. if(chunkID == null || (waveFile.BaseStream.Length - waveFile.BaseStream.Position) < 4){ break; } // Wave data chunk. else if(string.Equals(chunkID,"data",StringComparison.InvariantCultureIgnoreCase)){ data_Chunk data = wavReader.Read_data(); int totalReaded = 0; byte[] buffer = new byte[8000]; while(totalReaded < data.ChunkSize){ if(m_Stop){ m_IsPlaying = false; return; } // Read audio block. int countReaded = waveFile.Read(buffer,0,(int)Math.Min(buffer.Length,data.ChunkSize - totalReaded)); // Queue audio for play. player.Write(buffer,0,countReaded); // Don't buffer more than 2x read buffer, just wait some data played out first. while(m_IsPlaying && player.BytesBuffered >= (buffer.Length * 2)){ Thread.Sleep(10); } totalReaded += countReaded; } } // unknown chunk. else{ wavReader.SkipChunk(); } } } // Wait while audio playing is completed. while(m_IsPlaying && player.BytesBuffered > 0){ Thread.Sleep(10); } } } m_IsPlaying = false; })); }