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(); }
private void StopRecording() { if (waveIn != null) { if (waveIn is WasapiCapture) ((WasapiCapture)waveIn).RecordingStopped -= wasapi_RecordingStopped; waveIn.DataAvailable -= waveIn_DataAvailable; try { waveIn.StopRecording(); } catch (NAudio.MmException ex) { Console.WriteLine(ex.Message); } try { Trace.WriteLine("Disposing waveIn"); waveIn.Dispose(); Trace.WriteLine("waveIn disposed"); } catch { Trace.WriteLine("waveIn NOT disposed"); } waveIn = null; } if (LevelManager != null) { LevelManager.Dispose(); LevelManager = null; } ControlsEnabled = true; }
private void InitLevelManager() { var output = SelectedOutput; if (output != null) { switch (output.Provider) { case DeviceProvider.Wasapi: LevelManager = new AudioOutLevelManager(output.MMDevice); break; default: LevelManager = null; break; } } else LevelManager = null; }
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; }