//Stopwatch _stopwatch = new Stopwatch(); private void _waveIn_DataAvailable(object sender, WaveInEventArgs e) { // if(_stopwatch.ElapsedMilliseconds > 22) //Console.WriteLine($"Time: {_stopwatch.ElapsedMilliseconds} - Bytes: {e.BytesRecorded}"); // _stopwatch.Restart(); short[] pcmShort = null; if ((e.BytesRecorded / 2 == SEGMENT_FRAMES) && (_micInputQueue.Count == 0)) { //perfect! pcmShort = new short[SEGMENT_FRAMES]; Buffer.BlockCopy(e.Buffer, 0, pcmShort, 0, e.BytesRecorded); } else { for (var i = 0; i < e.BytesRecorded; i++) { _micInputQueue.Enqueue(e.Buffer[i]); } } //read out the queue while ((pcmShort != null) || (_micInputQueue.Count >= AudioManager.SEGMENT_FRAMES)) { //null sound buffer so read from the queue if (pcmShort == null) { pcmShort = new short[AudioManager.SEGMENT_FRAMES]; for (var i = 0; i < AudioManager.SEGMENT_FRAMES; i++) { pcmShort[i] = _micInputQueue.Dequeue(); } } //null sound buffer so read from the queue if (pcmShort == null) { pcmShort = new short[AudioManager.SEGMENT_FRAMES]; for (var i = 0; i < AudioManager.SEGMENT_FRAMES; i++) { pcmShort[i] = _micInputQueue.Dequeue(); } } try { //volume boost pre for (var i = 0; i < pcmShort.Length; i++) { // n.b. no clipping test going on here pcmShort[i] = (short)(pcmShort[i] * MicBoost); } //process with Speex _speex.Process(new ArraySegment <short>(pcmShort)); float max = 0; for (var i = 0; i < pcmShort.Length; i++) { //determine peak if (pcmShort[i] > max) { max = pcmShort[i]; } } //convert to dB MicMax = (float)VolumeConversionHelper.ConvertFloatToDB(max / 32768F); var pcmBytes = new byte[pcmShort.Length * 2]; Buffer.BlockCopy(pcmShort, 0, pcmBytes, 0, pcmBytes.Length); //encode as opus bytes int len; var buff = _encoder.Encode(pcmBytes, pcmBytes.Length, out len); if ((_tcpVoiceHandler != null) && (buff != null) && (len > 0)) { //create copy with small buffer var encoded = new byte[len]; Buffer.BlockCopy(buff, 0, encoded, 0, len); // Console.WriteLine("Sending: " + e.BytesRecorded); if (_tcpVoiceHandler.Send(encoded, len)) { //send audio so play over local too _micWaveOutBuffer?.AddSamples(pcmBytes, 0, pcmBytes.Length); } } else { Logger.Error($"Invalid Bytes for Encoding - {e.BytesRecorded} should be {SEGMENT_FRAMES} "); } _errorCount = 0; } catch (Exception ex) { _errorCount++; if (_errorCount < 10) { Logger.Error(ex, "Error encoding Opus! " + ex.Message); } else if (_errorCount == 10) { Logger.Error(ex, "Final Log of Error encoding Opus! " + ex.Message); } } pcmShort = null; } }
//Stopwatch _stopwatch = new Stopwatch(); private void _waveIn_DataAvailable(object sender, WaveInEventArgs e) { // if(_stopwatch.ElapsedMilliseconds > 22) //Console.WriteLine($"Time: {_stopwatch.ElapsedMilliseconds} - Bytes: {e.BytesRecorded}"); // _stopwatch.Restart(); byte[] soundBuffer = null; if ((e.BytesRecorded == SEGMENT_FRAMES) && (_micInputQueue.Count == 0)) { //perfect! soundBuffer = new byte[e.BytesRecorded]; Buffer.BlockCopy(e.Buffer, 0, soundBuffer, 0, e.BytesRecorded); } else { for (var i = 0; i < e.BytesRecorded; i++) { _micInputQueue.Enqueue(e.Buffer[i]); } } //read out the queue while ((soundBuffer != null) || (_micInputQueue.Count >= SEGMENT_FRAMES)) { //null sound buffer so read from the queue if (soundBuffer == null) { soundBuffer = new byte[SEGMENT_FRAMES]; for (var i = 0; i < SEGMENT_FRAMES; i++) { soundBuffer[i] = _micInputQueue.Dequeue(); } } short max = 0; for (var n = 0; n < soundBuffer.Length; n += 2) { var sample = (short)((soundBuffer[n + 1] << 8) | soundBuffer[n + 0]); // n.b. no clipping test going on here // FROM NAUDIO SOURCE ! sample = (short)(sample * MicBoost); //determine peak if (sample > max) { max = sample; } //convert back soundBuffer[n] = (byte)(sample & 0xFF); soundBuffer[n + 1] = (byte)(sample >> 8); } MicMax = max; try { //encode as opus bytes int len; var buff = _encoder.Encode(soundBuffer, soundBuffer.Length, out len); if ((_tcpVoiceHandler != null) && (buff != null) && (len > 0)) { //create copy with small buffer var encoded = new byte[len]; Buffer.BlockCopy(buff, 0, encoded, 0, len); // Console.WriteLine("Sending: " + e.BytesRecorded); if (_tcpVoiceHandler.Send(encoded, len)) { //send audio so play over local too if (_micWaveOutBuffer != null) { _micWaveOutBuffer.AddSamples(soundBuffer, 0, soundBuffer.Length); } } } else { Logger.Error($"Invalid Bytes for Encoding - {e.BytesRecorded} should be {SEGMENT_FRAMES} "); } } catch (Exception ex) { Logger.Error(ex, "Error encoding Opus! " + ex.Message); } soundBuffer = null; } }