コード例 #1
0
        public static string Name(this Audio.Codecs.INetworkChatCodec codec)
        {
            string bitRate = codec.BitsPerSecond == -1 ? "VBR" : String.Format("{0:0.#}kbps", codec.BitsPerSecond / 1024.0);
            string text    = String.Format("{0} ({1})", codec.Name, bitRate);

            return(text);
        }
コード例 #2
0
        private void Start(Audio.Codecs.INetworkChatCodec codec)
        {
            ShouldTryRestartOutput = false;

            Stop();

            waveOut = GetWavePlayer();

            waveProvider = new BufferedWaveProvider(codec.RecordFormat);

            sampleChannel        = new SampleChannel(waveProvider, false);
            sampleStream         = new NotifyingSampleProvider(sampleChannel);
            sampleStream.Sample += (s, e) => aggregator.Add(e.Left);
            waveOut.Init(sampleStream);
            waveOut.Play();

            if (LevelManager == null)
            {
                LevelManager = new AudioLevelManagerDisconnected();
            }

            OutputFormat = codec.RecordFormat.ToString();
        }
コード例 #3
0
        public void HandleAudio(Audio.Codecs.CodecID codecid, byte[] encoded)
        {
            if (isDisposed)
            {
                return;
            }

            Audio.Codecs.INetworkChatCodec remoteCodec = Codecs.SingleOrDefault(m => m.CodecID == codecid);
            if (remoteCodec == null)
            {
                Console.WriteLine("Bad Audio Packet: Codec ID {0}", codecid);
                return;
            }
            if (codecid != LastCodec)
            {
                LastCodec = codecid;
                CodecName = remoteCodec.Name();
            }

            TimeSpan buffered  = waveOut == null ? TimeSpan.Zero : waveProvider.BufferedDuration;
            bool     isPlaying = buffered != TimeSpan.Zero;

            if (waveOut == null || waveProvider.WaveFormat != remoteCodec.RecordFormat || (!isPlaying && ShouldTryRestartOutput))
            {
                Start(remoteCodec);
            }
            else if (!isPlaying)
            {
                UnderRuns++;
            }

            if (buffered <= FrameDropThresholdMs)
            {
                byte[] decoded = remoteCodec.Decode(encoded, encoded.Length);
                int    length  = decoded.Length;

                if (!isPlaying && AudioOutWPF.shouldRampUnderruns)
                {
                    InputResampler.RampPCM16Volume(ref decoded, length, InputResampler.RampDirection.ZeroToFull);
                }

                var volume = LevelManager.LevelScalar;
                if (volume < 1.0f)
                {
                    InputResampler.ScalePCM16VolumeDb(ref decoded, length, volume);
                }

                if (length > 0 && ShouldDropSilence)
                {
                    int dropped = DropSilence(silenceThreshhold, ref decoded, ref length);
                    DroppedSilence += dropped;
                }
                else if (ShouldAddSilence && length > 5)
                {
                    bool silent = true;
                    for (int i = 0; i < 5; i += 2)
                    {
                        if (decoded[i + 1] != 0 || decoded[i] > addSilenceThreshold)
                        {
                            silent = false;
                            break;
                        }
                    }
                    if (silent)
                    {
                        var  silenceBytes = length / 4;
                        var  silence      = new byte[silenceBytes];
                        byte silenceLevel = (byte)(addSilenceThreshold / 2);
                        for (int i = 0; i < silenceBytes - 1; i += 2)
                        {
                            silence[i + 1] = 0;
                            silence[i]     = silenceLevel;
                        }
                        waveProvider.AddSamples(silence, 0, silenceBytes);
                        AddedSilence += length;
                    }
                }

                waveProvider.AddSamples(decoded, 0, length);
            }
            else
            {
                DroppedPackets++;
            }

            if (shouldUpdateDuration)
            {
                BufferedDuration     = buffered;
                shouldUpdateDuration = false;
            }
            LastReceived = DateTime.UtcNow;
        }
