public DXWavePlayer(int device, int BufferByteSize, DataRequestDelegate fillProc) { if (BufferByteSize < 1000) { throw new ArgumentOutOfRangeException("BufferByteSize", "minimal size of buffer is 1000 bytes"); } _buffersize = BufferByteSize; _requestproc = fillProc; var devices = DirectSound.GetDevices(); if (device <= 0 || device >= devices.Count) { device = 0; } _outputDevice = new DirectSound(devices[device].DriverGuid); System.Windows.Interop.WindowInteropHelper wh = new System.Windows.Interop.WindowInteropHelper(Application.Current.MainWindow); _outputDevice.SetCooperativeLevel(wh.Handle, CooperativeLevel.Priority); _buffDescription = new SoundBufferDescription(); _buffDescription.Flags = BufferFlags.ControlPositionNotify | BufferFlags.ControlFrequency | BufferFlags.ControlEffects | BufferFlags.GlobalFocus | BufferFlags.GetCurrentPosition2; _buffDescription.BufferBytes = BufferByteSize * InternalBufferSizeMultiplier; WaveFormat format = new WaveFormat(16000, 16, 1); _buffDescription.Format = format; _soundBuffer = new SecondarySoundBuffer(_outputDevice, _buffDescription); _synchronizer = new AutoResetEvent(false); NotificationPosition[] nots = new NotificationPosition[InternalBufferSizeMultiplier]; NotificationPosition not; int bytepos = 800; for (int i = 0; i < InternalBufferSizeMultiplier; i++) { not = new NotificationPosition(); not.Offset = bytepos; not.WaitHandle = _synchronizer; nots[i] = not; bytepos += BufferByteSize; } _soundBuffer.SetNotificationPositions(nots); _waitThread = new Thread(new ThreadStart(DataRequestThread)) { Name = "MyWavePlayer.DataRequestThread" }; _waitThread.Start(); }
private void PlayFile(FileInfo FI) { lock (this) { if (this.DS == null) { this.DS = new DirectSound(); this.DS.SetCooperativeLevel(this.Handle, CooperativeLevel.Normal); } this.StopPlayback(); var bd = new SoundBufferDescription { Format = new WaveFormat(FI.AudioFile.SampleRate, 16, FI.AudioFile.Channels), BufferBytes = this.AudioBufferSize, Flags = BufferFlags.GlobalFocus | BufferFlags.StickyFocus | BufferFlags.ControlVolume | BufferFlags.GetCurrentPosition2 | BufferFlags.ControlPositionNotify }; this.CurrentBuffer = new SecondarySoundBuffer(this.DS, bd); if (this.AudioUpdateTrigger == null) this.AudioUpdateTrigger = new AutoResetEvent(false); var chunkSize = this.AudioBufferSize / this.AudioBufferMarkers; var updatePositions = new NotificationPosition[this.AudioBufferMarkers]; for (var i = 0; i < this.AudioBufferMarkers; ++i) { updatePositions[i] = new NotificationPosition() { WaitHandle = this.AudioUpdateTrigger, Offset = chunkSize * i }; } this.CurrentBuffer.SetNotificationPositions(updatePositions); this.CurrentStream = FI.AudioFile.OpenStream(); { var bytes = new byte[this.CurrentBuffer.Capabilities.BufferBytes]; var readbytes = this.CurrentStream.Read(bytes, 0, this.CurrentBuffer.Capabilities.BufferBytes); if (readbytes < this.CurrentBuffer.Capabilities.BufferBytes) Array.Clear(bytes, readbytes, this.CurrentBuffer.Capabilities.BufferBytes - readbytes); DataStream audiodata2; var audiodata1 = this.CurrentBuffer.Lock(0, this.CurrentBuffer.Capabilities.BufferBytes, LockFlags.EntireBuffer, out audiodata2); audiodata1.Write(bytes, 0, this.CurrentBuffer.Capabilities.BufferBytes); this.CurrentBuffer.Unlock(audiodata1, audiodata2); } if (this.CurrentStream.Position < this.CurrentStream.Length) { this.AudioUpdateTrigger.Reset(); this.AudioUpdateThread = new Thread(this.AudioUpdate); this.AudioUpdateThread.Start(); this.btnPause.Enabled = true; this.btnStop.Enabled = true; this.AudioIsLooping = true; } else { this.CurrentStream.Close(); this.CurrentStream = null; this.AudioIsLooping = false; } this.CurrentBuffer.Play(0, (this.AudioIsLooping ? PlayFlags.Looping : PlayFlags.None)); } }
/// <summary> /// Worker thread. /// </summary> /// private void WorkerThread() { // Get the selected capture device DirectSoundCapture captureDevice = new DirectSoundCapture(device); // Set the capture format var bitsPerSample = Signal.GetSampleSize(sampleFormat); WaveFormat format = WaveFormat.CreateCustomFormat(sampleFormat.ToWaveFormat(), sampleRate, 1, sampleRate * bitsPerSample / 8, bitsPerSample / 8, bitsPerSample); // Setup the capture buffer CaptureBufferDescription captureBufferDescription = new CaptureBufferDescription(); captureBufferDescription.Format = format; captureBufferDescription.BufferBytes = 2 * desiredCaptureSize * format.BlockAlign; captureBufferDescription.Flags |= CaptureBufferCapabilitiesFlags.WaveMapped; captureBufferDescription.Flags &= ~CaptureBufferCapabilitiesFlags.ControlEffects; CaptureBuffer captureBuffer = null; NotificationPosition[] notifications = new NotificationPosition[2]; try { captureBuffer = new CaptureBuffer(captureDevice, captureBufferDescription); // Setup the notification positions int bufferPortionSize = captureBuffer.Capabilities.BufferBytes / 2; notifications[0] = new NotificationPosition(); notifications[0].Offset = bufferPortionSize - 1; notifications[0].WaitHandle = new AutoResetEvent(false); notifications[1] = new NotificationPosition(); notifications[1].Offset = bufferPortionSize - 1 + bufferPortionSize; notifications[1].WaitHandle = new AutoResetEvent(false); captureBuffer.SetNotificationPositions(notifications); // Make a copy of the wait handles WaitHandle[] waitHandles = new WaitHandle[notifications.Length]; for (int i = 0; i < notifications.Length; i++) waitHandles[i] = notifications[i].WaitHandle; // Start capturing captureBuffer.Start(true); if (sampleFormat == SampleFormat.Format32BitIeeeFloat) { float[] currentSample = new float[desiredCaptureSize]; while (!stopEvent.WaitOne(0, true)) { int bufferPortionIndex = WaitHandle.WaitAny(waitHandles); captureBuffer.Read(currentSample, 0, currentSample.Length, bufferPortionSize * bufferPortionIndex, LockFlags.None); OnNewFrame(currentSample); } } else if (sampleFormat == SampleFormat.Format16Bit) { short[] currentSample = new short[desiredCaptureSize]; while (!stopEvent.WaitOne(0, true)) { int bufferPortionIndex = WaitHandle.WaitAny(waitHandles); captureBuffer.Read(currentSample, 0, currentSample.Length, bufferPortionSize * bufferPortionIndex, LockFlags.None); OnNewFrame(currentSample); } } } catch (Exception ex) { if (AudioSourceError != null) AudioSourceError(this, new AudioSourceErrorEventArgs(ex.Message)); else throw; } finally { if (captureBuffer != null) { captureBuffer.Stop(); captureBuffer.Dispose(); } if (captureDevice != null) captureDevice.Dispose(); for (int i = 0; i < notifications.Length; i++) if (notifications[i].WaitHandle != null) notifications[i].WaitHandle.Close(); } }