public void StartRecording(int deviceIndex) { if (mCaptureBuffer != null) { if (mCaptureBuffer.Capturing) { mCaptureBuffer.Stop(); } mCaptureBuffer.Dispose(); mCaptureBuffer = null; } CaptureDevicesCollection audioDevices = new CaptureDevicesCollection(); if (deviceIndex != -1 && deviceIndex < audioDevices.Count - 1) { // initialize the capture buffer and start the animation thread Capture capture = new Capture(audioDevices[deviceIndex].DriverGuid); CaptureBufferDescription captureBufferDescription = new CaptureBufferDescription(); WaveFormat waveFormat = new WaveFormat(); waveFormat.BitsPerSample = 16; waveFormat.SamplesPerSecond = 8000; waveFormat.Channels = 1; waveFormat.BlockAlign = (short)(waveFormat.Channels * waveFormat.BitsPerSample / 8); waveFormat.AverageBytesPerSecond = waveFormat.BlockAlign * waveFormat.SamplesPerSecond; waveFormat.FormatTag = WaveFormatTag.Pcm; captureBufferDescription.Format = waveFormat; captureBufferDescription.BufferBytes = waveFormat.SamplesPerSecond * 120; mCaptureBuffer = new Microsoft.DirectX.DirectSound.CaptureBuffer(captureBufferDescription, capture); mCaptureBuffer.Start(true); } }
public void RecStop() { // 关闭通知消息 AddLogInfo(DateTime.Now + "写入数据:关闭通知消息 "); if (null != mNotificationEvent) { mNotificationEvent.Set(); } // 停止录音 AddLogInfo(DateTime.Now + "写入数据:停止录音 "); mRecBuffer.Stop(); // 写入缓冲区最后的数据 AddLogInfo(DateTime.Now + "写入数据:写入缓冲区最后的数据 "); RecordCapturedData(); // 回写长度信息 AddLogInfo(DateTime.Now + "写入数据:回写长度信息 "); mWriter.Seek(4, SeekOrigin.Begin); mWriter.Write((int)(mSampleCount + 36)); // 写文件长度 mWriter.Seek(40, SeekOrigin.Begin); mWriter.Write(mSampleCount); // 写数据长度 mWriter.Close(); mWriter.Dispose(); mWaveFile.Close(); mWaveFile.Dispose(); mWriter = null; mWaveFile = null; }
/// <summary> /// Stop Recording /// </summary> public void StopRecording() { // Stop the buffer recording _recordBuffer.Stop(); // Copy out any remaining data CopyRecordedData(); // Check if the recording, is still recording - use this // same method when the form is disposing. if (_recording == true) { // Stop the recording and kill the thread _recording = false; _callMeThread.Abort(); // Write the final configuration infromation for the RIFF description _binaryWriter.Seek(4, SeekOrigin.Begin); _binaryWriter.Write((int)(_sampleBytes + 36)); // Write the data length of the descriptor in bytes _binaryWriter.Seek(40, SeekOrigin.Begin); _binaryWriter.Write(_sampleBytes); // Close and dispose of the writer components _binaryWriter.Close(); _binaryWriter = null; _recordFile = null; } }
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(); } }
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(); } }
/// <summary> /// 停止录音 /// </summary> public void RecStop() { try { // 关闭通知消息 if (null != mNotificationEvent) { mNotificationEvent.Set(); } // 停止录音 mRecBuffer.Stop(); // 写入缓冲区最后的数据 RecordCapturedData(); // 回写长度信息 mWriter.Seek(4, SeekOrigin.Begin); mWriter.Write((int)(mSampleCount + 36)); // 写文件长度 mWriter.Seek(40, SeekOrigin.Begin); mWriter.Write(mSampleCount); // 写数据长度 mWriter.Close(); mWaveFile.Close(); mWriter = null; mWaveFile = null; } catch { } }
private void StopDirectSoundCapturing() { if (applicationBuffer != null) { applicationBuffer.Stop(); } }
void StartOrStopRecord(bool StartRecording) { //----------------------------------------------------------------------------- // Name: StartOrStopRecord() // Desc: Starts or stops the capture buffer from recording //----------------------------------------------------------------------------- if (StartRecording) { // Create a capture buffer, and tell the capture // buffer to start recording CreateCaptureBuffer(); applicationBuffer.Start(true); } else { // Stop the buffer, and read any data that was not // caught by a notification applicationBuffer.Stop(); RecordCapturedData(); Writer.Seek(4, SeekOrigin.Begin); // Seek to the length descriptor of the RIFF file. Writer.Write((int)(SampleCount + 36)); // Write the file length, minus first 8 bytes of RIFF description. Writer.Seek(40, SeekOrigin.Begin); // Seek to the data length descriptor of the RIFF file. Writer.Write(SampleCount); // Write the length of the sample data in bytes. Writer.Close(); // Close the file now. Writer = null; // Set the writer to null. WaveFile = null; // Set the FileStream to null. } }
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(); }
/// <summary> /// Stops recording /// </summary> public void stopRecording() { switch (getState()) { case AudioDeviceState.Recording: case AudioDeviceState.PausedRecord: int ccp, crp; mBuffer.GetCurrentPosition(out ccp, out crp); mBuffer.Stop(); mBuffer.GetCurrentPosition(out ccp, out crp); setState(AudioDeviceState.Stopped); mHasRecordingStopped = true; break; default: throw new ApplicationException("Can only stop recording from recording or paused record states"); } }
/* * 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(); } }
/* * 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(); } }
/// <summary> /// /// </summary> private void stoprec() { capturebuffer.Stop();//Call the buffer to stop the method. Stop collecting sound if (notifyevent != null) { notifyevent.Set(); //Close notification } notifythread.Abort(); //End the thread fftthread.Abort(); RecordCapturedData(); //Write the last part of the buffer to the file }
/// /// 停止录音 /// private void RecStop() { mRecBuffer.Stop(); // 调用缓冲区的停止方法,停止采集声音 if (null != mNotificationEvent) { mNotificationEvent.Set(); //关闭通知 } mNotifyThread.Abort(); //结束线程 RecordCapturedData(); // 将缓冲区最后一部分数据写入到文件中 // 写WAV文件尾 mWriter.Seek(4, SeekOrigin.Begin); mWriter.Write((int)(mSampleCount + 36)); // 写文件长度 mWriter.Seek(40, SeekOrigin.Begin); mWriter.Write(mSampleCount); // 写数据长度 mWriter.Close(); mWaveFile.Close(); mWriter = null; mWaveFile = null; }
/// <summary> /// 停止语音采集 /// </summary> public void Stop() { capturebuffer.Stop(); if (notifyEvent != null) { notifyEvent.Set(); } if (notifyThread != null && notifyThread.IsAlive == true) { notifyThread.Abort(); } }
static void DisposeCaptureBuffer() { if (buffer != null) { if (buffer.Capturing) { buffer.Stop(); } buffer.Dispose(); buffer = null; } }
//it will start actual recording, append if there is data //in the wave file through the RecordCaptureData() public void InitRecording(bool SRecording) { //if no device is set then it is informed then no device is set if (null == m_cApplicationDevice) { throw new Exception("no device is set for recording"); } //format of the capture buffer and the input format is compared //if not same then it is informed that formats do not match if (dsc.Format.ToString() != InputFormat.ToString()) { throw new Exception("formats do not match"); } if (SRecording) { StateChanged mStateChanged = new StateChanged(mState); mState = AudioRecorderState.Recording; FireEvent(mStateChanged); CreateCaptureBuffer(Index); applicationBuffer.Start(true); //it will set the looping till the stop is used } else { applicationBuffer.Stop(); RecordCapturedData(); Writer = new BinaryWriter(File.OpenWrite(m_sFileName)); long Audiolength = (long)(SampleCount + 44); CalculationFunctions cf = new CalculationFunctions(); for (int i = 0; i < 4; i++) { Writer.BaseStream.Position = i + 4; Writer.Write(Convert.ToByte(cf.ConvertFromDecimal(Audiolength)[i])); } for (int i = 0; i < 4; i++) { Writer.BaseStream.Position = i + 40; Writer.Write(Convert.ToByte(cf.ConvertFromDecimal(SampleCount)[i])); } Writer.Close(); // Close the file now. Writer = null; // Set the writer to null. //m_AudioMediaAsset = new AudioMediaAsset(ProjectDirectory+"\\"+m_sFileName); m_AudioMediaAsset = new AudioMediaAsset(m_sFileName); if (OldAsset.SizeInBytes > 44) { OldAsset.MergeWith(m_AudioMediaAsset); //m_AudioMediaAsset = OldAsset; } } }
/// <summary> /// 停止录音 /// </summary> public void RecStop() { // 关闭通知消息 if (null != mNotificationEvent) { mNotificationEvent.Set(); } // 停止录音 mRecBuffer.Stop(); // 写入缓冲区最后的数据 RecordCapturedData(Client, epServer); //关闭socket Client.Shutdown(SocketShutdown.Both); Client.Close(); Client = null; /* * * // 回写长度信息 * * mWriter.Seek(4, SeekOrigin.Begin); * * mWriter.Write((int)(mSampleCount + 36)); // 写文件长度 * * mWriter.Seek(40, SeekOrigin.Begin); * * mWriter.Write(mSampleCount); // 写数据长度 * * * * mWriter.Close(); * * mWaveFile.Close(); * * mWriter = null; * * mWaveFile = null; */ }
public void Stop() { captureBuffer_.Stop(); captureExit_ = true; notifyEvent_.Set(); // 写WAV文件尾 //writer_.Seek(4, SeekOrigin.Begin); //writer_.Write((int)(captureDataLength_ + 36)); // 写文件长度 //writer_.Seek(40, SeekOrigin.Begin); //writer_.Write(captureDataLength_); // 写数据长度 //writer_.Close(); //writer_ = null; }
public void Deint() { server.Close(); server = null; capturebuffer.Stop(); if (notifyEvent != null) { notifyEvent.Set(); } if (notifyThread != null && notifyThread.IsAlive == true) { notifyThread.Abort(); } th.Abort(); }
/// <summary> /// 常時録音を終了する。 /// </summary> public void Stop() { try { applicationBuffer.Stop(); if (notificationEvent != null) { notificationEvent.Set(); } } catch (Exception e) { SoundControl.WriteErrorLog(e.ToString()); } }
/* * 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; } }
public void InitRecording(bool SRecording) { //if no device is set then it is informed then no device is set if (null == m_cApplicationDevice) { throw new Exception("no device is set for recording"); } //format of the capture buffer and the input format is compared //if not same then it is informed that formats do not match if (applicationBuffer.Format.ToString() != InputFormat.ToString()) { throw new Exception("formats do not match"); } if (SRecording) { CreateCaptureBuffer(); applicationBuffer.Start(true); //it will set the looping till the stop is used } else { applicationBuffer.Stop(); RecordCapturedData(); BinaryWriter Writer = new BinaryWriter(File.OpenWrite(m_sFileName)); long Audiolength = (long)(SampleCount + 44); CalculationFunctions cf = new CalculationFunctions(); for (int i = 0; i < 4; i++) { Writer.BaseStream.Position = i + 4; Writer.Write(Convert.ToByte(cf.ConvertFromDecimal(Audiolength)[i])); } for (int i = 0; i < 4; i++) { Writer.BaseStream.Position = i + 40; Writer.Write(Convert.ToByte(cf.ConvertFromDecimal(SampleCount)[i])); } Writer.Close(); // Close the file now. //Set the writer to null. Writer = null; SampleCount = 0; Audiolength = 0; AudioClip NewRecordedClip = new AudioClip(m_sFileName); mAsset.AddClip(NewRecordedClip); //NotifyThread = null; } }
public void stoprec() { //写WAV文件尾 capturebuffer.Stop();//调用缓冲区的停止方法。停止采集声音 if (notifyevent != null) { notifyevent.Set();//关闭通知 } //RecordCapturedData();//将缓冲区最后一部分数据写入到文件中 //bw.Seek(4, SeekOrigin.Begin); //bw.Write((int)(iSampleSize + 36)); // 写文件长度 //bw.Seek(40, SeekOrigin.Begin); //bw.Write(iSampleSize); // 写数据长度 //bw.Close(); //bw.Dispose(); notifythread.Abort();//结束线程 }
public void stoprec() { capturebuffer.Stop(); if (notifyevent != null) { notifyevent.Set(); } notifythread.Abort(); RecordCapturedData(); mWriter.Seek(4, SeekOrigin.Begin); mWriter.Write((int)(iSampleSize + 36)); mWriter.Seek(40, SeekOrigin.Begin); mWriter.Write(iSampleSize); mWriter.Close(); fsWav.Close(); mWriter = null; fsWav = null; }
public void Stoprec() { capturebuffer.Stop();//调用缓冲区的停止方法。停止采集声音 if (notifyevent != null) { notifyevent.Set(); //关闭通知 } notifythread.Abort(); //结束线程 RecordCapturedData(); //将缓冲区最后一部分数据写入到文件中 //写WAV文件尾 mWriter.Seek(4, SeekOrigin.Begin); mWriter.Write((int)(iSampleSize + 36)); // 写文件长度 mWriter.Seek(40, SeekOrigin.Begin); mWriter.Write(iSampleSize); // 写数据长度 mWriter.Close(); fsWav.Close(); mWriter = null; fsWav = null; }
private void UninitializeCall() { eMode = Mode.Stopped; try { udpClient.Close(); } catch (Exception) { } captureBuffer.Stop(); btnStartServer.Text = "Start Server"; //Set the flag to end the Send and Receive threads. bStop = true; bIsServerStarted = false; btnCall.Enabled = true; //btnEndCall.Enabled = false; }
private void _DoCapture() { int bufferPortionSamples = _BufferPortionSize / sizeof(byte); // Buffer type must match this.waveFormat.FormatTag and this.waveFormat.BitsPerSample var bufferPortion = new byte[bufferPortionSamples]; _CaptureBuffer.Start(true); while (_Running) { int bufferPortionIndex = WaitHandle.WaitAny(_WaitHandles); _CaptureBuffer.Read( bufferPortion, 0, bufferPortionSamples, _BufferPortionSize * Math.Abs((bufferPortionIndex - 1) % _BufferPortionCount)); SampleDataReady(this, new CSampleDataEventArgs(bufferPortion, _Guid)); } _CaptureBuffer.Stop(); }
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 { } } }
/// <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; } }
/* * 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(); } }
/// <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(); } }
/* * 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(); } }
// 음성정보를 전달한다. private void SendVoiceInfo() { try { 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; VoiceInfo voiceInfo = new VoiceInfo(); while (!bStop) { autoResetEvent.WaitOne(); memStream.Seek(0, SeekOrigin.Begin); captureBuffer.Read(offset, memStream, halfBuffer, LockFlag.None); readFirstBufferPart = !readFirstBufferPart; offset = readFirstBufferPart ? 0 : halfBuffer; if (vocoder == Vocoder.ALaw) { byte[] dataToWrite = ALawEncoder.ALawEncode(memStream.GetBuffer()); voiceInfo.UserId = Main_Pan._UserInfo.Id; voiceInfo.Data = dataToWrite; Main_Pan._ClientEngine.Send(NotifyType.Request_VoiceChat, voiceInfo); } else if (vocoder == Vocoder.uLaw) { byte[] dataToWrite = MuLawEncoder.MuLawEncode(memStream.GetBuffer()); voiceInfo.UserId = Main_Pan._UserInfo.Id; voiceInfo.Data = dataToWrite; Main_Pan._ClientEngine.Send(NotifyType.Request_VoiceChat, voiceInfo); } else { byte[] dataToWrite = memStream.GetBuffer(); voiceInfo.UserId = Main_Pan._UserInfo.Id; voiceInfo.Data = dataToWrite; Main_Pan._ClientEngine.Send(NotifyType.Request_VoiceChat, voiceInfo); } } } catch (Exception ex) { } finally { captureBuffer.Stop(); nUdpClientFlag = 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(); }
/// <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(); } } } }
/* * 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(); } }