Ejemplo n.º 1
0
        public void ReadPackets()
        {
            int packetSize = audioCapClient.GetNextPacketSize();

            while (packetSize != 0)
            {
                int framesAvailable;
                AudioClientBufferFlags flags;
                IntPtr srcBuffer    = audioCapClient.GetBuffer(out framesAvailable, out flags);
                int    totalSamples = framesAvailable * channelCount;

                if (captureBuffer == null || captureBuffer.Length < totalSamples)
                {
                    captureBuffer = new float[totalSamples];
                }

                Marshal.Copy(srcBuffer, captureBuffer, 0, totalSamples);

                audioCapClient.ReleaseBuffer(framesAvailable);

                for (int c = 0; c < channelCount; ++c)
                {
                    for (int i = 0; i < framesAvailable; ++i)
                    {
                        channels[c].Push(captureBuffer[c + channelCount * i]);
                    }
                }

                packetSize = audioCapClient.GetNextPacketSize();
            }
        }
Ejemplo n.º 2
0
        private void ReadNextPacket(AudioCaptureClient capture)
        {
            IntPtr buffer;
            int    framesAvailable;
            AudioClientBufferFlags flags;
            int packetSize         = capture.GetNextPacketSize();
            int recordBufferOffset = 0;

            //Debug.WriteLine(string.Format("packet size: {0} samples", packetSize / 4));

            while (packetSize != 0)
            {
                buffer = capture.GetBuffer(out framesAvailable, out flags);

                int bytesAvailable = framesAvailable * bytesPerFrame;

                // apparently it is sometimes possible to read more frames than we were expecting?
                // fix suggested by Michael Feld:
                int spaceRemaining = Math.Max(0, recordBuffer.Length - recordBufferOffset);
                if (spaceRemaining < bytesAvailable && recordBufferOffset > 0)
                {
                    if (DataAvailable != null)
                    {
                        DataAvailable(this, new WaveInEventArgs(recordBuffer, recordBufferOffset));
                    }
                    recordBufferOffset = 0;
                }

                // if not silence...
                if ((flags & AudioClientBufferFlags.Silent) != AudioClientBufferFlags.Silent)
                {
                    Marshal.Copy(buffer, recordBuffer, recordBufferOffset, bytesAvailable);
                }
                else
                {
                    Array.Clear(recordBuffer, recordBufferOffset, bytesAvailable);
                }
                recordBufferOffset += bytesAvailable;
                capture.ReleaseBuffer(framesAvailable);
                packetSize = capture.GetNextPacketSize();
            }
            if (DataAvailable != null)
            {
                DataAvailable(this, new WaveInEventArgs(recordBuffer, recordBufferOffset));
            }
        }
Ejemplo n.º 3
0
        private void ReadData(byte[] buffer, AudioCaptureClient captureClient, uint frameSize)
        {
            int nextPacketSize = captureClient.GetNextPacketSize();
            int read           = 0;
            int offset         = 0;

            while (nextPacketSize != 0)
            {
                int framesAvailable;
                AudioClientBufferFlags flags;

                IntPtr nativeBuffer = captureClient.GetBuffer(out framesAvailable, out flags);

                int bytesAvailable = (int)(framesAvailable * frameSize);
                int bytesToCopy    = Math.Min(bytesAvailable, buffer.Length);

                if (Math.Max(buffer.Length - read, 0) < bytesAvailable && read > 0)
                {
                    RaiseDataAvailable(buffer, 0, read);
                    read = offset = 0;
                }

                if ((flags & AudioClientBufferFlags.Silent) == AudioClientBufferFlags.Silent)
                {
                    Array.Clear(buffer, offset, bytesToCopy);
                }
                else
                {
                    Marshal.Copy(nativeBuffer, buffer, offset, bytesToCopy);
                }

                read   += bytesToCopy;
                offset += bytesToCopy;

                captureClient.ReleaseBuffer(framesAvailable);
                nextPacketSize = captureClient.GetNextPacketSize();
            }

            RaiseDataAvailable(buffer, 0, read);
        }
