예제 #1
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
        }
예제 #2
0
 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();
             }
         }
     }
 }
예제 #3
0
        public static void StartCapturing()
        {
            try
            {
                captureBuffer = new CaptureBuffer(captureBufferDescription, capture);
                SetBufferEvents();
                int halfBuffer = bufferSize / 2;
                captureBuffer.Start(true);
                bool         readFirstBufferPart = true;
                int          offset    = 0;
                MemoryStream memStream = new MemoryStream(halfBuffer);

                while (true)
                {
                    autoResetEvent.WaitOne();

                    memStream.Seek(0, SeekOrigin.Begin);
                    captureBuffer.Read(offset, memStream, halfBuffer, LockFlag.None);
                    readFirstBufferPart = !readFirstBufferPart;
                    offset = readFirstBufferPart ? 0 : halfBuffer;

                    byte[] dataToWrite = ALawEncoder.ALawEncode(memStream.GetBuffer());

                    if (!StopLoop)
                    {
                        OnBufferFulfill(dataToWrite, null);
                    }
                }
            }
            catch (Exception e)
            {
                //
            }
        }
예제 #4
0
    public void StartCapturing()
    {
        try
        {
            _captureBuffer = new CaptureBuffer(_capBufDescr, _capture);
            SetBufferEvents();
            int halfBuffer = _bufferSize / 2;
            _captureBuffer.Start(true);
            bool         readFirstBufferPart = true;
            int          offset    = 0;
            MemoryStream memStream = new MemoryStream(halfBuffer);

            while (true)
            {
                _eventToReset.WaitOne();

                memStream.Seek(0, SeekOrigin.Begin);
                _captureBuffer.Read(offset, memStream, halfBuffer, LockFlag.None);
                readFirstBufferPart = !readFirstBufferPart;
                offset = readFirstBufferPart ? 0 : halfBuffer;

                byte[] dataToWrite = ALawEncoder.ALawEncode(memStream.GetBuffer());

                if (!_StopLoop)
                {
                    OnBufferFulfill(dataToWrite, null);
                }
            }
        }
        catch {}
    }
    public void StartCapturing()
    {
        try
        {
            captureBuffer = new CaptureBuffer(captureBufferDescription, capture); // Set Buffer Size,Voice Recording Format & Input Voice Device
            SetBufferEvents();                                                    // Set the events Positions to Send While Recording
            int halfBuffer = bufferSize / 2;                                      // Take the half buffer size
            captureBuffer.Start(true);                                            // start capturing
            bool         readFirstBufferPart = true;                              // to know which part has been filled (the buufer has been divided into tow parts)
            int          offset    = 0;                                           // at point 0
            MemoryStream memStream = new MemoryStream(halfBuffer);                // set the half buffer size to the memory stream

            while (true)                                                          // Looping until Stoploop=true Set by the talker
            {
                //WaitOne() Blocks the current thread until the current WaitHandle receives a signal
                //WaitHandle("Encapsulates operating system–specific objects that wait for exclusive access to shared resources")
                autoResetEvent.WaitOne();

                memStream.Seek(0, SeekOrigin.Begin);                                //Sets the position within the current stream to 0
                captureBuffer.Read(offset, memStream, halfBuffer, LockFlag.None);   // capturing and set to MemoryStream
                readFirstBufferPart = !readFirstBufferPart;                         // reflecting the boolean value to set the new comming buffer to the other part
                offset = readFirstBufferPart ? 0 : halfBuffer;                      // if readFirstBufferPart set to true then set the offset to 0 else set the offset to the half buffer

                byte[] dataToWrite = ALawEncoder.ALawEncode(memStream.GetBuffer()); // G.711 Encoding, Compress to less then 50%

                if (!StopLoop)
                {
                    OnBufferFulfill(dataToWrite, null);
                }
            }
        }
        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
        }
        //真正转移数据的事件,其实就是把数据传送到网络上去。
        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;//取模是因为缓冲区是循环的。
        }
예제 #8
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");
        }
예제 #9
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
        }
예제 #10
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
        }
