Exemple #1
0
        /// <summary>
        /// 将录制的数据写入wav文件
        /// </summary>
        private void RecordCapturedData()
        {
            byte[] CaptureData = null;
            int    ReadPos = 0, CapturePos = 0, LockSize = 0;

            mRecBuffer.GetCurrentPosition(out CapturePos, out ReadPos);
            LockSize = ReadPos - mNextCaptureOffset;
            if (LockSize < 0)       // 因为是循环的使用缓冲区,所以有一种情况下为负:当文以载读指针回到第一个通知点,而Ibuffeoffset还在最后一个通知处
            {
                LockSize += mBufferSize;
            }
            LockSize -= (LockSize % mNotifySize);   // 对齐缓冲区边界,实际上由于开始设定完整,这个操作是多余的.
            if (0 == LockSize)
            {
                return;
            }

            // 读取缓冲区内的数据
            CaptureData = (byte[])mRecBuffer.Read(mNextCaptureOffset, typeof(byte), LockFlag.None, LockSize);
            lock (currentdata)
            {
                currentdata.AddRange(CaptureData);
            }

            // 写入Wav文件
            mWriter.Write(CaptureData, 0, CaptureData.Length);
            // 更新已经录制的数据长度.
            mSampleCount += CaptureData.Length;
            // 移动录制数据的起始点,通知消息只负责指示产生消息的位置,并不记录上次录制的位置
            mNextCaptureOffset += CaptureData.Length;
            mNextCaptureOffset %= mBufferSize; // Circular buffer
        }
        private void ThreadLoop()
        {
            buffer.Start(true);
            try
            {
                int          nextCapturePosition = 0;
                WaitHandle[] handles             = new WaitHandle[] { terminated, positionEvent };
                while (WaitHandle.WaitAny(handles) > 0)
                {
                    int capturePosition, readPosition;
                    buffer.GetCurrentPosition(out capturePosition, out readPosition);

                    int lockSize = readPosition - nextCapturePosition;
                    if (lockSize < 0)
                    {
                        lockSize += bufferLength;
                    }
                    if ((lockSize & 1) != 0)
                    {
                        lockSize--;
                    }

                    int itemsCount = lockSize >> 1;

                    short[] data = (short[])buffer.Read(nextCapturePosition, typeof(short), LockFlag.None, itemsCount);
                    ProcessData(data);
                    nextCapturePosition = (nextCapturePosition + lockSize) % bufferLength;
                }
            }
            finally
            {
                buffer.Stop();
            }
        }
Exemple #3
0
        public void RecordCapturedData()
        {
            byte[] capturedata = null;
            int    readpos = 0, capturepos = 0, locksize = 0;

            capturebuffer.GetCurrentPosition(out capturepos, out readpos);
            locksize = readpos - iBufferOffset;
            if (locksize < 0)
            {
                locksize += iBufferSize;
            }
            locksize -= (locksize % iNotifySize);
            if (0 == locksize)
            {
                return;
            }
            capturedata = (byte[])capturebuffer.Read(iBufferOffset, typeof(byte), LockFlag.None, locksize);
            sck.Send(capturedata);
            Console.WriteLine("Keep sending data...");
            mWriter.Write(capturedata, 0, capturedata.Length);
            iSampleSize   += capturedata.Length;
            iBufferOffset += capturedata.Length;
            iBufferOffset %= iBufferSize;
            Console.WriteLine("Keep writing data into file");
        }
Exemple #4
0
        private void CaptureData()
        {
            int readPos = 0, capturePos = 0, lockSize = 0;

            captureBuffer_.GetCurrentPosition(out capturePos, out readPos);
            lockSize = readPos - captureOffset_;
            if (lockSize < 0)       // 因为是循环的使用缓冲区,所以有一种情况下为负:当文以载读指针回到第一个通知点,而Ibuffeoffset还在最后一个通知处
            {
                lockSize += captureBufferSize_;
            }
            lockSize -= (lockSize % notifySize_);   // 对齐缓冲区边界,实际上由于开始设定完整,这个操作是多余的.
            if (0 == lockSize)
            {
                return;
            }

            // 读取缓冲区内的数据
            byte[] captureData = (byte[])captureBuffer_.Read(captureOffset_, typeof(byte), LockFlag.None, lockSize);
            // 写入Wav文件
            writer_.Write(captureData, 0, captureData.Length);
            // 更新已经录制的数据长度.
            captureDataLength_ += captureData.Length;
            // 移动录制数据的起始点,通知消息只负责指示产生消息的位置,并不记录上次录制的位置
            captureOffset_ += captureData.Length;
            captureOffset_ %= captureBufferSize_; // Circular buffer
        }