コード例 #4
0
        private void StartRecording(bool shouldTryUseExclusive = true)
        {
            if (waveIn != null)
            {
                StopRecording();
            }
            if (SelectedInputSource != null)
            {
                this.codec = SelectedCodec.Codec;

                var  deviceFormat    = WaveFormat.CreateIeeeFloatWaveFormat(codec.RecordFormat.SampleRate, codec.RecordFormat.Channels);
                bool canUseExclusive = false;

                if (SelectedInputSource.Provider == DeviceProvider.Wasapi)
                {
                    var mmdevice = SelectedInputSource.MMDevice;

                    WaveFormatExtensible bestMatch;
                    canUseExclusive = mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Exclusive, deviceFormat, out bestMatch);
                    if (canUseExclusive && shouldTryUseExclusive)
                    {
                        if (bestMatch != null)
                        {
                            deviceFormat = bestMatch;
                        }
                    }
                    else
                    {
                        mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Shared, deviceFormat, out bestMatch);
                        if (bestMatch != null)
                        {
                            deviceFormat = bestMatch;
                        }
                    }


                    if (deviceFormat.Encoding != WaveFormatEncoding.IeeeFloat && deviceFormat.BitsPerSample != 16)
                    {
                        deviceFormat = mmdevice.AudioClient.MixFormat;

                        if (mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Exclusive, codec.RecordFormat))
                        {
                            canUseExclusive = true;
                            deviceFormat    = codec.RecordFormat;
                        }
                        else if (mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Shared, codec.RecordFormat))
                        {
                            canUseExclusive = false;
                            deviceFormat    = codec.RecordFormat;
                        }
                        else
                        {
                            WaveFormat newFormat;
                            WaveFormat altWaveFormat  = new WaveFormat(deviceFormat.SampleRate, 16, deviceFormat.Channels);
                            WaveFormat altFloatFormat = WaveFormat.CreateIeeeFloatWaveFormat(mmdevice.AudioClient.MixFormat.SampleRate, mmdevice.AudioClient.MixFormat.Channels);

                            if (mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Exclusive, altFloatFormat))
                            {
                                canUseExclusive = true;
                                newFormat       = altFloatFormat;
                            }
                            else if (mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Exclusive, altWaveFormat))
                            {
                                canUseExclusive = true;
                                newFormat       = altWaveFormat;
                            }
                            else if (mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Shared, altFloatFormat))
                            {
                                canUseExclusive = false;
                                newFormat       = altFloatFormat;
                            }
                            else if (mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Shared, altWaveFormat))
                            {
                                canUseExclusive = false;
                                newFormat       = altWaveFormat;
                            }
                            else
                            {
                                throw new Exception("Device does not support 16bit PCM, or device is in use");
                            }

                            deviceFormat = newFormat;

                            Console.WriteLine("Initializing Wasapi\n  Device: {0}\n  Format: {1}\n  Mode: {2}\n  Resampling: {3}",
                                              mmdevice.FriendlyName,
                                              deviceFormat,
                                              canUseExclusive ? "Exclusive" : "Shared",
                                              deviceFormat.Equals(codec.RecordFormat) ? "NO" : "YES");
                        }
                    }

                    AudioClientShareMode shareMode;
                    if (canUseExclusive && shouldTryUseExclusive)
                    {
                        shareMode = AudioClientShareMode.Exclusive;
                    }
                    else
                    {
                        shareMode = AudioClientShareMode.Shared;
                    }

                    Guid audioSessionGuid = Guid.NewGuid();
                    try
                    {
                        mmdevice.AudioClient.Reset();
                    }
                    catch { }

                    BufferTargetMs = Math.Max(BufferTargetMs, mmdevice.MinBufferDurationMs);
                    var w = new WasapiCapture(mmdevice, BufferTargetMs);
                    w.RecordingStopped += wasapi_RecordingStopped;
                    waveIn              = w;
                    waveIn.WaveFormat   = deviceFormat;
                    w.ShareMode         = shareMode;

                    LevelManager = new AudioInLevelManager(w, mmdevice);
                }
                else
                {
                    Console.WriteLine("Initializing WaveIn{0}. Buffer:{1}ms Device:{2} Format:{3}", UseWaveEvent ? "Event" : "", BufferTargetMs, SelectedInputSource.WavDeviceNumber, deviceFormat);
                    if (UseWaveEvent)
                    {
                        var w = new WaveInEvent();
                        w.BufferMilliseconds = BufferTargetMs;
                        w.DeviceNumber       = SelectedInputSource.WavDeviceNumber;
                        LevelManager         = new AudioInLevelManager(w);
                        waveIn = w;
                    }
                    else
                    {
                        var w = new WaveIn();
                        w.BufferMilliseconds = BufferTargetMs;
                        w.DeviceNumber       = SelectedInputSource.WavDeviceNumber;
                        LevelManager         = new AudioInLevelManager(w);
                        waveIn = w;
                    }
                    waveIn.WaveFormat = deviceFormat;
                    canUseExclusive   = false;
                }

                waveIn.DataAvailable    += waveIn_DataAvailable;
                waveIn.RecordingStopped += waveIn_RecordingStopped;

                try
                {
                    waveIn.StartRecording();
                    ControlsEnabled = false;
                }
                catch (NAudio.MmException ex)
                {
                    Console.WriteLine("Audio Error: Couldn't open recording device\n{0}", ex.Message);
                    waveIn      = null;
                    IsRecording = false;
                }
                catch (ArgumentException ex)
                {
                    Console.WriteLine("Couldn't start recording: {0}", ex.Message);
                    IsRecording = false;
                    return;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Couldn't start recording: {0}", ex);
                    IsRecording = false;
                    return;
                }
            }
            else
            {
                IsRecording = false;
            }
        }