예제 #11
0
        public float GetSignFromDevice(out float response)
        {
            cap  = new Capture(deviceGuid);
            desc = new CaptureBufferDescription();

            WaveFormat wf = new WaveFormat();

            wf.BitsPerSample         = bitsPerSample;
            wf.SamplesPerSecond      = sampleRate;
            wf.Channels              = channels;
            wf.BlockAlign            = (short)(wf.Channels * wf.BitsPerSample / 8);
            wf.AverageBytesPerSecond = wf.BlockAlign * wf.SamplesPerSecond;
            wf.FormatTag             = WaveFormatTag.Pcm;

            desc.Format      = wf;
            desc.BufferBytes = SAMPLES * wf.BlockAlign;

            buffer = new Microsoft.DirectX.DirectSound.CaptureBuffer(desc, cap);
            buffer.Start(true);

            while (start)
            {
                Array samples = buffer.Read(0, typeof(Int16), LockFlag.FromWriteCursor, SAMPLE_FORMAT_ARRAY);
                response = ((float)samples.GetValue(0, 0, 0)) / 100;
            }
            response = 0.0f;
            return(0.0f);
        }
예제 #12
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;//取模是因为缓冲区是循环的。
        }
예제 #13
0
 private void Send()
 {
     try
     {
         captureBuffer = new CaptureBuffer(captureBufferDescription, cap);
         CreateNotifyPositions();
         int num = checked ((int)Math.Round(unchecked ((double)bufferSize / 2.0)));
         captureBuffer.Start(true);
         bool         flag = true;
         int          bufferStartingLocation = 0;
         MemoryStream memoryStream           = new MemoryStream(num);
         while (flagSrarting)
         {
             autoResetEvent.WaitOne();
             memoryStream.Seek(0L, SeekOrigin.Begin);
             captureBuffer.Read(bufferStartingLocation, memoryStream, num, LockFlag.None);
             flag = !flag;
             bufferStartingLocation = ((!flag) ? num : 0);
             byte[] buffer = memoryStream.GetBuffer();
             udpSend.Send(buffer, buffer.Length, send_Com);
         }
     }
     catch (Exception ex)
     {
         ProjectData.SetProjectError(ex);
         Exception ex2 = ex;
         ProjectData.ClearProjectError();
     }
     finally
     {
         captureBuffer.Stop();
         captureBuffer.Dispose();
         udpSend.Close();
     }
 }
예제 #14
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 { }
        }
예제 #15
0
        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();
            }
        }
예제 #16
0
            private void StreamSource(ISource aSource)
            {
                SendResponse("200 OK");

                iSocket.Send(iWavFileHeader);

                const int kAudioChunkBytes = 144 * 1024;
                const int kAudioChunks     = 4;

                CaptureBuffer capture = CreateCaptureBuffer(aSource, kAudioChunks * kAudioChunkBytes);

                int offset = 0;

                NotificationPosition[] notifications = new NotificationPosition[kAudioChunks];
                WaitHandle[]           handles       = new WaitHandle[kAudioChunks];

                for (uint i = 0; i < kAudioChunks; i++)
                {
                    NotificationPosition notification = new NotificationPosition();
                    notification.Offset = offset;
                    notification.Event  = new ManualResetEvent(false);
                    handles[i]          = notification.Event;
                    notifications[i]    = notification;
                    offset += kAudioChunkBytes;
                }

                capture.SetNotificationPositions(notifications);

                // Rotate notifications

                for (uint i = 0; i < kAudioChunks - 1; i++)
                {
                    WaitHandle a = handles[i];
                    handles[i]     = handles[i + 1];
                    handles[i + 1] = a;
                }

                byte[] audio = new byte[kAudioChunkBytes];

                capture.Start(true);

                try
                {
                    while (true)
                    {
                        int x = WaitHandle.WaitAny(handles);
                        ManualResetEvent manual = handles[x] as ManualResetEvent;
                        manual.Reset();
                        capture.Read <byte>(audio, 0, kAudioChunkBytes, notifications[x].Offset, false);
                        iSocket.Send(audio);
                    }
                }
                catch (SocketException)
                {
                }

                capture.Stop();
            }
예제 #17
0
파일: AudioRecorder.cs 프로젝트: daisy/obi
        //  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
        }