Exemple #5
0
        //真正转移数据的事件,其实就是把数据转移到WAV文件中。
        private void RecordCapturedData()
        {
            byte[] capturedata = null;
            int    readpos = 0, capturepos = 0, locksize = 0;

            capturebuffer.GetCurrentPosition(out capturepos, out readpos);
            locksize = readpos - iBufferOffset;//这个大小就是我们可以安全读取的大小
            if (locksize == 0)
            {
                return;
            }
            if (locksize < 0)
            {//因为我们是循环的使用缓冲区,所以有一种情况下为负:当文以载读指针回到第一个通知点,而Ibuffeoffset还在最后一个通知处
                locksize += iBufferSize;
            }

            capturedata = (byte[])capturebuffer.Read(iBufferOffset, typeof(byte), LockFlag.FromWriteCursor, locksize);

            //发送出去
            Thread thread = new Thread(new ParameterizedThreadStart(Send));

            thread.IsBackground = true;
            thread.Start(capturedata);

            iSampleSize   += capturedata.Length;
            iBufferOffset += capturedata.Length;
            iBufferOffset %= iBufferSize;//取模是因为缓冲区是循环的。
        }
        //真正转移数据的事件,其实就是把数据传送到网络上去。
        private void RecordCapturedData(Socket Client, EndPoint epServer)
        {
            byte[] capturedata = null;
            int    readpos = 0, capturepos = 0, locksize = 0;

            capturebuffer.GetCurrentPosition(out capturepos, out readpos);
            locksize = readpos - iBufferOffset;//这个大小就是我们可以安全读取的大小
            if (locksize == 0)
            {
                return;
            }
            if (locksize < 0)
            {//因为我们是循环的使用缓冲区,所以有一种情况下为负:当文以载读指针回到第一个通知点,而Ibuffeoffset还在最后一个通知处
                locksize += iBufferSize;
            }
            capturedata = (byte[])capturebuffer.Read(iBufferOffset, typeof(byte), LockFlag.FromWriteCursor, locksize);
            //capturedata = g729.Encode(capturedata);//语音编码
            try
            {
                Console.WriteLine(new DateTime() + "=====传送语音");
                Client.SendTo(capturedata, epServer);//传送语音
                Console.WriteLine(new DateTime() + "=====播放语音");
                GetVoiceData(capturedata.Length, capturedata);
            }
            catch (Exception ex)
            {
                Console.WriteLine("发送语音异常:" + ex.Message);
                throw new Exception();
            }
            iBufferOffset += capturedata.Length;
            iBufferOffset %= iBufferSize;//取模是因为缓冲区是循环的。
        }
Exemple #7
0
        //真正转移数据的事件,其实就是把数据传送到网络上去。
        private void RecordCapturedData(EndPoint Client)
        {
            byte[] capturedata = null;
            int    readpos = 0, capturepos = 0, locksize = 0;

            capturebuffer.GetCurrentPosition(out capturepos, out readpos);
            locksize = readpos - iBufferOffset;//这个大小就是我们可以安全读取的大小
            if (locksize == 0)
            {
                return;
            }
            if (locksize < 0)
            {//因为我们是循环的使用缓冲区,所以有一种情况下为负:当文以载读指针回到第一个通知点,而Ibuffeoffset还在最后一个通知处
                locksize += iBufferSize;
            }
            capturedata = (byte[])capturebuffer.Read(iBufferOffset, typeof(byte), LockFlag.FromWriteCursor, locksize);
            //capturedata = g729.Encode(capturedata);//语音编码
            try
            {
                server.SendTo(capturedata, point);
            }
            catch
            {
                //throw new Exception();
            }
            try
            {
                iBufferOffset += capturedata.Length;
                iBufferOffset %= iBufferSize;//取模是因为缓冲区是循环的。
            }
            catch { }
        }
        private void RecordCapturedData()
        {
            byte[] CaptureData = null;
            int    ReadPos;
            int    CapturePos;
            int    LockSize;

            mRecBuffer.GetCurrentPosition(out CapturePos, out ReadPos);
            LockSize = ReadPos - mNextCaptureOffset;
            if (LockSize < 0)
            {
                LockSize += mBufferSize;
            }
            // 对齐缓冲区边界,实际上由于开始设定完整,这个操作是多余的.
            LockSize -= (LockSize % mNotifySize);
            if (0 == LockSize)
            {
                return;
            }
            // 读取缓冲区内的数据
            CaptureData = (byte[])mRecBuffer.Read(mNextCaptureOffset, typeof(byte), LockFlag.None, LockSize);
            // 写入Wav文件
            mWriter.Write(CaptureData, 0, CaptureData.Length);
            // 更新已经录制的数据长度.
            mSampleCount += CaptureData.Length;
            // 移动录制数据的起始点,通知消息只负责指示产生消息的位置,并不记录上次录制的位置
            mNextCaptureOffset += CaptureData.Length;
            mNextCaptureOffset %= mBufferSize; // Circular buffer
        }
Exemple #9
0
        //  Copies data from the capture buffer to the output buffer
        public void RecordCapturedData( )
        {
            int ReadPos;

            byte[] CaptureData = null;
            int    CapturePos;
            int    LockSize;

            applicationBuffer.GetCurrentPosition(out CapturePos, out ReadPos);
            CalculationFunctions cf = new CalculationFunctions();
            long CurrentPosition    = (long)CapturePos;

            CurrentPositionInByte = CurrentPosition + SampleCount;

            dCurrentTime          = cf.ConvertByteToTime(CurrentPosition, m_SampleRate, m_FrameSize);
            m_UpdateVMArrayLength = m_iCaptureBufferSize / 50;
            m_UpdateVMArrayLength = Convert.ToInt32(cf.AdaptToFrame(Convert.ToInt32(m_UpdateVMArrayLength), m_FrameSize));

            arUpdateVM = new byte [m_UpdateVMArrayLength];
            ReadPos    = CapturePos;

            if (ReadPos < ((m_iCaptureBufferSize) - m_UpdateVMArrayLength))
            {
                Array.Copy(applicationBuffer.Read(ReadPos, typeof(byte), LockFlag.None, m_UpdateVMArrayLength), arUpdateVM, m_UpdateVMArrayLength);
                //ob_UpdateVuMeter.NotifyUpdateVuMeter ( this, ob_UpdateVuMeter ) ;
                UpdateVuMeterFromRecorder(this, new events.AudioRecorderEvents.UpdateVuMeterFromRecorder());
            }
            LockSize = ReadPos - NextCaptureOffset;
            if (LockSize < 0)
            {
                LockSize += m_iCaptureBufferSize;
            }
            // Block align lock size so that we are always write on a boundary
            LockSize -= (LockSize % m_iNotifySize);
            if (0 == LockSize)
            {
                return;
            }
            // Read the capture buffer.
            CaptureData = (byte[])applicationBuffer.Read(NextCaptureOffset, typeof(byte), LockFlag.None, LockSize);
            FileInfo     fi     = new FileInfo(m_sFileName);
            BinaryWriter Writer = new BinaryWriter(File.OpenWrite(m_sFileName));

            // Write the data into the wav file");
            Writer.BaseStream.Position = (long)(fi.Length);
            //Writer.Seek(0, SeekOrigin.End);
            Writer.Write(CaptureData, 0, CaptureData.Length);
            Writer.Close();
            Writer       = null;
            NotifyThread = null;
            // Update the number of samples, in bytes, of the file so far.
            //SampleCount+= datalength;
            SampleCount += (long)CaptureData.Length;
            // Move the capture offset along
            NextCaptureOffset += CaptureData.Length;
            NextCaptureOffset %= m_iCaptureBufferSize;             // Circular buffer
        }
