Exemplo n.º 1
0
        private void Record()
        {
            // Create buffer queue
            Queue <GCHandle> gchHeaderQueue = new Queue <GCHandle>();

            // Pin buffers and add them to queue
            int size = Marshal.SizeOf(typeof(MMInterop.WAVEHDR));
            int mmr;

            foreach (GCHandle gchHeader in this.gchHeaders)
            {
                IntPtr pHeader = gchHeader.AddrOfPinnedObject();
                mmr = MMInterop.waveInAddBuffer(this.hWaveIn, pHeader, (uint)size);
                if (mmr != 0)
                {
                    throw new SoundException("waveInStart", mmr);
                }
                gchHeaderQueue.Enqueue(gchHeader);
            }
            // Start recording
            mmr = MMInterop.waveInStart(this.hWaveIn);
            if (mmr != 0)
            {
                throw new SoundException("waveInStart", mmr);
            }

            // Recording loop
            while (this.state != RecordingState.Opened)
            {
                // Wait a buffer become full
                this.recordingSemaphore.WaitOne();

                // Get the buffer from buffer queue
                GCHandle          gchHeader = gchHeaderQueue.Dequeue();
                MMInterop.WAVEHDR header    = (MMInterop.WAVEHDR)gchHeader.Target;

                // Copy data from the buffer to the output queue
                int bytesRecorded = (int)header.dwBytesRecorded;
                if (bytesRecorded > 0)
                {
                    byte[] data = new byte[bytesRecorded];
                    Marshal.Copy(header.lpData, data, 0, bytesRecorded);
                    lock (syncRoot) {
                        if (output.Count == bufferCount) // Is output queue full?
                        // Drop an item
                        {
                            byte[] outputData = output.Dequeue();
                            this.nBytesLost += outputData.Length;
                        }
                        // Add data to output queue
                        output.Enqueue(data);
                    }
                }
                if (this.state == RecordingState.Stopping)
                {
                    if (gchHeaderQueue.Count == 0) // All the buffers are done
                    {
                        break;                     // No more recording
                    }
                }
                else if (this.state == RecordingState.Recording) // Recording is not stopped
                {
                    lock (syncRoot) {
                        // Make sure recording is not stopped
                        if (this.state == RecordingState.Recording)
                        {
                            IntPtr pHeader = gchHeader.AddrOfPinnedObject();
                            mmr = MMInterop.waveInAddBuffer(this.hWaveIn, pHeader, (uint)size);
                            if (mmr != 0)
                            {
                                throw new SoundException("waveInAddBuffer", mmr);
                            }
                            gchHeaderQueue.Enqueue(gchHeader);
                        }
                    }
                }
            }
            // Stop recording
            mmr = MMInterop.waveInStop(this.hWaveIn);
        }