Example #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Pipe"/> class.
        /// </summary>
        /// <param name="input">Audio device from which to capture audio.</param>
        /// <param name="outputs">Audio devices to which the captured audio should be output.</param>
        /// <param name="latency">Latency of the pipe in milliseconds. </param>
        public MultiOutputAudioPipe(MMDevice input, MultiChannelList <MMDevice> outputs, int latency = DefaultLatency)
        {
            foreach (var output in outputs)
            {
                if (DeviceService.Equals(input, output))
                {
                    throw new ArgumentException($"{nameof(input)} and {nameof(output)} cannot both be {input.FriendlyName}");
                }
            }

            if (latency < MinLatency)
            {
                throw new ArgumentException("Latency is too low.", nameof(latency));
            }

            InputDevice   = input;
            OutputDevices = outputs;

            try
            {
                inputCapture = new WasapiLoopbackCapture(InputDevice);
            }
            catch (COMException ex)
            {
                throw new PipeInitException(ex.HResult, InputDevice);
            }

            waveBuffers      = new MultiChannelList <BufferedWaveProvider>(OutputDevices.Select(device => new BufferedWaveProvider(inputCapture.WaveFormat)).ToList());
            waveMultiplexers = new MultiChannelList <MultiplexingWaveProvider>(waveBuffers.Select(waveBuffer => new MultiplexingWaveProvider(new BufferedWaveProvider[] { waveBuffer }, 1)));

            waveMultiplexers.RightDevice.ConnectInputToOutput(0, 0);
            waveMultiplexers.LeftDevice.ConnectInputToOutput(1, 0);

            inputCapture.DataAvailable += (sender, e) =>
            {
                waveBuffers.AsParallel().ForAll(buffer => buffer.AddSamples(e.Buffer, 0, e.BytesRecorded));
            };

            try
            {
                outputDevices = new MultiChannelList <WasapiOut>(OutputDevices.AsParallel().Select(device => new WasapiOut(device, AudioClientShareMode.Shared, true, latency)).ToList());
                outputDevices.Zip(waveMultiplexers, (device, multiplexer) => new { Device = device, Multiplexer = multiplexer }).AsParallel().ForAll(z => z.Device.Init(z.Multiplexer));
            }
            catch (COMException ex)
            {
                throw new PipeInitException(ex.HResult, null);
            }
        }
Example #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Pipe"/> class.
        /// </summary>
        /// <param name="input">Audio device from which to capture audio.</param>
        /// <param name="output">Audio device to which the captured audio should be output.</param>
        /// <param name="latency">Latency of the pipe in milliseconds. </param>
        public Pipe(MMDevice input, MMDevice output, int latency = DefaultLatency)
        {
            if (DeviceService.Equals(input, output))
            {
                throw new ArgumentException($"{nameof(input)} and {nameof(output)} cannot both be {input.FriendlyName}");
            }

            if (latency < MinLatency)
            {
                throw new ArgumentException("Latency is too low.", nameof(latency));
            }

            InputDevice  = input;
            OutputDevice = output;

            try
            {
                inputCapture = new WasapiLoopbackCapture(InputDevice);
            }
            catch (COMException ex)
            {
                throw new PipeInitException(ex.HResult, InputDevice);
            }

            buffer = new BufferedWaveProvider(inputCapture.WaveFormat);

            inputCapture.DataAvailable += (sender, e) =>
            {
                buffer.AddSamples(e.Buffer, 0, e.BytesRecorded);
            };

            try
            {
                outputDevice = new WasapiOut(OutputDevice, AudioClientShareMode.Shared, true, latency);
                outputDevice.Init(buffer);
            }
            catch (COMException ex)
            {
                throw new PipeInitException(ex.HResult, OutputDevice);
            }
        }