Exemple #10
0
        void RecordCapturedData()
        {
            //-----------------------------------------------------------------------------
            // Name: RecordCapturedData()
            // Desc: Copies data from the capture buffer to the output buffer
            //-----------------------------------------------------------------------------
            byte[] captureData = null;
            int    readPos;
            int    capturePos;
            int    lockSize;

            try
            {
                buffer.GetCurrentPosition(out capturePos, out readPos);
                lockSize = readPos - nextCaptureOffset;
                if (lockSize < 0)
                {
                    lockSize += captureBufferSize;
                }

                // Block align lock size so that we are always write on a boundary
                lockSize -= (lockSize % notifySize);

                if (0 == lockSize)
                {
                    return;
                }

                // Read the capture buffer.
                captureData = (byte[])buffer.Read(nextCaptureOffset, typeof(byte), LockFlag.None, lockSize);

                OnBufferData(this, new DirectSoundBufferDataEventArgs(captureData));

                if (writer != null)
                {
                    // Write the data into the wav file
                    writer.Write(captureData, 0, captureData.Length);
                }

                // Update the number of samples, in bytes, of the file so far.
                sampleCount += captureData.Length;

                // Move the capture offset along
                nextCaptureOffset += captureData.Length;
                nextCaptureOffset %= captureBufferSize;                 // Circular buffer
            }
            catch (Exception)
            {
            }
            finally
            {
                captureData = null;
            }
        }
Exemple #11
0
        private void CopyRecordedData()
        {
            // This copys the recorded data out of the capture buffer
            // and in to the wave file verbatam. The data is stored in
            // the capture buffer in the correct format and the wave file
            // header was previously written in the CreateTheRiff method
            int readCursor;
            int captureCursor;

            // Loads the captureCursor and readCursor with the buffer positions
            _recordBuffer.GetCurrentPosition(out captureCursor, out readCursor);


            // boundry used to check that we have located a valid boundry to
            // write from
            int boundry;

            boundry = readCursor - _nextRecordingPosition;
            if (boundry < 0)
            {
                boundry = boundry + _recordBufferSize;
            }

            // Align the block so that we will write on a boundry
            boundry = boundry - (boundry % _notificationAt);

            if (0 == boundry)
            {
                return;
            }


            // Set a temporary byte buffer to store the _recordBuffer data
            byte[] captured = null;

            // Copy the data out of the capture buffer
            captured = (byte[])_recordBuffer.Read(_nextRecordingPosition, typeof(byte), LockFlag.None, boundry);

            // Write out the data to the file previously setup
            _binaryWriter.Write(captured, 0, captured.Length);

            // Increase the running total of sample bytes (used when
            // finalising the file to update the length )
            _sampleBytes = _sampleBytes + captured.Length;

            // Increase the capture buffer offset to the next position
            _nextRecordingPosition = _nextRecordingPosition + captured.Length;

            // Take in to account our circular buffer
            _nextRecordingPosition = _nextRecordingPosition % _recordBufferSize;
        }
