예제 #1
0
 public AudioReceiver()
 {
     opusDecoder      = new OpusDecoder(KinectSpeaker.KH_SAMPLE_RATE, KinectSpeaker.KH_CHANNEL_COUNT);
     lastAudioFrameId = -1;
 }
예제 #2
0
        public void StartEncoding(int mic, MMDevice speakers, string guid, InputDeviceManager inputManager,
                                  IPAddress ipAddress, int port, MMDevice micOutput, VOIPConnectCallback voipConnectCallback)
        {
            _stop = false;


            try
            {
                _micInputQueue.Clear();

                InitMixers();

                InitAudioBuffers();

                //Audio manager should start / stop and cleanup based on connection successfull and disconnect
                //Should use listeners to synchronise all the state

                _waveOut = new WasapiOut(speakers, AudioClientShareMode.Shared, true, 40);

                //add final volume boost to all mixed audio
                _volumeSampleProvider = new VolumeSampleProviderWithPeak(_clientAudioMixer,
                                                                         (peak => SpeakerMax = (float)VolumeConversionHelper.ConvertFloatToDB(peak)));
                _volumeSampleProvider.Volume = SpeakerBoost;

                if (speakers.AudioClient.MixFormat.Channels == 1)
                {
                    if (_volumeSampleProvider.WaveFormat.Channels == 2)
                    {
                        _waveOut.Init(_volumeSampleProvider.ToMono());
                    }
                    else
                    {
                        //already mono
                        _waveOut.Init(_volumeSampleProvider);
                    }
                }
                else
                {
                    if (_volumeSampleProvider.WaveFormat.Channels == 1)
                    {
                        _waveOut.Init(_volumeSampleProvider.ToStereo());
                    }
                    else
                    {
                        //already stereo
                        _waveOut.Init(_volumeSampleProvider);
                    }
                }
                _waveOut.Play();

                //opus
                _encoder = OpusEncoder.Create(INPUT_SAMPLE_RATE, 1, Application.Voip);
                _encoder.ForwardErrorCorrection = false;
                _decoder = OpusDecoder.Create(INPUT_SAMPLE_RATE, 1);
                _decoder.ForwardErrorCorrection = false;

                //speex
                _speex = new Preprocessor(AudioManager.SEGMENT_FRAMES, AudioManager.INPUT_SAMPLE_RATE);
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Error starting audio Output - Quitting! " + ex.Message);


                ShowOutputError("Problem Initialising Audio Output!");


                Environment.Exit(1);
            }

            if (micOutput != null) // && micOutput !=speakers
            {
                //TODO handle case when they're the same?

                try
                {
                    _micWaveOut = new WasapiOut(micOutput, AudioClientShareMode.Shared, true, 40);

                    _micWaveOutBuffer           = new BufferedWaveProvider(new WaveFormat(AudioManager.INPUT_SAMPLE_RATE, 16, 1));
                    _micWaveOutBuffer.ReadFully = true;
                    _micWaveOutBuffer.DiscardOnBufferOverflow = true;

                    var sampleProvider = _micWaveOutBuffer.ToSampleProvider();

                    if (micOutput.AudioClient.MixFormat.Channels == 1)
                    {
                        if (sampleProvider.WaveFormat.Channels == 2)
                        {
                            _micWaveOut.Init(new RadioFilter(sampleProvider.ToMono()));
                        }
                        else
                        {
                            //already mono
                            _micWaveOut.Init(new RadioFilter(sampleProvider));
                        }
                    }
                    else
                    {
                        if (sampleProvider.WaveFormat.Channels == 1)
                        {
                            _micWaveOut.Init(new RadioFilter(sampleProvider.ToStereo()));
                        }
                        else
                        {
                            //already stereo
                            _micWaveOut.Init(new RadioFilter(sampleProvider));
                        }
                    }

                    _micWaveOut.Play();
                }
                catch (Exception ex)
                {
                    Logger.Error(ex, "Error starting mic audio Output - Quitting! " + ex.Message);

                    ShowOutputError("Problem Initialising Mic Audio Output!");


                    Environment.Exit(1);
                }
            }


            if (mic != -1)
            {
                try
                {
                    _waveIn = new WaveIn(WaveCallbackInfo.FunctionCallback())
                    {
                        BufferMilliseconds = INPUT_AUDIO_LENGTH_MS,
                        DeviceNumber       = mic,
                    };

                    _waveIn.NumberOfBuffers = 2;
                    _waveIn.DataAvailable  += _waveIn_DataAvailable;
                    _waveIn.WaveFormat      = new WaveFormat(INPUT_SAMPLE_RATE, 16, 1);

                    _udpVoiceHandler =
                        new UdpVoiceHandler(_clientsList, guid, ipAddress, port, _decoder, this, inputManager, voipConnectCallback);
                    var voiceSenderThread = new Thread(_udpVoiceHandler.Listen);

                    voiceSenderThread.Start();

                    _waveIn.StartRecording();


                    MessageHub.Instance.Subscribe <SRClient>(RemoveClientBuffer);
                }
                catch (Exception ex)
                {
                    Logger.Error(ex, "Error starting audio Input - Quitting! " + ex.Message);

                    ShowInputError("Problem initialising Audio Input!");

                    Environment.Exit(1);
                }
            }
        }
