예제 #1
0
        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();
        }
예제 #2
0
 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();
            }
        }