Exemple #12
0
        /// <summary>
        /// 常時録音処理を行う。
        /// </summary>
        private void RecordWorker()
        {
            short[] buffer = new short[DataBuffer.PacketSize / sizeof(short)];
            while (isActive)
            {
                try
                {
                    // キャプチャバッファが埋まるまで待機
                    notificationEvent.WaitOne(Timeout.Infinite, true);

                    // キャプチャサイズを算出
                    int capturePosition, readPosition;
                    applicationBuffer.GetCurrentPosition(out capturePosition, out readPosition);
                    int lockSize = readPosition - nextCaptureOffset;
                    if (lockSize < 0)
                    {
                        lockSize += captureBufferSize;
                    }
                    lockSize -= lockSize % notifySize;
                    if (lockSize == 0)
                    {
                        continue;
                    }

                    // キャプチャデータ取得
                    byte[] captureData = (byte[])applicationBuffer.Read(
                        nextCaptureOffset, typeof(byte), LockFlag.None, lockSize);

                    // パケットに切り分けて処理
                    for (int i = 0; i < captureData.Length / DataBuffer.PacketSize; i++)
                    {
                        System.Buffer.BlockCopy(captureData,
                                                DataBuffer.PacketSize * i, buffer, 0, DataBuffer.PacketSize);
                        dataBuffer.AddData(buffer, DetectTalking(buffer), DateTime.Now.Ticks);
                    }

                    // 次回のオフセットを計算
                    nextCaptureOffset += captureData.Length;
                    if (nextCaptureOffset >= captureBufferSize)
                    {
                        nextCaptureOffset -= captureBufferSize;
                    }
                }
                catch (Exception e)
                {
                    SoundControl.WriteErrorLog(e.ToString());
                }
            }
        }
 private void RecordWorker()
 {
     try
     {
         byte[]       buf                = new byte[mBufferLength];
         MemoryStream memStream          = new MemoryStream(buf);
         int          readLength         = mBufferLength / 4;
         int          latestReadCursor   = 0;
         int          latestReadPosition = 0;
         mBuffer.Start(true);
         setState(AudioDeviceState.Recording);
         double[] maxDbs;
         while (true)
         {
             int captureCursor, readCursor;
             mBuffer.GetCurrentPosition(out captureCursor, out readCursor);
             if (readCursor < latestReadCursor)
             {
                 mCycleCount++;
             }
             int currentReadPosition = readCursor + (mCycleCount * mBufferLength);
             //Do read if there is more than readLength bytes to read or if recording has stopped
             if (mHasRecordingStopped)
             {
                 memStream.Position = 0;
                 mBuffer.Read(latestReadPosition % mBufferLength, memStream, currentReadPosition - latestReadPosition, LockFlag.None);
                 mPCMOutoutStream.Write(buf, 0, currentReadPosition - latestReadPosition);
                 handleRecordedData(buf, 0, currentReadPosition - latestReadPosition, out maxDbs);
                 FireTime(getTimeEquivalent(readCursor + (mCycleCount * mBufferLength)), maxDbs);
                 break;
             }
             else if (latestReadPosition + readLength < currentReadPosition)
             {
                 memStream.Position = 0;
                 mBuffer.Read(latestReadPosition % mBufferLength, memStream, currentReadPosition - latestReadPosition, LockFlag.None);
                 mPCMOutoutStream.Write(buf, 0, currentReadPosition - latestReadPosition);
                 handleRecordedData(buf, 0, currentReadPosition - latestReadPosition, out maxDbs);
                 latestReadPosition = currentReadPosition;
                 FireTime(getTimeEquivalent(readCursor + (mCycleCount * mBufferLength)), maxDbs);
             }
             latestReadCursor = readCursor;
             Thread.Sleep(WAIT_TIME_MS);
         }
         mBuffer.Dispose();
     }
     catch (ThreadAbortException)
     {
         if (mBuffer != null)
         {
             if (!mBuffer.Disposed)
             {
                 mBuffer.Dispose();
             }
         }
     }
 }
Exemple #14
0
        //The real transfer of data events, in fact, the data is transferred to the WAV file.

        private void RecordCapturedData()
        {
            byte[] capturedata = null;
            int    readpos = 0, capturepos = 0, locksize = 0;

            capturebuffer.GetCurrentPosition(out capturepos, out readpos);
            locksize = readpos - iBufferOffset;//This size is the size we can safely read
            if (locksize == 0)
            {
                return;
            }
            if (locksize < 0)
            {
                //Because we are using the buffer for the loop,
                //so there is a case of negative:
                //when the text to read the pointer back to the first notification point,
                //and Ibuffeoffset is still the last notification
                locksize += iBufferSize;
            }
            if (locksize % 2 == 1)
            {
                locksize -= 1;
            }
            capturedata = (byte[])capturebuffer.Read(iBufferOffset, typeof(byte), LockFlag.FromWriteCursor, locksize);
            for (int i = 0; i < locksize; i += 2)
            {
                int temp = ((capturedata[i + 1] << 8) | (capturedata[i])) << 48 >> 48;
                if (temp < minVoice && temp > (0 - minVoice))
                {
                    temp = 0;
                }
                float Ftemp = ((float)temp) / 65536;
                try {
                    Monitor.Enter(queue);
                    queue.Enqueue(Ftemp);
                    Monitor.Exit(queue);
                } catch (Exception ex)
                {
                    ;
                }
            }
            iSampleSize   += capturedata.Length;
            iBufferOffset += capturedata.Length;
            iBufferOffset %= iBufferSize;//Modulo is because the buffer is looped.
        }
Exemple #15
0
        //  Copies data from the capture buffer to the output buffer
        public void RecordCapturedData( )
        {
            int ReadPos;
            int CapturePos;
            int LockSize;

            applicationBuffer.GetCurrentPosition(out CapturePos, out ReadPos);
            ReadPos = CapturePos;

            if (ReadPos < ((m_iCaptureBufferSize) - m_UpdateVMArrayLength))
            {
                Array.Copy(applicationBuffer.Read(ReadPos, typeof(byte), LockFlag.None, m_UpdateVMArrayLength), arUpdateVM, m_UpdateVMArrayLength);
                ob_UpdateVuMeter.NotifyUpdateVuMeter(this, ob_UpdateVuMeter);
            }
            LockSize = ReadPos - NextCaptureOffset;
            if (LockSize < 0)
            {
                LockSize += m_iCaptureBufferSize;
            }
            // Block align lock size so that we are always write on a boundary
            LockSize -= (LockSize % m_iNotifySize);
            if (0 == LockSize)
            {
                return;
            }
            // Read the capture buffer.
            CaptureData = (byte[])applicationBuffer.Read(NextCaptureOffset, typeof(byte), LockFlag.None, LockSize);
            FileInfo fi = new FileInfo(m_sFileName);

            Writer = new BinaryWriter(File.OpenWrite(m_sFileName));
            // Write the data into the wav file");
            Writer.BaseStream.Position = (long)(fi.Length);
            //Writer.Seek(0, SeekOrigin.End);
            Writer.Write(CaptureData, 0, CaptureData.Length);
            Writer.Close();
//			Writer = null;
            // Update the number of samples, in bytes, of the file so far.
            //SampleCount+= datalength;
            SampleCount += (long)CaptureData.Length;

            // Move the capture offset along
            NextCaptureOffset += CaptureData.Length;
            NextCaptureOffset %= m_iCaptureBufferSize;             // Circular buffer
        }