예제 #18
0
        /*
         * Send synchronously sends data captured from microphone across the network on port 1550.
         */
        private void UDP_Send()
        {
            try {
                //The following lines get audio from microphone and then send them
                //across network.

                captureBuffer = new CaptureBuffer(captureBufferDescription, capture);

                UDP_CreateNotifyPositions();

                int halfBuffer = bufferSize / 2;

                captureBuffer.Start(true);

                bool readFirstBufferPart = true;
                int  offset = 0;

                MemoryStream memStream = new MemoryStream(halfBuffer);
                bStop = false;
                while (!bStop)
                {
                    autoResetEvent.WaitOne();
                    memStream.Seek(0, SeekOrigin.Begin);
                    captureBuffer.Read(offset, memStream, halfBuffer, LockFlag.None);
                    readFirstBufferPart = !readFirstBufferPart;
                    offset = readFirstBufferPart ? 0 : halfBuffer;

                    //TODO: Fix this ugly way of initializing differently.

                    //Choose the vocoder. And then send the data to other party at port 1550.


                    byte[] dataToWrite = ALawEncoder.ALawEncode(memStream.GetBuffer());
                    udpClient.Send(dataToWrite, dataToWrite.Length, otherPartyIP.Address.ToString(), 6068);
                }
            } catch (Exception ex) {
                MessageBox.Show(ex.Message, "VoiceChat-Send ()", MessageBoxButtons.OK, MessageBoxIcon.Error);
            } finally {
                captureBuffer.Stop();

                //Increment flag by one.
                nUdpClientFlag += 1;

                //When flag is two then it means we have got out of loops in Send and Receive.
                while (nUdpClientFlag != 2)
                {
                }

                //Clear the flag.
                nUdpClientFlag = 0;

                //Close the socket.
                udpClient.Close();
            }
        }
예제 #19
0
        /*
         * Send synchronously sends data captured from microphone across the network on port 1550.
         */
        private void Send()
        {
            try
            {
                //The following lines get audio from microphone and then send them
                //across network.

                captureBuffer = new CaptureBuffer(captureBufferDescription, capture);

                CreateNotifyPositions();

                int halfBuffer = bufferSize / 2;

                captureBuffer.Start(true);

                bool readFirstBufferPart = true;
                int  offset = 0;

                MemoryStream memStream = new MemoryStream(halfBuffer);
                bStop = false;
                while (!bStop)
                {
                    autoResetEvent.WaitOne();
                    memStream.Seek(0, SeekOrigin.Begin);
                    captureBuffer.Read(offset, memStream, halfBuffer, LockFlag.None);
                    readFirstBufferPart = !readFirstBufferPart;
                    offset = readFirstBufferPart ? 0 : halfBuffer;

                    byte[] dataToWrite = memStream.GetBuffer();
                    udpClient.Send(dataToWrite, dataToWrite.Length, "169.254.133.4", 1550);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "VoiceChat-Send ()", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                captureBuffer.Stop();

                //Increment flag by one.
                nUdpClientFlag += 1;

                //When flag is two then it means we have got out of loops in Send and Receive.
                while (nUdpClientFlag != 2)
                {
                }

                //Clear the flag.
                nUdpClientFlag = 0;

                //Close the socket.
                udpClient.Close();
            }
        }
예제 #20
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;
            }
        }
예제 #21
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;
        }
예제 #22
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());
                }
            }
        }
예제 #23
0
        /*
         * Send synchronously sends data captured from microphone across the network on port 1550.
         */
        private void Send()
        {
            try
            {
                udpAudioSending = new UdpClient();

                //The following lines get audio from microphone and then send them
                //across network.

                captureBuffer = new CaptureBuffer(captureBufferDescription, capture);

                CreateNotifyPositions();

                int halfBuffer = bufferSize / 2;

                captureBuffer.Start(true);

                bool readFirstBufferPart = true;
                int  offset = 0;

                MemoryStream memStream = new MemoryStream(halfBuffer);
                audioSend = true;

                while (true)
                {
                    autoResetEvent.WaitOne();
                    memStream.Seek(0, SeekOrigin.Begin);
                    captureBuffer.Read(offset, memStream, halfBuffer, LockFlag.None);
                    readFirstBufferPart = !readFirstBufferPart;
                    offset = readFirstBufferPart ? 0 : halfBuffer;

                    byte[] dataToWrite = memStream.GetBuffer();

                    udpAudioSending.Send(dataToWrite, dataToWrite.Length, serverIPAddress, 1550);
                }
            }
            catch (Exception ex)
            {
                if (captureBuffer.Capturing)
                {
                    captureBuffer.Stop();
                }

                Send();
                //MessageBox.Show(ex.Message, "VoiceChat-Send ()", MessageBoxButtons.OK, MessageBoxIcon.Error);
                //return;
            }
        }
예제 #24
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.
        }
예제 #25
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 { }
        }
예제 #26
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;//取模是因为缓冲区是循环的。
        }
예제 #27
0
        private void Process()
        {
            //lock (this.thread)
            while (true)
            {
                // Wait for the buffer to fill up (no timeout)
                WaitHandle.WaitAny(this.fullEvent, -1, false);

                // Capture audio data
                var data = new short[numberOfSamples * 2]; // Stereo
                captureBuffer.Read(data, captureBuffer.CurrentRealPosition, LockFlags.FromWriteCursor);

                onProcessAudio(data);

                /*int num = captureBuffer.CurrentCapturePosition - captureBuffer.CurrentRealPosition;
                 *
                 * if (num > 0)
                 * {
                 *  onProcessAudio(data, num);
                 * }*/
            }
        }
