Exemplo n.º 1
0
 public AudioContext(AudioFormat audioFormat, IAudioFilter resampler, IDtxFilter dtxFilter, IAudioTwoWayFilter speechEnhancer, IAudioEncoder encoder)
 {
     AudioFormat            = audioFormat;
     Resampler              = resampler;
     SpeechEnhancementStack = speechEnhancer;
     Encoder        = encoder;
     DtxFilter      = dtxFilter;
     ResampleBuffer = new byte[audioFormat.BytesPerFrame];
     CancelBuffer   = new short[audioFormat.SamplesPerFrame];
     EncodeBuffer   = new short[audioFormat.SamplesPerFrame];
     SendBuffer     = new short[audioFormat.SamplesPerFrame];
 }
Exemplo n.º 2
0
        private void TransmitAudio()
        {
            while (_audioEncodeResetEvent.WaitOne() && _isActive)
            {
                _audioEncodeResetEvent.Reset();

                while (_audioFrames.Count > 0)
                {
                    AudioFrame audioFrame;
                    lock (_audioFrames)
                    {
                        audioFrame = _audioFrames.Dequeue();
                    }
                    if (audioFrame == null)
                    {
                        continue;
                    }

                    // Cancel any echo onto the audioCancelBuffer.
                    var audioContext = audioFrame.AudioContext;
                    var frame        = audioFrame.Samples;
                    _lastSpeechEnhancementStack = audioContext.SpeechEnhancementStack;
                    LastSpeechEnhancementName   = _lastSpeechEnhancementStack.InstanceName;
                    _lastSpeechEnhancementStack.Write(frame);

                    bool moreFrames;
                    do
                    {
                        if (_lastSpeechEnhancementStack.Read(audioContext.CancelBuffer, out moreFrames))
                        {
                            if (!MediaConfig.PlayEchoCancelledSound)
                            {
                                Buffer.BlockCopy(frame, 0, audioContext.CancelBuffer, 0, frame.Length);
                            }
                            _cancelledStatistics.LatestFrame = audioContext.CancelBuffer;
                            if (OtherMembersInRoom)
                            {
                                PrepareAndSendAudioPacket(audioContext, audioContext.CancelBuffer);
                            }
                        }
                    } while (moreFrames);
                }
            }
        }
        public AudioContext GetAudioContext()
        {
            var resampler     = new ResampleFilter(rawAudioFormat, transmittedAudioFormat);
            var conferenceDtx = new DtxFilter(transmittedAudioFormat);

            IAudioTwoWayFilter enhancer = null;

            switch (enhancementStack)
            {
            case SpeechEnhancementStack.None:
                enhancer = new NullEchoCancelFilter(mediaConfig.ExpectedAudioLatency, mediaConfig.FilterLength, transmittedAudioFormat, AudioFormat.Default);
                break;

            case SpeechEnhancementStack.Speex:
                enhancer = new SpeexEchoCanceller2(mediaConfig, transmittedAudioFormat, AudioFormat.Default);
                break;

            case SpeechEnhancementStack.WebRtc:
                enhancer = new WebRtcFilter(mediaConfig.ExpectedAudioLatency, mediaConfig.FilterLength, transmittedAudioFormat, AudioFormat.Default, mediaConfig.EnableAec, mediaConfig.EnableDenoise, mediaConfig.EnableAgc);
                break;
            }

            IAudioEncoder encoder = null;

            switch (codecType)
            {
            case AudioCodecType.G711M:
                encoder = new G711MuLawEncoder(transmittedAudioFormat);
                break;

            case AudioCodecType.Speex:
                encoder = new SpeexEncoder(transmittedAudioFormat);
                break;
            }

            var ctx = new AudioContext(transmittedAudioFormat, resampler, conferenceDtx, enhancer, encoder);

            return(ctx);
        }
Exemplo n.º 4
0
        public SpeexPreprocessFilter(int samplesPerFrame, int samplesPerSecond, MediaConfig config, IAudioTwoWayFilter echoCancelFilter, string instanceName = "")
        {
            this.samplesPerSecond = samplesPerSecond;
#if SILVERLIGHT
            st           = this;
            InstanceName = instanceName;
            st.config    = config;

            speex_preprocess_state_init(samplesPerFrame, samplesPerSecond);

            AgcLevel        = 8000;
            DereverbEnabled = false;

            // ks 3/14/11 - VAD is supposedly a "kludge" right now, i.e., it's based on the overall power of the frame,
            // and that's it. See http://lists.xiph.org/pipermail/speex-dev/2006-March/004271.html for the "fix" that eventually
            // made its way into Speex as the "kludge". But turning it on seems to help, especially with AGC.
            VadEnabled = true;

            // ks 3/14/11 - Adjusted these, because the defaults amplify background noise too much.
            // See http://lists.xiph.org/pipermail/speex-dev/2007-May/005696.html
            AgcMaxGain = 15;                                     // Default is 30
            // NoiseSuppression = -30; // Default is -15. Recommended is -30, but that sounds awful in my environment.
            EchoState = echoCancelFilter as SpeexEchoCanceller2; // Will store null if the provided echo canceller isn't a Speex echo canceller, which is what we want.
#endif
        }