Ejemplo n.º 4
0
        private void DoRecording(AudioClient client)
        {
            Debug.WriteLine(client.BufferSize);

            var buf = new Byte[client.BufferSize * bytesPerFrame];

            int bufLength     = 0;
            int minPacketSize = waveFormat.AverageBytesPerSecond / 100; //100ms

            IntPtr hEvent = NativeMethods.CreateEventEx(IntPtr.Zero, IntPtr.Zero, 0, EventAccess.EVENT_ALL_ACCESS);

            client.SetEventHandle(hEvent);

            try
            {
                AudioCaptureClient capture = client.AudioCaptureClient;
                client.Start();

                int packetSize = capture.GetNextPacketSize();

                while (!this.stop)
                {
                    IntPtr pData                   = IntPtr.Zero;
                    int    numFramesToRead         = 0;
                    AudioClientBufferFlags dwFlags = 0;

                    if (packetSize == 0)
                    {
                        if (NativeMethods.WaitForSingleObjectEx(hEvent, 100, true) != 0)
                        {
                            throw new Exception("Capture event timeout");
                        }
                    }

                    pData = capture.GetBuffer(out numFramesToRead, out dwFlags);

                    if ((int)(dwFlags & AudioClientBufferFlags.Silent) > 0)
                    {
                        pData = IntPtr.Zero;
                    }

                    if (numFramesToRead == 0)
                    {
                        continue;
                    }

                    int capturedBytes = numFramesToRead * bytesPerFrame;

                    System.Runtime.InteropServices.Marshal.Copy(pData, buf, bufLength, capturedBytes);
                    bufLength += capturedBytes;

                    capture.ReleaseBuffer(numFramesToRead);

                    if (bufLength >= minPacketSize)
                    {
                        if (DataAvailable != null)
                        {
                            DataAvailable(this, new WaveInEventArgs(buf, bufLength));
                        }
                        bufLength = 0;
                    }

                    packetSize = capture.GetNextPacketSize();
                }
            }
            catch (Exception ex)
            {
                RaiseRecordingStopped(ex);
                Debug.WriteLine("stop wasapi");
            }
            finally
            {
                RaiseRecordingStopped(null);

                NativeMethods.CloseHandle(hEvent);
                client.Stop();
                client.Dispose();
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// This is the loop that does all of the hard work, each packet is recorded here and then dispatched.
        /// </summary>
        /// <param name="client"></param>
        private void DoRecording(AudioClient2 audioClient)
        {
            this.EventWriterDLL.WriteLine(EventWriterDLL.SeverityTypes.Information, 0x01,
                                          "WasapiCapture::DoRecording => has a buffer size of " + audioClient.BufferSize);

            int sampleBufferByteSize = audioClient.BufferSize * bytesPerFrame;

            byte[] sampleBuffer = new byte[sampleBufferByteSize];

            IntPtr audioSamplesReadyEventHandle = NativeMethods.CreateEventExW(IntPtr.Zero, IntPtr.Zero, 0, EventAccess.EVENT_ALL_ACCESS);

            audioClient.SetEventHandle(audioSamplesReadyEventHandle);

            try
            {
                AudioCaptureClient captureClient = audioClient.AudioCaptureClient;
                audioClient.Start();


                while (!this.pendingStopRequest)
                {
                    NativeMethods.WaitForSingleObjectEx(audioSamplesReadyEventHandle, 1000, true);
                    int packetSize = captureClient.GetNextPacketSize();

                    if (packetSize > 0)
                    {
                        int numFramesToRead            = 0;
                        int numBytesInSampleBuffer     = 0;
                        AudioClientBufferFlags dwFlags = 0;
                        IntPtr micDataIn;

                        micDataIn = captureClient.GetBuffer(out numFramesToRead, out dwFlags);

                        int capturedBytes = numFramesToRead * bytesPerFrame;

                        if ((int)(dwFlags & AudioClientBufferFlags.Silent) > 0)
                        {
                            int maxBytes = Math.Min(capturedBytes, sampleBufferByteSize);
                            while (maxBytes-- > 0)
                            {
                                sampleBuffer[numBytesInSampleBuffer++] = 0;
                            }
                        }
                        else
                        {
                            System.Runtime.InteropServices.Marshal.Copy(micDataIn, sampleBuffer, 0, capturedBytes);
                            numBytesInSampleBuffer = capturedBytes;
                        }

                        captureClient.ReleaseBuffer(numFramesToRead);

                        if (DataAvailableEventHandler != null)
                        {
                            if (this.waveFormat.Channels == 2)
                            {
                                // convert stereo to mono inline!
                                ConvertStereoToMono(sampleBuffer, numBytesInSampleBuffer);
                                numBytesInSampleBuffer /= 2;
                            }
                            else if (this.waveFormat.Channels == 6)
                            {
                                // convert 6 to mono inline!
                                Convert6ToMono(sampleBuffer, numBytesInSampleBuffer, Channel2 | Channel3, 2);
                                numBytesInSampleBuffer /= 6;
                            }

                            DataAvailableEventHandler(this, new WaveInEventArgs(sampleBuffer, numBytesInSampleBuffer));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                this.EventWriterDLL.WriteLine(EventWriterDLL.SeverityTypes.Error, 0x01, "WasapiCapture::DoRecording => Exception: " + ex.ToString());
            }
            finally
            {
                NativeMethods.CloseHandle(audioSamplesReadyEventHandle);
                audioClient.Stop();
                audioClient.Dispose();
                this.pendingStopRequest = false;
            }
        }
Ejemplo n.º 6
0
        private void DoRecording()
        {
            Debug.WriteLine("Recording buffer size: " + audioClient.BufferSize);

            var buf = new Byte[audioClient.BufferSize * bytesPerFrame];

            int bufLength     = 0;
            int minPacketSize = waveFormat.AverageBytesPerSecond / 100; //100ms

            try
            {
                AudioCaptureClient capture = audioClient.AudioCaptureClient;
                audioClient.Start();

                int packetSize = capture.GetNextPacketSize();

                while (captureState == WasapiCaptureState.Recording)
                {
                    IntPtr pData                   = IntPtr.Zero;
                    int    numFramesToRead         = 0;
                    AudioClientBufferFlags dwFlags = 0;

                    if (packetSize == 0)
                    {
                        if (NativeMethods.WaitForSingleObjectEx(hEvent, 100, true) != 0)
                        {
                            throw new Exception("Capture event timeout");
                        }
                    }

                    pData = capture.GetBuffer(out numFramesToRead, out dwFlags);

                    if ((int)(dwFlags & AudioClientBufferFlags.Silent) > 0)
                    {
                        pData = IntPtr.Zero;
                    }

                    if (numFramesToRead == 0)
                    {
                        continue;
                    }

                    int capturedBytes = numFramesToRead * bytesPerFrame;

                    if (pData == IntPtr.Zero)
                    {
                        Array.Clear(buf, bufLength, capturedBytes);
                    }
                    else
                    {
                        Marshal.Copy(pData, buf, bufLength, capturedBytes);
                    }

                    bufLength += capturedBytes;

                    capture.ReleaseBuffer(numFramesToRead);

                    if (bufLength >= minPacketSize)
                    {
                        if (DataAvailable != null)
                        {
                            DataAvailable(this, new WaveInEventArgs(buf, bufLength));
                        }
                        bufLength = 0;
                    }

                    packetSize = capture.GetNextPacketSize();
                }
            }
            catch (Exception ex)
            {
                RaiseRecordingStopped(ex);
                Debug.WriteLine("stop wasapi");
            }
            finally
            {
                RaiseRecordingStopped(null);

                audioClient.Stop();
            }
            Debug.WriteLine("stop wasapi");
        }