예제 #3
0
파일: AudioOPUS.cs 프로젝트: zxc120/GARbro
        public override SoundInput TryOpen(IBinaryStream file)
        {
            if (file.Signature != 0x5367674F) // 'OggS'
            {
                return(null);
            }
            var header     = file.ReadHeader(0x1C);
            int table_size = header[0x1A];

            if (table_size < 1)
            {
                return(null);
            }
            int header_size = header[0x1B];

            if (header_size < 0x10)
            {
                return(null);
            }
            int header_pos = 0x1B + table_size;

            header = file.ReadHeader(header_pos + header_size);
            if (!header.AsciiEqual(header_pos, "OpusHead"))
            {
                return(null);
            }
            int channels = header[header_pos + 9];
//            int rate = header.ToInt32 (header_pos+0xC);
            int rate = 48000;

            file.Position = 0;
            var decoder = OpusDecoder.Create(rate, channels);
            var ogg_in  = new OpusOggReadStream(decoder, file.AsStream);
            var pcm     = new MemoryStream();

            try
            {
                using (var output = new BinaryWriter(pcm, System.Text.Encoding.UTF8, true))
                {
                    while (ogg_in.HasNextPacket)
                    {
                        var packet = ogg_in.DecodeNextPacket();
                        if (packet != null)
                        {
                            for (int i = 0; i < packet.Length; ++i)
                            {
                                output.Write(packet[i]);
                            }
                        }
                    }
                }
                var format = new WaveFormat
                {
                    FormatTag        = 1,
                    Channels         = (ushort)channels,
                    SamplesPerSecond = (uint)rate,
                    BitsPerSample    = 16,
                };
                format.BlockAlign            = (ushort)(format.Channels * format.BitsPerSample / 8);
                format.AverageBytesPerSecond = format.SamplesPerSecond * format.BlockAlign;
                pcm.Position = 0;
                var sound = new RawPcmInput(pcm, format);
                file.Dispose();
                return(sound);
            }
            catch
            {
                pcm.Dispose();
                throw;
            }
        }
예제 #4
0
 public MicrophoneHandler(SoundEngine eng)
 {
     Engine  = eng;
     Encoder = OpusEncoder.Create(SampleRate, 1, Application.Voip);
     Decoder = OpusDecoder.Create(SampleRate, 1);
 }
예제 #5
0
 public void Open(VoiceInfo i)
 {
     decoder = new OpusDecoder((SamplingRate)i.SamplingRate, (Channels)i.Channels);
 }
