Beispiel #1
0
        private void _waveIn_DataAvailable(object sender, WaveInEventArgs e)
        {
            var soundBuffer = new byte[e.BytesRecorded + _notEncodedBuffer.Length];

            for (var i = 0; i < _notEncodedBuffer.Length; i++)
            {
                soundBuffer[i] = _notEncodedBuffer[i];
            }

            for (var i = 0; i < e.BytesRecorded; i++)
            {
                soundBuffer[i + _notEncodedBuffer.Length] = e.Buffer[i];
            }

            var byteCap = _bytesPerSegment;
            //      Console.WriteLine("{0} ByteCao", byteCap);
            var segmentCount    = (int)Math.Floor((decimal)soundBuffer.Length / byteCap);
            var segmentsEnd     = segmentCount * byteCap;
            var notEncodedCount = soundBuffer.Length - segmentsEnd;

            _notEncodedBuffer = new byte[notEncodedCount];
            for (var i = 0; i < notEncodedCount; i++)
            {
                _notEncodedBuffer[i] = soundBuffer[segmentsEnd + i];
            }

            for (var i = 0; i < segmentCount; i++)
            {
                //create segment of audio
                var segment = new byte[byteCap];
                for (var j = 0; j < segment.Length; j++)
                {
                    segment[j] = soundBuffer[i * byteCap + j];
                }

                //boost microphone volume if needed
                if (MicBoost != 1.0f)
                {
                    for (var n = 0; n < segment.Length; n += 2)
                    {
                        var sample = (short)((segment[n + 1] << 8) | segment[n + 0]);
                        // n.b. no clipping test going on here // FROM NAUDIO SOURCE !
                        sample         = (short)(sample * MicBoost);
                        segment[n]     = (byte)(sample & 0xFF);
                        segment[n + 1] = (byte)(sample >> 8);
                    }
                }

                //encode as opus bytes
                int len;
                var buff = _encoder.Encode(segment, segment.Length, out len);

                if (_udpVoiceHandler != null && buff != null && len > 0)
                {
                    _udpVoiceHandler.Send(buff, len);
                }
            }
        }
        private void SendAudio()
        {
            Logger.Info("Sending Audio... Please Wait");
            AudioGenerator mp3       = new AudioGenerator(mp3Path, volume, SpeakerGender, SpeakerCulture);
            var            opusBytes = mp3.GetOpusBytes();
            int            count     = 0;

            CancellationTokenSource tokenSource = new CancellationTokenSource();

            //get all the audio as Opus frames of 40 ms
            //send on 40 ms timer

            //when empty - disconnect
            //user timer for accurate sending
            var _timer = new Timer(() =>
            {
                if (!finished.IsCancellationRequested)
                {
                    if (count < opusBytes.Count)
                    {
                        udpVoiceHandler.Send(opusBytes[count], opusBytes[count].Length, freq, modulationBytes);
                        count++;

                        if (count % 50 == 0)
                        {
                            Logger.Info($"Playing audio - sent {count * 40}ms - {((float)count / (float)opusBytes.Count) * 100.0:F0}% ");
                        }
                    }
                    else
                    {
                        tokenSource.Cancel();
                    }
                }
                else
                {
                    Logger.Error("Client Disconnected");
                    tokenSource.Cancel();
                    return;
                }
            }, TimeSpan.FromMilliseconds(40));

            _timer.Start();

            //wait for cancel
            tokenSource.Token.WaitHandle.WaitOne();
            _timer.Stop();

            Logger.Info("Finished Sending Audio");
            finished.Cancel();
        }
        //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 ((_udpVoiceHandler != 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 (_udpVoiceHandler.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;
            }
        }
        private void WasapiCaptureOnDataAvailable(object sender, WaveInEventArgs e)
        {
            if (_resampler == null)
            {
                //create and use in the same thread or COM issues
                _resampler = new EventDrivenResampler(windowsN, _wasapiCapture.WaveFormat, new WaveFormat(AudioManager.INPUT_SAMPLE_RATE, 16, 1));
            }

            if (e.BytesRecorded > 0)
            {
                //Logger.Info($"Time: {_stopwatch.ElapsedMilliseconds} - Bytes: {e.BytesRecorded}");
                short[] resampledPCM16Bit = _resampler.Resample(e.Buffer, e.BytesRecorded);

                // Logger.Info($"Time: {_stopwatch.ElapsedMilliseconds} - Bytes: {resampledPCM16Bit.Length}");
                //fill sound buffer
                for (var i = 0; i < resampledPCM16Bit.Length; i++)
                {
                    _micInputQueue.Enqueue(resampledPCM16Bit[i]);
                }

                //read out the queue
                while (_micInputQueue.Count >= AudioManager.SEGMENT_FRAMES)
                {
                    short[] 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 ((_udpVoiceHandler != 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 (_udpVoiceHandler.Send(encoded, len))
                            {
                                //send audio so play over local too
                                _micWaveOutBuffer?.AddSamples(pcmBytes, 0, pcmBytes.Length);
                            }
                        }
                        else
                        {
                            Logger.Error($"Invalid Bytes for Encoding - {pcmShort.Length} 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);
                        }
                    }
                }
            }
        }
        //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();

            //fill sound buffer

            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 ((_udpVoiceHandler != 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);
                        _udpVoiceHandler.Send(encoded, len);
                    }
                    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;
            }
        }