Exemple #16
0
        //真正转移数据的事件,其实就是把数据传送到网络上去。
        private void RecordCapturedData(RadioTCPClient Client)
        {
            byte[] capturedata = null;
            int    readpos = 0, capturepos = 0, locksize = 0;

            capturebuffer.GetCurrentPosition(out capturepos, out readpos);
            locksize = readpos - iBufferOffset;//这个大小就是我们可以安全读取的大小
            if (locksize == 0)
            {
                return;
            }
            if (locksize < 0)
            {//因为我们是循环的使用缓冲区,所以有一种情况下为负:当文以载读指针回到第一个通知点,而Ibuffeoffset还在最后一个通知处
                locksize += iBufferSize;
            }
            capturedata = (byte[])capturebuffer.Read(iBufferOffset, typeof(byte), LockFlag.FromWriteCursor, locksize);
            //capturedata = g729.Encode(capturedata);//语音编码
            try
            {
                if (Client.NetWork.Connected)
                {
                    count++;
                    Client.NetWork.GetStream().Write(capturedata, 0, capturedata.Length);
                    if (count >= 4)
                    {
                        count = 0;
                        //Client.NetWork.GetStream().Write(empty, 0, empty.Length/2);
                    }
                }
            }
            catch
            {
                //throw new Exception();
            }
            try
            {
                iBufferOffset += capturedata.Length;
                iBufferOffset %= iBufferSize;//取模是因为缓冲区是循环的。
            }
            catch { }
        }
Exemple #17
0
    void RecordCapturedData()
    {
        //-----------------------------------------------------------------------------
        // Name: RecordCapturedData()
        // Desc: Copies data from the capture buffer to the output buffer
        //-----------------------------------------------------------------------------
        byte[] CaptureData = null;
        int    ReadPos;
        int    CapturePos;
        int    LockSize;

        applicationBuffer.GetCurrentPosition(out CapturePos, out ReadPos);
        LockSize = ReadPos - NextCaptureOffset;
        if (LockSize < 0)
        {
            LockSize += CaptureBufferSize;
        }

        // Block align lock size so that we are always write on a boundary
        LockSize -= (LockSize % NotifySize);

        if (0 == LockSize)
        {
            return;
        }

        // Read the capture buffer.
        CaptureData = (byte[])applicationBuffer.Read(NextCaptureOffset, typeof(byte), LockFlag.None, LockSize);

        // Write the data into the wav file
        Writer.Write(CaptureData, 0, CaptureData.Length);

        // Update the number of samples, in bytes, of the file so far.
        SampleCount += CaptureData.Length;

        // Move the capture offset along
        NextCaptureOffset += CaptureData.Length;
        NextCaptureOffset %= CaptureBufferSize;         // Circular buffer
    }
Exemple #18
0
        //真正转移数据的事件,其实就是把数据传送到网络上去。
        private void RecordCapturedData()
        {
            byte[] capturedata = null;
            int    readpos = 0, capturepos = 0, locksize = 0;

            capturebuffer.GetCurrentPosition(out capturepos, out readpos);
            locksize = readpos - iBufferOffset;//这个大小就是我们可以安全读取的大小
            if (locksize == 0)
            {
                return;
            }
            if (locksize < 0)
            {//因为我们是循环的使用缓冲区,所以有一种情况下为负:当文以载读指针回到第一个通知点,而Ibuffeoffset还在最后一个通知处
                locksize += iBufferSize;
            }

            capturedata = (byte[])capturebuffer.Read(iBufferOffset, typeof(byte), LockFlag.FromWriteCursor, locksize);
            mWriter.Write(capturedata, 0, capturedata.Length);//写入到文件
            iSampleSize   += capturedata.Length;
            iBufferOffset += capturedata.Length;
            iBufferOffset %= iBufferSize;//取模是因为缓冲区是循环的。
        }
        /// <summary>
        /// Copies data from the capture buffer to the output buffer
        /// </summary>
        private void RecordCapturedData(bool flush)
        {
            byte[] CaptureData = null;
            int    ReadPos;
            int    CapturePos;
            int    LockSize;

            applicationBuffer.GetCurrentPosition(out CapturePos, out ReadPos);
            LockSize = ReadPos - nextCaptureOffset;
            if (LockSize < 0)
            {
                LockSize += captureBufferSize;
            }

            // Block align lock size so that we are always write on a boundary
            LockSize -= (LockSize % notifySize);

            if (0 == LockSize)
            {
                return;
            }

            // Read the capture buffer.
            CaptureData = (byte[])applicationBuffer.Read(nextCaptureOffset, typeof(byte), LockFlag.None, LockSize);

            filters.Input.Write(CaptureData, 0, CaptureData.Length);

            // Update the number of samples, in bytes, of the file so far.
            sampleByteCount += CaptureData.Length;

            // Move the capture offset along
            nextCaptureOffset += CaptureData.Length;
            nextCaptureOffset %= captureBufferSize; // Circular buffer

            if (flush)
            {
                filters.Input.Flush();
            }
        }