예제 #28
0
        /// <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();
            }
        }
예제 #29
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
    }
예제 #30
0
        private void SendAudio()
        {
            try
            {
                // Capturamos el audio y lo enviamos por la red
                int halfbuffer = buffersize / 2;
                captureBuffer = new CaptureBuffer(captureBuffDesc, capture);
                CreateNotifyPositions();
                captureBuffer.Start(true);
                bool         readFirstBufferPart = true;
                int          offset    = 0;
                MemoryStream memStream = new MemoryStream(halfbuffer);

                while (!button7.Enabled)
                {
                    // Esperamos un evento
                    autoResetEvent.WaitOne();
                    // Ponemos el puntero al principio del MS
                    memStream.Seek(0, SeekOrigin.Begin);
                    // Leemos el Buffer de Captura y lo guardamos en la primera mitad
                    captureBuffer.Read(offset, memStream, halfbuffer, LockFlag.None);
                    readFirstBufferPart = !readFirstBufferPart;
                    offset = readFirstBufferPart ? 0 : halfbuffer;

                    // Preparamos el stream de datos
                    //byte[] data = memStream.GetBuffer();    // Sin compresión
                    byte[] data = ALawEncoder.ALawEncode(memStream.GetBuffer());

                    // Enviamos via RTP al usuario.
                    audio.sendALaw(data);
                    num_audio++;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error sending audio.");
            }
        }
예제 #31
0
        /// <summary>
        ///   Worker thread.
        /// </summary>
        /// 
        private void WorkerThread()
        {
            // Get the selected capture device
            DirectSoundCapture captureDevice = new DirectSoundCapture(device);


            // Set the capture format
            WaveFormat format = new WaveFormat();
            format.Channels = 1;
            format.SamplesPerSecond = sampleRate;
            format.FormatTag = sampleFormat.ToWaveFormat();
            format.BitsPerSample = (short)Signal.GetSampleSize(sampleFormat);
            format.BlockAlignment = (short)(format.BitsPerSample / 8);
            format.AverageBytesPerSecond = format.SamplesPerSecond * format.BlockAlignment;

            // Setup the capture buffer
            CaptureBufferDescription captureBufferDescription = new CaptureBufferDescription();
            captureBufferDescription.Format = format;
            captureBufferDescription.BufferBytes = 2 * desiredCaptureSize * format.BlockAlignment;
            captureBufferDescription.WaveMapped = true;
            captureBufferDescription.ControlEffects = false;

            CaptureBuffer captureBuffer = null;
            NotificationPosition[] notifications = new NotificationPosition[2];

            try
            {
                captureBuffer = new CaptureBuffer(captureDevice, captureBufferDescription);

                // Setup the notification positions
                int bufferPortionSize = captureBuffer.SizeInBytes / 2;
                notifications[0] = new NotificationPosition();
                notifications[0].Offset = bufferPortionSize - 1;
                notifications[0].Event = new AutoResetEvent(false);
                notifications[1] = new NotificationPosition();
                notifications[1].Offset = bufferPortionSize - 1 + bufferPortionSize;
                notifications[1].Event = 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].Event;



                // 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);
                        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);
                        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].Event != null)
                        notifications[i].Event.Close();
            }
        }