コード例 #5
0
        private void StartRecording(bool shouldTryUseExclusive = true)
        {
            if (waveIn != null)
                StopRecording();
            if (SelectedInputSource != null)
            {
                this.codec = SelectedCodec.Codec;

                var deviceFormat = WaveFormat.CreateIeeeFloatWaveFormat(codec.RecordFormat.SampleRate, codec.RecordFormat.Channels);
                bool canUseExclusive = false;

                if (SelectedInputSource.Provider == DeviceProvider.Wasapi)
                {
                    var mmdevice = SelectedInputSource.MMDevice;

                    WaveFormatExtensible bestMatch;
                    canUseExclusive = mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Exclusive, deviceFormat, out bestMatch);
                    if (canUseExclusive && shouldTryUseExclusive)
                    {
                        if (bestMatch != null)
                            deviceFormat = bestMatch;
                    }
                    else
                    {
                        mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Shared, deviceFormat, out bestMatch);
                        if (bestMatch != null)
                            deviceFormat = bestMatch;
                    }

                    if (deviceFormat.Encoding != WaveFormatEncoding.IeeeFloat && deviceFormat.BitsPerSample != 16)
                    {
                        deviceFormat = mmdevice.AudioClient.MixFormat;

                        if (mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Exclusive, codec.RecordFormat))
                        {
                            canUseExclusive = true;
                            deviceFormat = codec.RecordFormat;
                        }
                        else if (mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Shared, codec.RecordFormat))
                        {
                            canUseExclusive = false;
                            deviceFormat = codec.RecordFormat;
                        }
                        else
                        {
                            WaveFormat newFormat;
                            WaveFormat altWaveFormat = new WaveFormat(deviceFormat.SampleRate, 16, deviceFormat.Channels);
                            WaveFormat altFloatFormat = WaveFormat.CreateIeeeFloatWaveFormat(mmdevice.AudioClient.MixFormat.SampleRate, mmdevice.AudioClient.MixFormat.Channels);

                            if (mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Exclusive, altFloatFormat))
                            {
                                canUseExclusive = true;
                                newFormat = altFloatFormat;
                            }
                            else if (mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Exclusive, altWaveFormat))
                            {
                                canUseExclusive = true;
                                newFormat = altWaveFormat;
                            }
                            else if (mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Shared, altFloatFormat))
                            {
                                canUseExclusive = false;
                                newFormat = altFloatFormat;
                            }
                            else if (mmdevice.AudioClient.IsFormatSupported(AudioClientShareMode.Shared, altWaveFormat))
                            {
                                canUseExclusive = false;
                                newFormat = altWaveFormat;
                            }
                            else
                                throw new Exception("Device does not support 16bit PCM, or device is in use");

                            deviceFormat = newFormat;

                            Console.WriteLine("Initializing Wasapi\n  Device: {0}\n  Format: {1}\n  Mode: {2}\n  Resampling: {3}",
                                mmdevice.FriendlyName,
                                deviceFormat,
                                canUseExclusive ? "Exclusive" : "Shared",
                                deviceFormat.Equals(codec.RecordFormat) ? "NO" : "YES");
                        }
                    }

                    AudioClientShareMode shareMode;
                    if (canUseExclusive && shouldTryUseExclusive)
                        shareMode = AudioClientShareMode.Exclusive;
                    else
                        shareMode = AudioClientShareMode.Shared;

                    Guid audioSessionGuid = Guid.NewGuid();
                    try
                    {
                        mmdevice.AudioClient.Reset();
                    }
                    catch { }

                    BufferTargetMs = Math.Max(BufferTargetMs, mmdevice.MinBufferDurationMs);
                    var w = new WasapiCapture(mmdevice, BufferTargetMs);
                    w.RecordingStopped += wasapi_RecordingStopped;
                    waveIn = w;
                    waveIn.WaveFormat = deviceFormat;
                    w.ShareMode = shareMode;

                    LevelManager = new AudioInLevelManager(w, mmdevice);
                }
                else
                {
                    Console.WriteLine("Initializing WaveIn{0}. Buffer:{1}ms Device:{2} Format:{3}", UseWaveEvent ? "Event" : "", BufferTargetMs, SelectedInputSource.WavDeviceNumber, deviceFormat);
                    if (UseWaveEvent)
                    {
                        var w = new WaveInEvent();
                        w.BufferMilliseconds = BufferTargetMs;
                        w.DeviceNumber = SelectedInputSource.WavDeviceNumber;
                        LevelManager = new AudioInLevelManager(w);
                        waveIn = w;
                    }
                    else
                    {
                        var w = new WaveIn();
                        w.BufferMilliseconds = BufferTargetMs;
                        w.DeviceNumber = SelectedInputSource.WavDeviceNumber;
                        LevelManager = new AudioInLevelManager(w);
                        waveIn = w;
                    }
                    waveIn.WaveFormat = deviceFormat;
                    canUseExclusive = false;
                }

                waveIn.DataAvailable += waveIn_DataAvailable;
                waveIn.RecordingStopped += waveIn_RecordingStopped;

                try
                {
                    waveIn.StartRecording();
                    ControlsEnabled = false;
                }
                catch (NAudio.MmException ex)
                {
                    Console.WriteLine("Audio Error: Couldn't open recording device\n{0}", ex.Message);
                    waveIn = null;
                    IsRecording = false;
                }
                catch (ArgumentException ex)
                {
                    Console.WriteLine("Couldn't start recording: {0}", ex.Message);
                    IsRecording = false;
                    return;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Couldn't start recording: {0}", ex);
                    IsRecording = false;
                    return;
                }
            }
            else
                IsRecording = false;
        }
コード例 #6
0
        private void LoadSettings()
        {
            var settings = Settings.Container;

            string strCodec = settings.Codec;
            string strInputDevice = settings.InputDevice;

            var codecs = comboBoxCodecs.Items.OfType<CodecModel>();
            if (codecs.Any())
            {
                CodecModel selectCodecItem = null;
                if (!string.IsNullOrWhiteSpace(strCodec))
                {
                    selectCodecItem = codecs.Where(m => m.Text == strCodec).FirstOrDefault();
                }
                SelectedCodec = selectCodecItem ?? codecs.First();
                this.codec = SelectedCodec.Codec;
            }

            if (!string.IsNullOrWhiteSpace(strInputDevice))
            {
                var selectInputDevice = InputList.Where(m => m.ToString() == strInputDevice).FirstOrDefault();
                if (selectInputDevice != null)
                    SelectedInputSource = selectInputDevice;
            }
            else
            {
                SelectedInputSource = InputList.FirstOrDefault();
                if (comboInputGroups.Items.Count > 0)
                    comboInputGroups.SelectedIndex = 0;
            }

            BufferTargetMs = settings.InputLatency;

            UseWaveEvent = settings.UseWaveInEvent;
        }