/// <summary> /// Clean up the SecondaryBuffer /// </summary> /// <remarks> /// <para> /// In DirectSound, when playback is started, /// the rest of the sound that was played last time is played back as noise. /// This happens even if the secondary buffer is completely silenced, /// so it seems that the buffer in the primary buffer or higher is not cleared. /// </para> /// <para> /// To solve this problem fill the secondary buffer with silence data when stop playback. /// </para> /// </remarks> private void CleanUpSecondaryBuffer() { if (secondaryBuffer != null) { byte[] silence = new byte[samplesTotalSize]; // Lock the SecondaryBuffer IntPtr wavBuffer1; int nbSamples1; IntPtr wavBuffer2; int nbSamples2; secondaryBuffer.Lock(0, (uint)samplesTotalSize, out wavBuffer1, out nbSamples1, out wavBuffer2, out nbSamples2, DirectSoundBufferLockFlag.None); // Copy silence data to the SecondaryBuffer if (wavBuffer1 != IntPtr.Zero) { Marshal.Copy(silence, 0, wavBuffer1, nbSamples1); if (wavBuffer2 != IntPtr.Zero) { Marshal.Copy(silence, 0, wavBuffer1, nbSamples1); } } // Unlock the SecondaryBuffer secondaryBuffer.Unlock(wavBuffer1, nbSamples1, wavBuffer2, nbSamples2); } }
/// <summary> /// Feeds the SecondaryBuffer with the WaveStream /// </summary> /// <param name="bytesToCopy">number of bytes to feed</param> private int Feed(int bytesToCopy) { int bytesRead = bytesToCopy; // Restore the buffer if lost if (IsBufferLost()) { secondaryBuffer.Restore(); } // Clear the bufferSamples if in Paused if (playbackState == PlaybackState.Paused) { Array.Clear(samples, 0, samples.Length); } else { // Read data from stream (Should this be inserted between the lock / unlock?) bytesRead = waveStream.Read(samples, 0, bytesToCopy); if (bytesRead == 0) { Array.Clear(samples, 0, samples.Length); return(0); } } // Lock a portion of the SecondaryBuffer (starting from 0 or 1/2 the buffer) IntPtr wavBuffer1; int nbSamples1; IntPtr wavBuffer2; int nbSamples2; secondaryBuffer.Lock(nextSamplesWriteIndex, (uint)bytesRead, // (uint)bytesToCopy, out wavBuffer1, out nbSamples1, out wavBuffer2, out nbSamples2, DirectSoundBufferLockFlag.None); // Copy back to the SecondaryBuffer if (wavBuffer1 != IntPtr.Zero) { Marshal.Copy(samples, 0, wavBuffer1, nbSamples1); if (wavBuffer2 != IntPtr.Zero) { Marshal.Copy(samples, 0, wavBuffer1, nbSamples1); } } // Unlock the SecondaryBuffer secondaryBuffer.Unlock(wavBuffer1, nbSamples1, wavBuffer2, nbSamples2); return(bytesRead); }