예제 #32
0
        /*
         * Send synchronously sends data captured from microphone across the network on port 1550.
         */
        private void Send()
        {
            try
            {
                //The following lines get audio from microphone and then send them
                //across network.

                captureBuffer = new CaptureBuffer(captureBufferDescription, capture);

                CreateNotifyPositions();

                int halfBuffer = bufferSize / 2;

                captureBuffer.Start(true);

                bool readFirstBufferPart = true;
                int offset = 0;

                MemoryStream memStream = new MemoryStream(halfBuffer);
                bStop = false;
                while (!bStop)
                {
                    autoResetEvent.WaitOne();
                    memStream.Seek(0, SeekOrigin.Begin);
                    captureBuffer.Read(offset, memStream, halfBuffer, LockFlag.None);
                    readFirstBufferPart = !readFirstBufferPart;
                    offset = readFirstBufferPart ? 0 : halfBuffer;

                    //TODO: Fix this ugly way of initializing differently.

                    //Choose the vocoder. And then send the data to other party at port 1550.

                    if (vocoder == Vocoder.ALaw)
                    {
                        byte[] dataToWrite = ALawEncoder.ALawEncode(memStream.GetBuffer());
                        udpClient.Send(dataToWrite, dataToWrite.Length, otherPartyIP.Address.ToString (), 1550);
                    }
                    else if (vocoder == Vocoder.uLaw)
                    {
                        byte[] dataToWrite = MuLawEncoder.MuLawEncode(memStream.GetBuffer());
                        udpClient.Send(dataToWrite, dataToWrite.Length, otherPartyIP.Address.ToString(), 1550);
                    }
                    else
                    {
                        byte[] dataToWrite = memStream.GetBuffer();
                        udpClient.Send(dataToWrite, dataToWrite.Length, otherPartyIP.Address.ToString(), 1550);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "VoiceChat-Send ()", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                captureBuffer.Stop();

                //Increment flag by one.
                nUdpClientFlag += 1;

                //When flag is two then it means we have got out of loops in Send and Receive.
                while (nUdpClientFlag != 2)
                { }

                //Clear the flag.
                nUdpClientFlag = 0;

                //Close the socket.
                udpClient.Close();
            }
        }
예제 #33
0
 private void StartRecordAndSend()
 {
     try
     {
         Capture capture = null;
         CaptureDevicesCollection captureDeviceCollection = new CaptureDevicesCollection();
         try
         {
             capture = new Capture(captureDeviceCollection[ConfSingleton.Instance.CaptureDeviceIndex].DriverGuid);
         }
         catch
         {
             capture = new Capture(captureDeviceCollection[0].DriverGuid);
         }
         captureBuffer = new CaptureBuffer(captureBufferDescription, capture);
         SetBufferEvents();
         int halfBuffer = bufferSize / 2;
         captureBuffer.Start(true);
         bool readFirstBufferPart = true;
         int offset = 0;
         MemoryStream memStream = new MemoryStream(halfBuffer);
         bStop = false;
         while (!bStop)
         {
             autoResetEvent.WaitOne();
             memStream.Seek(0, SeekOrigin.Begin);
             captureBuffer.Read(offset, memStream, halfBuffer, LockFlag.None);
             readFirstBufferPart = !readFirstBufferPart;
             offset = readFirstBufferPart ? 0 : halfBuffer;
             rtpSender.Send(ConfSingleton.Instance.Compression ? ALawEncoder.ALawEncode(memStream.GetBuffer()) : memStream.GetBuffer());
         }
     }
     catch (ThreadAbortException)
     {
         /* This is OK. It's raised when the record thread is stopped. */
     }
     /* Catch DirectSound's uninformative exceptions and attempt to expand on them... */
     catch (Exception ex)
     {
         if (OnCaptureError != null)
         {
             AudioCaptureException captureException = new AudioCaptureException("There was a problem in the audio capture process. This is often due to no working capture device being available.", ex);
             OnCaptureError(this, new AudioCaptureExceptionEventArgs() { Exception = captureException });
         }
     }
     finally
     {
         try
         {
             if (captureBuffer != null)
                 captureBuffer.Stop();
             bStop = true;
         }
         catch { }
     }
 }
예제 #34
0
        /*
         * Send synchronously sends data captured from microphone across the network on port 1550.
         */
        private void Send()
        {
            try
            {
                //The following lines get audio from microphone and then send them
                //across network.

                captureBuffer = new CaptureBuffer(captureBufferDescription, capture);

                CreateNotifyPositions();

                int halfBuffer = bufferSize / 2;

                captureBuffer.Start(true);

                bool readFirstBufferPart = true;
                int offset = 0;

                MemoryStream memStream = new MemoryStream(halfBuffer);
                bStop = false;
                while (!bStop)
                {
                    autoResetEvent.WaitOne();
                    memStream.Seek(0, SeekOrigin.Begin);
                    captureBuffer.Read(offset, memStream, halfBuffer, LockFlag.None);
                    readFirstBufferPart = !readFirstBufferPart;
                    offset = readFirstBufferPart ? 0 : halfBuffer;

                    //TODO: Fix this ugly way of initializing differently.

                    //Choose the vocoder. And then send the data to other party at port 1550.

                    //循环聊天室里面的用户发送语音数据

                    List<ChatUser> chatUserlist = LoginRoler.chatUserlist;

                    if (chatUserlist!=null && chatUserlist.Count>0)
                    {
                        //chatroomusers
                        for (int a = 0; a < chatUserlist.Count; a++)
                        {

                            //Console.WriteLine("ip=" + chatroomusers.Items[a].Text.ToString() + "进入聊天");

                            string ip = (((ChatUser)chatUserlist[a]).ChatIp).ToString();

                            if (ip.Equals(LoginRoler.ip)) continue;

                            //Console.WriteLine("发送音频数据到:" + ip);

                            if (vocoder == Vocoder.ALaw)
                            {
                                byte[] dataToWrite = ALawEncoder.ALawEncode(memStream.GetBuffer());
                                //udpClient.Send(dataToWrite, dataToWrite.Length, otherPartyIP.Address.ToString(), 1550);
                                udpClient.Send(dataToWrite, dataToWrite.Length, ip, 1550);
                            }
                            else if (vocoder == Vocoder.uLaw)
                            {
                                byte[] dataToWrite = MuLawEncoder.MuLawEncode(memStream.GetBuffer());
                                //udpClient.Send(dataToWrite, dataToWrite.Length, otherPartyIP.Address.ToString(), 1550);
                                udpClient.Send(dataToWrite, dataToWrite.Length, ip, 1550);
                                //udpClient.Send(dataToWrite, dataToWrite.Length, "192.168.0.104", 1550);
                            }
                            else
                            {
                                byte[] dataToWrite = memStream.GetBuffer();
                                //udpClient.Send(dataToWrite, dataToWrite.Length, otherPartyIP.Address.ToString(), 1550);
                                udpClient.Send(dataToWrite, dataToWrite.Length, ip, 1550);
                            }
                        }
                    }

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "VoiceChat-Send ()", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                captureBuffer.Stop();

                //Increment flag by one.
                nUdpClientFlag += 1;

                //When flag is two then it means we have got out of loops in Send and Receive.
                while (nUdpClientFlag != 2)
                { }

                //Clear the flag.
                nUdpClientFlag = 0;

                //Close the socket.
                //udpClient.Close();
            }
        }
예제 #35
0
        /// <summary>
        /// Records sound data from the given audio input.
        /// </summary>
        ///
        /// <remarks>
        /// Note that this method will block forever. Threading will be required
        /// to get the data back.
        /// </remarks>
        /// 
        /// <param name="capture">The input to record from.</param>
        /// <returns>The audio data recorded from the input.</returns>
        public void Record(Capture capture)
        {
            if (Recording) {
            throw new Exception("Already recording.");
              }

              WaveFormat format = (WaveFormat) GetAmibiguousType(typeof(WaveFormat));
              format.SamplesPerSecond = 96000;
              format.BitsPerSample = 16;
              format.Channels = 1;
              format.FormatTag = WaveFormatTag.Pcm;
              format.BlockAlign = (Int16) (format.Channels * (format.BitsPerSample / 8));
              format.AverageBytesPerSecond = format.SamplesPerSecond * format.BlockAlign;

              int notifySize = Math.Max(4096, format.AverageBytesPerSecond / 16);
              notifySize -= notifySize % format.BlockAlign;

              // This is a fairly arbitrary choice.
              int inputSize = notifySize * 16;
              // Output is half of input, as every two bytes is a piece of sound data.
              int outputSize = inputSize / 2;

              CaptureBufferDescription description = (CaptureBufferDescription)
              GetAmibiguousType(typeof(CaptureBufferDescription));
              description.Format = format;
              description.BufferBytes = inputSize;

              CaptureBuffer buffer;
              try {
            buffer = new CaptureBuffer(description, capture);
              } catch {
            throw new IOException(
            "An error occurred attempting to set up a read buffer.");
              }

              AutoResetEvent reset = new AutoResetEvent(false);
              Notify notify = new Notify(buffer);

              BufferPositionNotify bpn1 = (BufferPositionNotify)
              GetAmibiguousType(typeof(BufferPositionNotify));

              bpn1.Offset = buffer.Caps.BufferBytes / 2 - 1;
              bpn1.EventNotifyHandle = reset.SafeWaitHandle.DangerousGetHandle();
              BufferPositionNotify bpn2 = (BufferPositionNotify)
              GetAmibiguousType(typeof(BufferPositionNotify));
              bpn2.Offset = buffer.Caps.BufferBytes - 1;
              bpn2.EventNotifyHandle = reset.SafeWaitHandle.DangerousGetHandle();

              notify.SetNotificationPositions(new BufferPositionNotify[] {
            bpn1, bpn2
              });

              int offset = 0;
              Data = new List<Int16>();

              Recording = true;
              new Thread((ThreadStart) delegate {
            buffer.Start(true);

            while (Recording) {
              // Let the buffer fill up from the last read.
              reset.WaitOne();

              byte[] read;
              try {
            read = (byte[]) buffer.Read(offset, typeof(byte), LockFlag.None,
                               outputSize);
              } catch {
            throw new IOException(
                "An error occurred attempting to read the input data.");
              }
              offset = (offset + outputSize) % inputSize;

              bool written = false;
              Int16 old = 0;
              foreach (byte b in read) {
            if (!written) {
              old = (Int16) b;
            } else {
              old = (Int16) (old | (((Int16) (b << 8))));
              Data.Add(old);
            }
            written = !written;
              }
            }

            buffer.Stop();
              }).Start();
        }
예제 #36
0
        /*
          * Send synchronously sends data captured from microphone across the network on port 1550.
          */
        private void Send()
        {
            try
             {

                 IsThreadSendEnd = false;

                 //The following lines get audio from microphone and then send them
                 //across network.

                 int users_count = 0;

                 captureBuffer = new CaptureBuffer(captureBufferDescription, capture);
                 CreateNotifyPositions();
                 int halfBuffer = bufferSize / 2;
                 captureBuffer.Start(true);
                 bool readFirstBufferPart = true;
                 int offset = 0;
                 MemoryStream memStream = new MemoryStream(halfBuffer);
                 bStop = false;

                 LogAppend("Sending Started");

                 while (!bStop)
                 {

                     lock (otherPartyIPs)
                     {

                         users_count = otherPartyIPs.Count;

                         if (users_count > 0)
                         {

                             autoResetEvent.WaitOne();
                             memStream.Seek(0, SeekOrigin.Begin);
                             captureBuffer.Read(offset, memStream, halfBuffer, LockFlag.None);
                             readFirstBufferPart = !readFirstBufferPart;
                             offset = readFirstBufferPart ? 0 : halfBuffer;

                             //TODO: Fix this ugly way of initializing differently.
                             //Choose the vocoder. And then send the data to other party at port 1550.
                             //if (vocoder == Vocoder.ALaw)
                             //{

                             //byte[] dataToWrite = MuLawEncoder.MuLawEncode(memStream.GetBuffer()); //MULAW
                             //byte[] dataToWrite = ALawEncoder.ALawEncode(memStream.GetBuffer()); //ALAW (RECOMENdADO)
                             byte[] dataToWrite = memStream.GetBuffer(); //NORMAL

                             if (bStop)
                                 return;

                             for (int i = 0; i < users_count; i++)
                                 udpClient.Send(dataToWrite, dataToWrite.Length, otherPartyIPs[i].Address.ToString(), 1550);
                         }

                     }
                 }

                 IsThreadSendEnd = true;
                 LogAppend("Sending Ended");

             }
             catch (Exception ex)
             {
                 // MessageBox.Show(ex.Message, "VoiceChat-Send ()", MessageBoxButtons.OK, MessageBoxIcon.Error);
                 LogAppend("VoiceChat-Send >> " + ex.Message);
             }
             finally
             {
                 captureBuffer.Stop();

                 //Increment flag by one.
                 nUdpClientFlag += 1;

                 //When flag is two then it means we have got out of loops in Send and Receive.
                 while (nUdpClientFlag != 2)
                 { }

                 //Clear the flag.
                 nUdpClientFlag = 0;

                 //Close the socket.
                 udpClient.Close();
             }
        }
예제 #37
0
        /// <summary>
        /// Records sound data from the given audio input.
        /// </summary>
        ///
        /// <remarks>
        /// Note that this method will block forever. Threading will be required
        /// to get the data back.
        /// </remarks>
        /// 
        /// <param name="capture">The input to record from.</param>
        /// <returns>The audio data recorded from the input.</returns>
        public bool Record(Capture cap)
        {
            if(recording){
            return false;
              }
              // string captureDescriptor – string for eg “Mic”, “Input”
              // Control owner – maybe Window or Form would do for this – was Native.GetDesktopWindow()
              // if windowless application use desktop window as message broker
              // Returns true for setup done and thread started, false for problem

              // Choose a Wave format, calculating BlockAlign and AverageBytesPerSecond
              ConstructorInfo nom = typeof(WaveFormat).GetConstructor(Type.EmptyTypes);
              format = (WaveFormat)nom.Invoke(null);
              format.SamplesPerSecond = 96000;
              format.BitsPerSample = 16;
              format.Channels = 1;
              format.FormatTag = WaveFormatTag.Pcm;

              SData = new List<Int16>();

              // Both of these are calculate for All channels
              // BlockAlign = BytesPerSampleAllChannels, AverageBytesPerSecond = BytesPerSecondAllChannels
              format.BlockAlign = (short)(format.Channels * (format.BitsPerSample / 8));
              format.AverageBytesPerSecond = format.SamplesPerSecond * format.BlockAlign;

              // Set the size of input and output buffers

              // Multiplier of both delay and minimum buffer size in units of 1/16th secs,
              int NUM_BUFFERS = 8;

              // Sets _dwNotifySize to enough bytes for 1/16th of a second, all channels
              // Note that this was 1/8th (ie line ended ‘/ 8);’), and output buffer size = capture size/2
              // But this was changed to allow output buffer size to be a multiple of BlockAlign
              int _dwNotifySize = Math.Max(4096, format.AverageBytesPerSecond / (8 * 2));
              // rounds _dwNotifySize to a multiple of BlockAlign (BytesPerSampleAllChannel)
              _dwNotifySize -= _dwNotifySize % format.BlockAlign;

              // Capture buffer is looped – when the end is reached, it starts from the beginning again.
              // Capturing one should be twice as large as output – so that when completed capture
              // is being read to output buffer there is still room to for the buffer to keep filling
              // without overwriting the output. I think.
              int _dwCaptureBufferSize = NUM_BUFFERS * _dwNotifySize * 2;
              int _dwOutputBufferSize = NUM_BUFFERS * _dwNotifySize;

              // Check a matching capture device was found
              if (cap == null)
            return false; // no matching sound card/capture device
              {

            // Make the description and create a CaptureBuffer accordingly
            ConstructorInfo capnom = typeof(CaptureBufferDescription).GetConstructor(Type.EmptyTypes);
            var capDesc = (CaptureBufferDescription)capnom.Invoke(null);

            capDesc.Format = format;
            capDesc.BufferBytes = _dwCaptureBufferSize;

            var _dwCapBuffer = new CaptureBuffer(capDesc, cap);

            // Create two output buffers – this seems to avoid the buffer being locked and written
            // to while it's still playing, helping to avoid a sound glitch on my machine.
            var _dwDevBuffers = new SecondaryBuffer[2];

            // Set autoResetEvent to be fired when it's filled and subscribe to buffer notifications

            var _resetEvent = new AutoResetEvent(false);
            var _notify = new Notify(_dwCapBuffer);
            // Half&half – one notification halfway through the output buffer, one at the end
            ConstructorInfo buffnom = typeof(BufferPositionNotify).GetConstructor(Type.EmptyTypes);
            var bpn1 = (BufferPositionNotify)buffnom.Invoke(null);
            bpn1.Offset = _dwCapBuffer.Caps.BufferBytes / 2 - 1;
            bpn1.EventNotifyHandle = _resetEvent.SafeWaitHandle.DangerousGetHandle();
            var bpn2 = (BufferPositionNotify)buffnom.Invoke(null);
            bpn2.Offset = _dwCapBuffer.Caps.BufferBytes - 1;
            bpn2.EventNotifyHandle = _resetEvent.SafeWaitHandle.DangerousGetHandle();

            _notify.SetNotificationPositions(new BufferPositionNotify[] { bpn1, bpn2 });

            recording = true; // ready to capture sound

            // Fire worker thread to take care of messages
            // Note that on a uniprocessor, the new thread may not get any processor time
            // until the main thread is preempted or yields, eg by ending button click event or
            // calling Thread.Sleep(0)

            // botch – not sure if these are thread safe for multiple threads
            int offset = 0;
            int devbuffer = 0;

            // Make a new thread – as countained in the { }
            Thread _dwCaptureThread = new Thread((ThreadStart)delegate
            {
              _dwCapBuffer.Start(true); // start capture

              // IsReady – This should be true while you wish to capture and then output the sound.
              while (recording)
              {
            _resetEvent.WaitOne(); // blocks thread until _dwCapBuffer is half/totally full
            // Read the capture buffer into an array, and output it to the next DevBuffer
            byte[] read = (byte[])_dwCapBuffer.Read(offset, typeof(byte), LockFlag.None, _dwOutputBufferSize);

            for (int i = 0; i < read.Length; i++)
            {
              SData.Add(Int16.Parse(read[i].ToString()));
            }

            //       _dwDevBuffers[devbuffer].Write(0, read, LockFlag.EntireBuffer);

            // Update offset
            offset = (offset + _dwOutputBufferSize) % _dwCaptureBufferSize;

            devbuffer = 1 - devbuffer; // toggle between 0 and 1

              }
              _dwCapBuffer.Stop(); // stop capture

            });

            _dwCaptureThread.Start(); // start the new Thread
            return true;
              }
        }