在 UWP 应用中使用 AudioGraph 将音频输出发送到两台设备

Posted

技术标签:

【中文标题】在 UWP 应用中使用 AudioGraph 将音频输出发送到两台设备【英文标题】:Send audio output to two devices with AudioGraph in an UWP app 【发布时间】:2017-02-08 19:06:25 【问题描述】:

我尝试将来自麦克风的输入同时发送到扬声器和连接的耳机。 我知道如何使用文件和设备执行此操作,但我不知道如何将第二个设备与输出节点连接并将其附加到图表。 我可以使用 CreateDeviceOutputNodeAsync 创建节点,但我不知道如何将设备与节点相关联。 对于一个设备,当我在创建图表时在设置中将设备作为 PrimaryRenderDevice 时,它​​可以工作。 这是一个输出设备的工作代码。我不知道如何解决这个问题以使其适用于两个输出设备。

private async Task CreateAudioGraph()

       AudioGraphSettings settings = new AudioGraphSettings(AudioRenderCategory.Speech);
        settings.QuantumSizeSelectionMode = QuantumSizeSelectionMode.LowestLatency;
        settings.DesiredRenderDeviceAudioProcessing = Windows.Media.AudioProcessing.Raw; // this is also set automatically when LowestLatency is set
        settings.PrimaryRenderDevice = OutputDeviceForInput;

        CreateAudioGraphResult result = await AudioGraph.CreateAsync(settings);

        if (result.Status != AudioGraphCreationStatus.Success)
        
            // Cannot create graph

            ConnectionStatus = String.Format("AudioGraph Creation Error because 0", result.Status.ToString());
            return;
        

        graphForInputDeviceNo1 = result.Graph;
        ConnectionStatus = "Graph successfully created!";


        // Create a device input node using the selectedt input device
        CreateAudioDeviceInputNodeResult deviceInputNodeResult = await graphForInputDeviceNo1.CreateDeviceInputNodeAsync(MediaCategory.Speech, graphForInputDeviceNo1.EncodingProperties, FirstInputDevice);

        if (deviceInputNodeResult.Status != AudioDeviceNodeCreationStatus.Success)
        
            // Cannot create device input node
            ConnectionStatus = String.Format("Audio Device Input unavailable because 0", deviceInputNodeResult.Status.ToString());
            return;
        

        deviceInputNode = deviceInputNodeResult.DeviceInputNode;

        // Create the first device output node
        CreateAudioDeviceOutputNodeResult deviceOutputNodeNo1Result = await graphForInputDeviceNo1.CreateDeviceOutputNodeAsync();
        if (deviceOutputNodeNo1Result.Status != AudioDeviceNodeCreationStatus.Success)
        
            // Cannot create device output node
            ConnectionStatus = String.Format("Audio Device Output unavailable because 0", deviceOutputNodeNo1Result.Status.ToString());
            return;
        

        deviceOutputNodeNo1 = deviceOutputNodeNo1Result.DeviceOutputNode;

        // Create the second device output node
        CreateAudioDeviceOutputNodeResult deviceOutputNodeNo2Result = await graphForInputDeviceNo1.CreateDeviceOutputNodeAsync();
        if (deviceOutputNodeNo2Result.Status != AudioDeviceNodeCreationStatus.Success)
        
            // Cannot create device output node
            ConnectionStatus = String.Format("Audio Device Output unavailable because 0", deviceOutputNodeNo2Result.Status.ToString());
            return;
        
        deviceOutputNodeNo2 = deviceOutputNodeNo2Result.DeviceOutputNode;

        ConnectionStatus = "Device Output connection successfully created";


        deviceInputNode.AddOutgoingConnection(deviceOutputNodeNo1);

        ConnectionStatus = "Device Input connection successfully created";
        deviceInputNode.AddOutgoingConnection(deviceOutputNodeNo2);

        // Because we are using lowest latency setting, we need to handle device disconnection errors
        graphForInputDeviceNo1.UnrecoverableErrorOccurred += Graph_UnrecoverableErrorOccurred;
        graphForInputDeviceNo1.Start();  // erst damit geht es los

【问题讨论】:

有类似案例,请参考***。 我看不出这有什么相似之处。我不想要任何帧输入或其他任何东西。我只想将我的输出发送到两个设备,例如耳机和扬声器,但我不知道如何设置两个输出节点。 嘿@Frank,你有没有找到使用 AudioGraph 将音频输出到两个设备的解决方案? 嗨,艾伦,我没有。但从那以后我就没有尝试过。 感谢您的回复!据我所知,每个图表只能有一个输出设备。考虑到整个框架的设计,这看起来很奇怪,但实际的代码 API 似乎很清晰,除非我在某处遗漏了一些方法...... 【参考方案1】:

MSDN document 有点混乱:

创建一个新的 AudioDeviceOutputNode,它将音频数据中的音频数据输出到系统的默认输出设备,例如扬声器或耳机。

其实,输出设备不一定是系统默认的输出设备。但是,由于您无法更改节点的Device 属性,并且构造函数没有为您提供该选项,因此似乎必须来自系统设置。

不过,还有一个地方我们可以设置:AudioGraphSettings class 允许你设置PrimaryRenderDevice property,这实际上是创建输出节点时将使用的设备。

您可以尝试以下方法:

var settings = new AudioGraphSettings(AudioRenderCategory.Other);
settings.PrimaryRenderDevice = device_other_than_system_output;

var ag_result = await AudioGraph.CreateAsync(settings);
var ag = ag_result.Graph;

var result = await ag.CreateDeviceOutputNodeAsync();
assert(result.DeviceOutputNode == device_other_than_system_output);

从技术上讲,这并没有解决您的问题,因为 AudioGraph 仍然无法拥有两个输出节点。但是,您可以尝试创建多个 AudioGraphs,它们使用相同的输入,并输出到不同的渲染设备,以获得您希望的相同效果。

【讨论】:

以上是关于在 UWP 应用中使用 AudioGraph 将音频输出发送到两台设备的主要内容,如果未能解决你的问题,请参考以下文章

AudioGraph 可以播放流吗?

最小化或锁定时继续播放 Audiograph UWP 输出

uwp AudioGraph 音频处理

UWP AudioGraph API - FrameOutputNode 读取字节错误

AudioGraph DesiredSamplesPerQuantum 属性被忽略

如何使用默认输出设备作为使用 AudioGraph 录制音频的源?