예제 #6
0
        internal static int run_test2(bool no_fuzz)
        {
            byte[]        mapping /*[256]*/ = { 0, 1, 255 };
            byte[]        db62 = new byte[36];
            int           i;
            int           rc, j;
            BoxedValueInt err = new BoxedValueInt(0);
            OpusMSEncoder MSenc;
            OpusMSDecoder MSdec;
            OpusMSDecoder MSdec_err;

            OpusDecoder[] dec_err = new OpusDecoder[10];
            short[]       inbuf;
            short[]       out2buf;
            byte[]        packet = new byte[MAX_PACKET + 257];
            uint          enc_final_range;
            uint          dec_final_range;
            int           count;

            inbuf   = new short[SAMPLES * 2];
            out2buf = new short[MAX_FRAME_SAMP * 3];
            if (inbuf == null || out2buf == null)
            {
                test_failed();
            }

            generate_music(inbuf.GetPointer(), SAMPLES);

            for (i = 0; i < 2; i++)
            {
                try
                {
                    MSenc = OpusMSEncoder.Create(8000, 2, 2, 0, mapping, OpusApplication.OPUS_APPLICATION_UNIMPLEMENTED); test_failed();
                }
                catch (ArgumentException) { }
                try
                {
                    MSenc = OpusMSEncoder.Create(8000, 0, 1, 0, mapping, OpusApplication.OPUS_APPLICATION_VOIP); test_failed();
                }
                catch (ArgumentException) { }
                try
                {
                    MSenc = OpusMSEncoder.Create(44100, 2, 2, 0, mapping, OpusApplication.OPUS_APPLICATION_VOIP); test_failed();
                }
                catch (ArgumentException) { }
                try
                {
                    MSenc = OpusMSEncoder.Create(8000, 2, 2, 3, mapping, OpusApplication.OPUS_APPLICATION_VOIP); test_failed();
                }
                catch (ArgumentException) { }
                try
                {
                    MSenc = OpusMSEncoder.Create(8000, 2, -1, 0, mapping, OpusApplication.OPUS_APPLICATION_VOIP); test_failed();
                }
                catch (ArgumentException) { }
                try
                {
                    MSenc = OpusMSEncoder.Create(8000, 256, 2, 0, mapping, OpusApplication.OPUS_APPLICATION_VOIP); test_failed();
                }
                catch (ArgumentException) { }
            }

            MSenc = OpusMSEncoder.Create(8000, 2, 2, 0, mapping, OpusApplication.OPUS_APPLICATION_AUDIO);
            if (err.Val != OpusError.OPUS_OK || MSenc == null)
            {
                test_failed();
            }

            MSdec = new OpusMSDecoder(48000, 2, 2, 0, mapping);
            if (err.Val != OpusError.OPUS_OK || MSdec == null)
            {
                test_failed();
            }

            MSdec_err = new OpusMSDecoder(48000, 3, 2, 0, mapping);
            if (err.Val != OpusError.OPUS_OK || MSdec_err == null)
            {
                test_failed();
            }

            /*Some multistream encoder API tests*/
            i = MSenc.Bitrate;
            i = MSenc.LSBDepth;
            if (i < 16)
            {
                test_failed();
            }

            {
                OpusEncoder tmp_enc;
                tmp_enc = MSenc.GetMultistreamEncoderState(1);
                if (tmp_enc == null)
                {
                    test_failed();
                }
                j = tmp_enc.LSBDepth;
                if (i != j)
                {
                    test_failed();
                }
                try
                {
                    MSenc.GetMultistreamEncoderState(2);
                    test_failed();
                }
                catch (ArgumentException) { }
            }

            OpusMode[] modes = { OpusMode.MODE_SILK_ONLY, OpusMode.MODE_SILK_ONLY, OpusMode.MODE_SILK_ONLY, OpusMode.MODE_SILK_ONLY, OpusMode.MODE_SILK_ONLY, OpusMode.MODE_SILK_ONLY, OpusMode.MODE_SILK_ONLY, OpusMode.MODE_SILK_ONLY, OpusMode.MODE_CELT_ONLY, OpusMode.MODE_CELT_ONLY, OpusMode.MODE_CELT_ONLY, OpusMode.MODE_CELT_ONLY, OpusMode.MODE_CELT_ONLY, OpusMode.MODE_CELT_ONLY, OpusMode.MODE_CELT_ONLY, OpusMode.MODE_CELT_ONLY };
            int[]      rates = { 4000, 12000, 32000, 8000, 16000, 32000, 48000, 88000, 4000, 12000, 32000, 8000, 16000, 32000, 48000, 88000 };
            int[]      frame = { 160 * 1, 160, 80, 160, 160, 80, 40, 20, 160 * 1, 160, 80, 160, 160, 80, 40, 20 };

            for (rc = 0; rc < 3; rc++)
            {
                MSenc.UseVBR            = (rc < 2);
                MSenc.UseConstrainedVBR = (rc == 1);
                MSenc.UseInbandFEC      = (rc == 0);
                for (j = 0; j < 16; j++)
                {
                    int rate;
                    MSenc.UseInbandFEC = (rc == 0 && j == 1);
                    MSenc.ForceMode    = (modes[j]);
                    rate          = rates[j] + ((int)fast_rand() % rates[j]);
                    MSenc.UseDTX  = ((fast_rand() & 1U) != 0);
                    MSenc.Bitrate = (rate);
                    count         = i = 0;
                    do
                    {
                        int  len, out_samples, frame_size;
                        bool loss;
                        bool pred = MSenc.PredictionDisabled;
                        MSenc.PredictionDisabled = ((int)(fast_rand() & 15) < (pred ? 11 : 4));
                        frame_size              = frame[j];
                        MSenc.Complexity        = ((count >> 2) % 11);
                        MSenc.PacketLossPercent = (((int)fast_rand() & 15) & ((int)fast_rand() % 15));
                        if ((fast_rand() & 255) == 0)
                        {
                            MSenc.ResetState();
                            MSdec.ResetState();
                            if ((fast_rand() & 3) != 0)
                            {
                                MSdec_err.ResetState();
                            }
                        }
                        if ((fast_rand() & 255) == 0)
                        {
                            MSdec_err.ResetState();
                        }
                        len = MSenc.EncodeMultistream(inbuf, i << 1, frame_size, packet, 0, MAX_PACKET);
                        if (len < 0 || len > MAX_PACKET)
                        {
                            test_failed();
                        }
                        enc_final_range = MSenc.FinalRange;
                        if ((fast_rand() & 3) == 0)
                        {
                            if (OpusRepacketizer.PadMultistreamPacket(packet, 0, len, len + 1, 2) != OpusError.OPUS_OK)
                            {
                                test_failed();
                            }
                            len++;
                        }
                        if ((fast_rand() & 7) == 0)
                        {
                            if (OpusRepacketizer.PadMultistreamPacket(packet, 0, len, len + 256, 2) != OpusError.OPUS_OK)
                            {
                                test_failed();
                            }
                            len += 256;
                        }
                        //if ((fast_rand() & 3) == 0)
                        //{
                        //    len = Repacketizer.opus_multistream_packet_unpad(packet, len, 2);
                        //    if (len < 1) test_failed();
                        //}
                        out_samples = MSdec.DecodeMultistream(packet, 0, len, out2buf, 0, MAX_FRAME_SAMP, 0);
                        if (out_samples != frame_size * 6)
                        {
                            test_failed();
                        }
                        dec_final_range = MSdec.FinalRange;
                        if (enc_final_range != dec_final_range)
                        {
                            test_failed();
                        }
                        /*LBRR decode*/
                        loss        = (fast_rand() & 63) == 0;
                        out_samples = MSdec_err.DecodeMultistream(packet, 0, loss ? 0 : len, out2buf, 0, frame_size * 6, ((fast_rand() & 3) != 0) ? 1 : 0);
                        if (out_samples != (frame_size * 6))
                        {
                            test_failed();
                        }
                        i += frame_size;
                        count++;
                    } while (i < (SSAMPLES / 12 - MAX_FRAME_SAMP));
                    Console.WriteLine("    Mode {0} NB dual-mono MS encode {1}, {2} bps OK.", mstrings[(int)modes[j] - (int)OpusMode.MODE_SILK_ONLY], rc == 0 ? " VBR" : rc == 1 ? "CVBR" : " CBR", rate);
                }
            }

            return(0);
        }