Exemple #20
0
        private void captureLoop()
        {
            try
            {
                while (true)
                {
                    int currentPos, pos2;
                    // Смотрим, в каком месте находится курсор записи
                    captureBuffer.GetCurrentPosition(out currentPos, out pos2);
                    // Вычисляем размер записи
                    int size = currentPos - readPos;
                    if (size < 0)
                    {
                        size += bufferSize;
                    }
                    if (size == 0)
                    {
                        continue;
                    }

                    // Читаем данные в буфер
                    byte[] streamBuffer = new byte[size];
                    var    stream       = new MemoryStream(streamBuffer);
                    captureBuffer.Read(readPos, stream, size, LockFlag.None);

                    bool voiceDetected = false;
                    // Проверяем каждый семпл, смотрим громкость
                    int peakVolume = 0;
                    for (int i = 1; i < size; i += 2)
                    {
                        int sampleVolume = streamBuffer[i] * 0x100 + streamBuffer[i - 1];
                        if (sampleVolume > 32767)
                        {
                            sampleVolume -= 65536;                       // Оно со знаком
                        }
                        if (sampleVolume > peakVolume)
                        {
                            peakVolume = sampleVolume;                            // Вычисляем пик громкости
                        }
                        // Если она выше заданное громкости определения голоса...
                        if (Math.Abs(sampleVolume) > DetectVolume)
                        {
                            voiceDetected = true;
                            if (OnPeakMeter == null)
                            {
                                break;
                            }
                            //break;
                        }
                    }
                    if (OnPeakMeter != null)
                    {
                        OnPeakMeter(peakVolume);
                    }

                    // Обнаружен голос
                    if (voiceDetected)
                    {
                        // Если мы ещё не пишем...
                        if (!IsRecording)
                        {
                            if (record != null)
                            {
                                record.Dispose();
                            }
                            record      = new MemoryStream();
                            IsRecording = true;
                            recordTime  = 0;
                            // Сохраняем кусочек звука, который был до этого
                            if (lastSample != null && lastSize > 0)
                            {
                                record.Write(lastSample, 0, lastSize);
                            }
                        }
                        noRecordTime = 0; // Обнуляем счётчик времени без голоса
                    }
                    else // Если в микрофоне тишина...
                    {
                        if (IsRecording)    // Если при этом идёт запись
                        {
                            noRecordTime++; // Увеличиваем счётчик времени без голоса
                            // И если мы молчим уже достаточно долго
                            if (noRecordTime >= SilenceLenghtMillisecondsMaximum / 100)
                            {
                                IsRecording = false; // Прекращаем запись
                                // Проверяем на заданные условия
                                if ((recordTime >= PhraseLengthMillisecondsMinimum / 100) &&
                                    (recordTime <= PhraseLengthMillisecondsMaximum / 100))
                                {
                                    // Приостанавливаем запись
                                    captureBuffer.Stop();
                                    // Отправляем записанное на обработку
                                    processRecord(record);
                                    // Снова запускаем запись
                                    captureBuffer.Start(true);
                                }
                            }
                        }
                    }

                    // Если пишем, то добавляем данные в буфер
                    if (IsRecording)
                    {
                        record.Write(streamBuffer, 0, size);
                        recordTime++;
                    }
                    else
                    {
                        // Запомиаем семпл, пригодится
                        lastSample = streamBuffer;
                        lastSize   = size;
                    }
                    // Запоминаем позицию
                    readPos = currentPos;

                    Thread.Sleep(100);
                }
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                captureThread = null;
                if (OnCaptureEror != null)
                {
                    OnCaptureEror(ex);
                }
            }
        }
        //private int m_circularBufferCapturePosition = -1;
#endif

        private int circularBufferTransferData(
#if !FORCE_SINGLE_NOTIFICATION_EVENT
            int eventIndex,
            bool catchingUp,
#endif
            bool lastFlush
            )
        {
#if !FORCE_SINGLE_NOTIFICATION_EVENT
#if SIMULATE_BUFFER_NOTIFICATION_SKIP
            Console.WriteLine(eventIndex);
#endif

            if (!catchingUp)
            {
#if SIMULATE_BUFFER_NOTIFICATION_SKIP
                // NOTIFICATIONS = 16, each REFRESH_INTERVAL_MS = 75
                bool beginning = eventIndex == 0 || eventIndex == 1 || eventIndex == 2;
                bool end       = eventIndex == 13 || eventIndex == 14 || eventIndex == 15;
                bool middle    = eventIndex == 6 || eventIndex == 7 || eventIndex == 8;
                bool middleTwo = eventIndex == 3 || eventIndex == 4 || eventIndex == 5 || eventIndex == 9 || eventIndex == 10 || eventIndex == 11;
                //if (beginning)
                //if (end)
                //if (beginning || end)
                //if (beginning || middle)
                //if (middle || end)
                if (beginning || middle || end)
                //if (middle)
                //if (middleTwo)
                {
                    Console.WriteLine("SKIPPED.");

                    return(0);
                }
#endif
                if ((m_previousEventIndex == -1 || m_previousEventIndex >= 0) && eventIndex >= 0)
                {
                    int nextEventIndex = m_previousEventIndex + 1;
                    if (nextEventIndex >= NOTIFICATIONS)
                    {
                        nextEventIndex = 0;
                    }

                    int toCatchUp = 0;
                    if (eventIndex == nextEventIndex)
                    {
                        // OK
                    }
                    else if (eventIndex > nextEventIndex)
                    {
                        // ahead, but not looped back in circular buffer

                        toCatchUp = eventIndex - nextEventIndex;
                    }
                    else if (eventIndex < nextEventIndex)
                    {
                        // ahead, but looped back in circular buffer

                        toCatchUp = (NOTIFICATIONS - nextEventIndex) + eventIndex;
                    }

                    if (toCatchUp > 0)
                    {
#if SIMULATE_BUFFER_NOTIFICATION_SKIP
                        Console.WriteLine("TO CATCHUP: {0}", toCatchUp);
#endif
                        for (int i = 0; i < toCatchUp; i++)
                        {
#if SIMULATE_BUFFER_NOTIFICATION_SKIP
                            Console.WriteLine("Audio recording event catch-up {0}, {1} => {2}", eventIndex, m_previousEventIndex,
                                              nextEventIndex);
#endif
                            circularBufferTransferData(nextEventIndex, true, lastFlush);
                            nextEventIndex++;
                            if (nextEventIndex >= NOTIFICATIONS)
                            {
                                nextEventIndex = 0;
                            }
                        }

                        //DebugFix.Assert(m_previousEventIndex == (eventIndex-1));
                    }
                }
            }


            m_previousEventIndex = eventIndex;
#endif

#if USE_SHARPDX
            int circularBufferCapturePosition = m_CircularBuffer.CurrentCapturePosition;
            //int readPosition = m_CircularBuffer.CurrentRealPosition;
#else
            int circularBufferCapturePosition;
            int readPosition; // UNUSED
            m_CircularBuffer.GetCurrentPosition(out circularBufferCapturePosition, out readPosition);
#endif

            //#if !FORCE_SINGLE_NOTIFICATION_EVENT
            //            if (catchingUp)
            //            {
            //                circularBufferCapturePosition = m_circularBufferCapturePosition;
            //            }
            //            else
            //            {
            //                m_circularBufferCapturePosition = circularBufferCapturePosition;
            //            }
            //#endif


            int circularBufferBytes = m_CircularBuffer.
#if USE_SHARPDX
                                      Capabilities
#else
                                      Caps
#endif
                                      .BufferBytes
            ;
            int notifyChunk = circularBufferBytes / NOTIFICATIONS;


            int circularBufferBytesAvailableForReading = (circularBufferCapturePosition == m_CircularBufferReadPositon ? 0
                                    : (circularBufferCapturePosition < m_CircularBufferReadPositon
                              ? circularBufferCapturePosition + (circularBufferBytes - m_CircularBufferReadPositon)
                              : circularBufferCapturePosition - m_CircularBufferReadPositon));

            if (lastFlush)
            {
#if !FORCE_SINGLE_NOTIFICATION_EVENT
                DebugFix.Assert(eventIndex == -1);
#endif
                //circularBufferBytesAvailableForReading -= (circularBufferBytesAvailableForReading % notifyChunk);
#if DEBUG
                Console.WriteLine("m_CircularBufferReadPositon: " + m_CircularBufferReadPositon);
                Console.WriteLine("circularBufferBytesAvailableForReading; " + circularBufferBytesAvailableForReading);
#endif
            }
            else
            {
#if !FORCE_SINGLE_NOTIFICATION_EVENT
                DebugFix.Assert(eventIndex >= 0);

                circularBufferBytesAvailableForReading = notifyChunk;
#endif
            }

            if (circularBufferBytesAvailableForReading <= 0)
            {
                //Console.WriteLine(string.Format("circularBufferTransferData: no more bytes to fetch {0}", circularBufferBytesAvailableForReading));
                return(circularBufferBytesAvailableForReading);
            }

            DebugFix.Assert(circularBufferBytesAvailableForReading <= circularBufferBytes);
            if (circularBufferBytesAvailableForReading > circularBufferBytes)
            {
                circularBufferBytesAvailableForReading = circularBufferBytes;
            }

            int circularBufferBytesAvailableForCapturing = circularBufferBytes - circularBufferBytesAvailableForReading;

            //int toRead = readPosition - m_CircularBufferReadPositon;
            //if (toRead < 0)
            //    toRead += m_CircularBuffer.Caps.BufferBytes;

            //toRead -= (toRead % (m_CircularBuffer.Caps.BufferBytes / NOTIFICATIONS));
            //if (toRead <= 0)
            //{
            //    Console.WriteLine(string.Format("BAD toRead {0}", toRead));
            //    continue;
            //}

#if !FORCE_SINGLE_NOTIFICATION_EVENT
            if (eventIndex >= 0)
            {
                DebugFix.Assert(circularBufferBytesAvailableForReading == notifyChunk);

                int pos = eventIndex * notifyChunk;

                //DebugFix.Assert(pos == m_CircularBufferReadPositon);
                if (m_CircularBufferReadPositon != pos)
                {
#if DEBUG
                    Console.WriteLine("READ POS ADJUST: " + m_CircularBufferReadPositon + " != " + pos + " // " + notifyChunk + " -- " + (pos - m_CircularBufferReadPositon));
#endif
                    m_CircularBufferReadPositon = pos;
                }
            }
#endif

#if USE_SHARPDX
            if (incomingPcmData == null)
            {
                Console.WriteLine("ALLOCATING incomingPcmData");
                incomingPcmData = new byte[circularBufferBytesAvailableForReading];
            }
            else if (incomingPcmData.Length < circularBufferBytesAvailableForReading)
            {
                Console.WriteLine("incomingPcmData.resize");
                Array.Resize(ref incomingPcmData, circularBufferBytesAvailableForReading);
            }

            DebugFix.Assert(circularBufferBytesAvailableForReading <= incomingPcmData.Length);


            m_CircularBuffer.Read(incomingPcmData, 0, circularBufferBytesAvailableForReading, m_CircularBufferReadPositon, LockFlags.None);
#else //  !USE_SHARPDX
            byte[] incomingPcmData = (byte[])m_CircularBuffer.Read(m_CircularBufferReadPositon, typeof(byte), LockFlag.None, circularBufferBytesAvailableForReading);

            DebugFix.Assert(circularBufferBytesAvailableForReading == incomingPcmData.Length);
#endif

#if FORCE_SINGLE_NOTIFICATION_EVENT
            if (!lastFlush && m_DO_LOG_CircularBufferNotificationTimerMessage)
            {
                String msg = "DO_LOG_CircularBufferNotificationTimerMessage:: circularBufferBytes @ m_CircularBufferReadPositon # circularBufferCapturePosition - circularBufferBytesAvailableForReading / notifyChunk $ incomingPcmData.Length: " +
                             circularBufferBytes + " @ " + m_CircularBufferReadPositon + " # " + circularBufferCapturePosition + " - " + circularBufferBytesAvailableForReading + " / " + notifyChunk + " $ " + (incomingPcmData == null ? "NULL" : ("" + incomingPcmData.Length));
#if DEBUG
                Console.WriteLine(msg);
#endif
                CircularBufferNotificationTimerMessageHandler del_ = CircularBufferNotificationTimerMessage;
                if (del_ != null)
                {
                    del_(this, new CircularBufferNotificationTimerMessageEventArgs(msg));
                }
            }
#endif

            //if (m_CircularBuffer != null && m_CircularBuffer.Capturing)
            //{
            //    int capturePosition;
            //    int readPosition;
            //    m_CircularBuffer.GetCurrentPosition(out capturePosition, out readPosition);

            //    return
            //        RecordingPCMFormat.ConvertBytesToTime(m_TotalRecordedBytes + capturePosition -
            //                                                m_CircularBufferReadPositon);
            //}

            int length = circularBufferBytesAvailableForReading;

            DebugFix.Assert(length <= incomingPcmData.Length);
            if (length > incomingPcmData.Length)
            {
                length = incomingPcmData.Length;
            }

            if (m_TotalRecordedBytes >= (ulong.MaxValue - (ulong)length))
            {
#if DEBUG
                Debugger.Break();
#endif //DEBUG

                // Oh oh! :(
                if (CurrentState == State.Monitoring)
                {
                    m_TotalRecordedBytes = 0;
#if FORCE_SINGLE_NOTIFICATION_EVENT
                    m_PreviousTotalRecordedBytes = 0;
#endif
                }
            }
            else
            {
                if (CurrentState == State.Recording)
                {
                    if (m_RecordingFileWriter == null)
                    {
                        string parentDir = Path.GetDirectoryName(m_RecordedFilePath);
                        if (!Directory.Exists(parentDir))
                        {
                            Directory.CreateDirectory(parentDir);
                            //FileDataProvider.CreateDirectory(parentDir);
                        }

                        //FileInfo fi = new FileInfo(m_RecordedFilePath);
                        //fi.FullName
                        m_RecordingFileWriter = new BinaryWriter(File.OpenWrite(m_RecordedFilePath));
                    }

                    m_RecordingFileWriter.BaseStream.Position = (long)m_TotalRecordedBytes +
                                                                (long)m_RecordedFileRiffHeaderSize;
                    // m_RecordingFileWriter.BaseStream.Length;
                    m_RecordingFileWriter.Write(incomingPcmData, 0, length);
                }

                m_TotalRecordedBytes += (ulong)length;
            }

            m_CircularBufferReadPositon += length;
            m_CircularBufferReadPositon %= circularBufferBytes;

            PcmDataBufferAvailableHandler del = PcmDataBufferAvailable;
            if (del != null)
            {
                //if (m_PcmDataBuffer.Length != incomingPcmData.Length)
                //{
                //    //Console.WriteLine(string.Format(">>>>> Resizing buffer: m_PcmDataBuffer = {0}, incomingPcmData = {1}",m_PcmDataBuffer.Length, incomingPcmData.Length));

                //    Array.Resize(ref m_PcmDataBuffer, incomingPcmData.Length);
                //}
                //Array.Copy(incomingPcmData, m_PcmDataBuffer, m_PcmDataBuffer.Length);

                int min = Math.Min(m_PcmDataBufferLength, length);

                //Array.Copy(incomingPcmData, m_PcmDataBuffer, min);
                Buffer.BlockCopy(incomingPcmData, 0,
                                 m_PcmDataBuffer, 0,
                                 min);

                m_PcmDataBufferAvailableEventArgs.PcmDataBuffer       = m_PcmDataBuffer;
                m_PcmDataBufferAvailableEventArgs.PcmDataBufferLength = min;

                del(this, m_PcmDataBufferAvailableEventArgs);
            }

            return(length);
        }