예제 #7
0
        internal static int run_test1(bool no_fuzz)
        {
            byte[]        mapping /*[256]*/ = { 0, 1, 255 };
            byte[]        db62 = new byte[36];
            int           i;
            int           rc, j;
            BoxedValueInt err = new BoxedValueInt();
            OpusEncoder   enc;
            OpusDecoder   dec;

            OpusDecoder[]   dec_err = new OpusDecoder[10];
            Pointer <short> inbuf;
            Pointer <short> outbuf;
            Pointer <short> out2buf;
            //int bitrate_bps;
            Pointer <byte> packet = Pointer.Malloc <byte>(MAX_PACKET + 257);
            uint           enc_final_range;
            uint           dec_final_range;
            //int fswitch;
            //int fsize;
            int count;

            /*FIXME: encoder api tests, fs!=48k, mono, VBR*/

            Console.WriteLine("  Encode+Decode tests.");

            enc = OpusEncoder.Create(48000, 2, OpusApplication.OPUS_APPLICATION_VOIP);
            if (err.Val != OpusError.OPUS_OK || enc == null)
            {
                test_failed();
            }

            dec = OpusDecoder.Create(48000, 2);
            if (err.Val != OpusError.OPUS_OK || dec == null)
            {
                test_failed();
            }

            // fixme: this tests assign() performed on a decoder struct, which doesn't exist
            //dec_err[0] = (OpusDecoder*)malloc(OpusDecoder_get_size(2));
            //memcpy(dec_err[0], dec, OpusDecoder_get_size(2));
            dec_err[0] = OpusDecoder.Create(48000, 2);
            dec_err[1] = OpusDecoder.Create(48000, 1);
            dec_err[2] = OpusDecoder.Create(24000, 2);
            dec_err[3] = OpusDecoder.Create(24000, 1);
            dec_err[4] = OpusDecoder.Create(16000, 2);
            dec_err[5] = OpusDecoder.Create(16000, 1);
            dec_err[6] = OpusDecoder.Create(12000, 2);
            dec_err[7] = OpusDecoder.Create(12000, 1);
            dec_err[8] = OpusDecoder.Create(8000, 2);
            dec_err[9] = OpusDecoder.Create(8000, 1);
            for (i = 1; i < 10; i++)
            {
                if (dec_err[i] == null)
                {
                    test_failed();
                }
            }

            //{
            //    OpusEncoder* enccpy;
            //    /*The opus state structures contain no pointers and can be freely copied*/
            //    enccpy = (OpusEncoder*)malloc(opus_encoder_get_size(2));
            //    memcpy(enccpy, enc, opus_encoder_get_size(2));
            //    memset(enc, 255, opus_encoder_get_size(2));
            //    opus_encoder_destroy(enc);
            //    enc = enccpy;
            //}

            inbuf   = Pointer.Malloc <short>(SAMPLES * 2);
            outbuf  = Pointer.Malloc <short>(SAMPLES * 2);
            out2buf = Pointer.Malloc <short>(MAX_FRAME_SAMP * 3);
            if (inbuf == null || outbuf == null || out2buf == null)
            {
                test_failed();
            }

            generate_music(inbuf, SAMPLES);

            ///*   FILE *foo;
            //foo = fopen("foo.sw", "wb+");
            //fwrite(inbuf, 1, SAMPLES*2*2, foo);
            //fclose(foo);*/

            enc.Bandwidth = (OpusBandwidth.OPUS_BANDWIDTH_AUTO);

            for (rc = 0; rc < 3; rc++)
            {
                enc.UseVBR            = (rc < 2);
                enc.UseConstrainedVBR = (rc == 1);
                enc.UseInbandFEC      = (rc == 0);

                int[] modes = { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2 };
                int[] rates = { 6000, 12000, 48000, 16000, 32000, 48000, 64000, 512000, 13000, 24000, 48000, 64000, 96000 };
                int[] frame = { 960 * 2, 960, 480, 960, 960, 960, 480, 960 * 3, 960 * 3, 960, 480, 240, 120 };

                for (j = 0; j < modes.Length; j++)
                {
                    int rate;
                    rate  = rates[j] + (int)fast_rand() % rates[j];
                    count = i = 0;
                    do
                    {
                        OpusBandwidth bw;
                        int           len, out_samples, frame_size;
                        frame_size = frame[j];
                        if ((fast_rand() & 255) == 0)
                        {
                            enc.ResetState();
                            dec.ResetState();

                            if ((fast_rand() & 1) != 0)
                            {
                                dec_err[fast_rand() & 1].ResetState();
                            }
                        }

                        if ((fast_rand() & 127) == 0)
                        {
                            dec_err[fast_rand() & 1].ResetState();
                        }

                        if (fast_rand() % 10 == 0)
                        {
                            int complex = (int)(fast_rand() % 11);
                            enc.Complexity = (complex);
                        }

                        if (fast_rand() % 50 == 0)
                        {
                            dec.ResetState();
                        }

                        enc.UseInbandFEC      = (rc == 0);
                        enc.ForceMode         = (OpusMode.MODE_SILK_ONLY + modes[j]);
                        enc.UseDTX            = ((fast_rand() & 1) != 0);
                        enc.Bitrate           = (rate);
                        enc.ForceChannels     = (rates[j] >= 64000 ? 2 : 1);
                        enc.Complexity        = ((count >> 2) % 11);
                        enc.PacketLossPercent = ((int)((fast_rand() & 15) & (fast_rand() % 15)));

                        bw = modes[j] == 0 ? OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND + (int)(fast_rand() % 3) :
                             modes[j] == 1 ? OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND + (int)(fast_rand() & 1) :
                             OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND + (int)(fast_rand() % 5);

                        if (modes[j] == 2 && bw == OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND)
                        {
                            bw += 3;
                        }
                        enc.Bandwidth = (bw);
                        len           = enc.Encode(inbuf.Data, i << 1, frame_size, packet.Data, 0, MAX_PACKET);
                        if (len < 0 || len > MAX_PACKET)
                        {
                            test_failed();
                        }
                        enc_final_range = enc.FinalRange;
                        if ((fast_rand() & 3) == 0)
                        {
                            if (OpusRepacketizer.PadPacket(packet.Data, packet.Offset, len, len + 1) != OpusError.OPUS_OK)
                            {
                                test_failed();
                            }
                            len++;
                        }
                        if ((fast_rand() & 7) == 0)
                        {
                            if (OpusRepacketizer.PadPacket(packet.Data, packet.Offset, len, len + 256) != OpusError.OPUS_OK)
                            {
                                test_failed();
                            }
                            len += 256;
                        }
                        if ((fast_rand() & 3) == 0)
                        {
                            len = OpusRepacketizer.UnpadPacket(packet.Data, packet.Offset, len);
                            if (len < 1)
                            {
                                test_failed();
                            }
                        }
                        out_samples = dec.Decode(packet.Data, 0, len, outbuf.Data, i << 1, MAX_FRAME_SAMP, false);
                        if (out_samples != frame_size)
                        {
                            test_failed();
                        }
                        dec_final_range = dec.FinalRange;
                        if (enc_final_range != dec_final_range)
                        {
                            test_failed();
                        }
                        /*LBRR decode*/
                        out_samples = dec_err[0].Decode(packet.Data, 0, len, out2buf.Data, 0, frame_size, ((int)fast_rand() & 3) != 0);
                        if (out_samples != frame_size)
                        {
                            test_failed();
                        }
                        out_samples = dec_err[1].Decode(packet.Data, 0, (fast_rand() & 3) == 0 ? 0 : len, out2buf.Data, 0, /*MAX_FRAME_SAMP*/ frame_size, ((int)fast_rand() & 7) != 0);
                        if (out_samples < 120)
                        {
                            test_failed();
                        }
                        i += frame_size;
                        count++;
                    } while (i < (SSAMPLES - MAX_FRAME_SAMP));
                    Console.WriteLine("    Mode {0} FB encode {1}, {2} bps OK.", mstrings[modes[j]], rc == 0 ? " VBR" : rc == 1 ? "CVBR" : " CBR", rate);
                }
            }

            //if (opus_encoder_ctl(enc, OPUS_RESET_STATE) != OpusError.OPUS_OK) test_failed();
            //opus_encoder_destroy(enc);
            //if (opus_multistream_encoder_ctl(MSenc, OPUS_RESET_STATE) != OpusError.OPUS_OK) test_failed();
            //opus_multistream_encoder_destroy(MSenc);
            //if (OpusDecoder_ctl(dec, OPUS_RESET_STATE) != OpusError.OPUS_OK) test_failed();
            //OpusDecoder_destroy(dec);
            //if (opus_multistream_decoder_ctl(MSdec, OPUS_RESET_STATE) != OpusError.OPUS_OK) test_failed();

            return(0);
        }
예제 #8
0
        public void StartPreview(bool windowsN)
        {
            this.windowsN = windowsN;
            try
            {
                MMDevice speakers = null;
                if (_audioOutputSingleton.SelectedAudioOutput.Value == null)
                {
                    speakers = WasapiOut.GetDefaultAudioEndpoint();
                }
                else
                {
                    speakers = (MMDevice)_audioOutputSingleton.SelectedAudioOutput.Value;
                }

                _waveOut = new WasapiOut(speakers, AudioClientShareMode.Shared, true, 80, windowsN);

                _buffBufferedWaveProvider =
                    new BufferedWaveProvider(new WaveFormat(AudioManager.OUTPUT_SAMPLE_RATE, 16, 1));
                _buffBufferedWaveProvider.ReadFully = true;
                _buffBufferedWaveProvider.DiscardOnBufferOverflow = true;

                RadioFilter filter = new RadioFilter(_buffBufferedWaveProvider.ToSampleProvider());

                //add final volume boost to all mixed audio
                _volumeSampleProvider = new VolumeSampleProviderWithPeak(filter,
                                                                         (peak => SpeakerMax = (float)VolumeConversionHelper.ConvertFloatToDB(peak)));
                _volumeSampleProvider.Volume = SpeakerBoost;

                if (speakers.AudioClient.MixFormat.Channels == 1)
                {
                    if (_volumeSampleProvider.WaveFormat.Channels == 2)
                    {
                        _waveOut.Init(_volumeSampleProvider.ToMono());
                    }
                    else
                    {
                        //already mono
                        _waveOut.Init(_volumeSampleProvider);
                    }
                }
                else
                {
                    if (_volumeSampleProvider.WaveFormat.Channels == 1)
                    {
                        _waveOut.Init(_volumeSampleProvider.ToStereo());
                    }
                    else
                    {
                        //already stereo
                        _waveOut.Init(_volumeSampleProvider);
                    }
                }

                _waveOut.Play();
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Error starting audio Output - Quitting! " + ex.Message);

                ShowOutputError("Problem Initialising Audio Output!");

                Environment.Exit(1);
            }

            try
            {
                _speex = new Preprocessor(AudioManager.MIC_SEGMENT_FRAMES, AudioManager.MIC_SAMPLE_RATE);
                //opus
                _encoder = OpusEncoder.Create(AudioManager.MIC_SAMPLE_RATE, 1,
                                              FragLabs.Audio.Codecs.Opus.Application.Voip);
                _encoder.ForwardErrorCorrection = false;
                _decoder = OpusDecoder.Create(AudioManager.OUTPUT_SAMPLE_RATE, 1);
                _decoder.ForwardErrorCorrection = false;
                _decoder.MaxDataBytes           = AudioManager.OUTPUT_SAMPLE_RATE * 4;

                var device = (MMDevice)_audioInputSingleton.SelectedAudioInput.Value;

                if (device == null)
                {
                    device = WasapiCapture.GetDefaultCaptureDevice();
                }

                device.AudioEndpointVolume.Mute = false;

                _wasapiCapture                   = new WasapiCapture(device, true);
                _wasapiCapture.ShareMode         = AudioClientShareMode.Shared;
                _wasapiCapture.DataAvailable    += WasapiCaptureOnDataAvailable;
                _wasapiCapture.RecordingStopped += WasapiCaptureOnRecordingStopped;

                //debug wave file
                //      _waveFile = new WaveFileWriter(@"C:\Temp\Test-Preview.wav", new WaveFormat(AudioManager.INPUT_SAMPLE_RATE, 16, 1));

                _wasapiCapture.StartRecording();
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Error starting audio Input - Quitting! " + ex.Message);
                ShowInputError();

                Environment.Exit(1);
            }
        }