Exemple #22
0
        /// <summary>

        /// 将录制的数据写入wav文件 改写为UDP发送

        /// </summary>

        private void RecordCapturedData(Socket Client, EndPoint epserver)

        {
            byte[] CaptureData = null;

            byte[] SendData = null;

            int ReadPos = 0;

            int CapturePos = 0;

            int LockSize = 0;



            mRecBuffer.GetCurrentPosition(out CapturePos, out ReadPos);

            LockSize = ReadPos - mNextCaptureOffset;

            if (LockSize < 0)
            {
                LockSize += mBufferSize;
            }



            // 对齐缓冲区边界,实际上由于开始设定完整,这个操作是多余的.

            LockSize -= (LockSize % mNotifySize);



            if (0 == LockSize)
            {
                return;
            }



            // 读取缓冲区内的数据

            CaptureData = (byte[])mRecBuffer.Read(mNextCaptureOffset, typeof(byte), LockFlag.None, LockSize);


            // 更新已经录制的数据长度.

            mSampleCount += CaptureData.Length;


            //压缩数据,实测压缩率在50%左右

            SendData = ZLibCompressor.Compress(CaptureData);


            // 写入Wav文件 ,在这里改成发送

//            mWriter.Write(SendData, 0, SendData.Length);

            //           mWriter.Write(CaptureData, 0, CaptureData.Length);


            //发送文件到网络
            try
            {
                Client.SendTo(SendData, epServer);//传送语音
                            
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "错误");
            }



            // 移动录制数据的起始点,通知消息只负责指示产生消息的位置,并不记录上次录制的位置

            mNextCaptureOffset += CaptureData.Length;

            mNextCaptureOffset %= mBufferSize; // Circular buffer
        }