(c#) 使用 DirectShow 播放和控制多个声音文件

(c#) Playing and controlling multiple sound files using DirectShow

我对 DirectShow 的经验很少,到目前为止,我已经在特定输出设备上管理播放 .wav 文件,同时能够控制其音量和 get/set 其轨道位置。基本上我能够创建一个非常简单的声音播放器应用程序。

这是我目前使用的代码:

    //select an output device          
    DsDevice[] devices = DsDevice.GetDevicesOfCat(FilterCategory.AudioRendererCategory 
    DsDevice device = (DsDevice)devices[xxx];

  
    //define a source          
    Guid iid = typeof(IBaseFilter).GUID; 
    object source = null;            
    device.Mon.BindToObject(null, null, ref iid, out source);          
           
    //build a basic graph to play the sound
    IGraphBuilder player_gra = (IGraphBuilder)new FilterGraph();                
    player_gra.AddFilter((IBaseFilter)source, "Audio Render");            
    player_gra.RenderFile(@"test.wav", "");                         
            
    //start the sound
    (player_gra as IMediaControl).Run();          
            
    //control the volume          
    (player_gra as IBasicAudio).put_Volume(volume);

    //get/set position on the track
    (player_gra as IMediaPosition).get_Duration(out out1);//how long the track is
    (player_gra as IMediaPosition).get_CurrentPosition(out out2);
    (player_gra as IMediaPosition).put_CurrentPosition(yyy);

我现在想做的是同时播放多个 .wav 文件,同时能够在 运行 时间控制每个文件的音量和音轨位置。

我的第一次尝试是创建多个 IGraphBuilder 实例并同时 运行 它们,但似乎只有一个可以同时播放,而其他的则等待当前播放的实例通过以下方式终止:

Marshal.ReleaseComObject(player_gra);  

我的第二次尝试是在启动 IGraphBuilder 之前给它几个要渲染的文件。

…
player_gra.RenderFile(@"testA.wav", "");            
player_gra.RenderFile(@"testB.wav", "");            
player_gra.RenderFile(@"testC.wav", "");            
…

通过这种方式可以同时播放文件,但我看不出有什么办法可以控制每个声音的音量,更不用说它在音轨上的位置了。

提前谢谢你;-)

在这些行中

DsDevice[] devices = DsDevice.GetDevicesOfCat(FilterCategory.AudioRendererCategory);
DsDevice device = (DsDevice)devices[0];

您枚举音频输出设备并选择第一个看起来是 Default WaveOut Device 或其实例之一的“随机”设备。

它有一个遗留行为,即只有一个活动实例实际发送数据进行播放。系统中没有防止同时回放的基本限制,这只是遗留行为。

也就是说,您同时播放了两个图表,但第二个图表的音频被静音了。

Audio mixing is disabled in the waveOut Audio Renderer, so if you need to mix multiple audio streams during playback, use the DirectSound renderer.

如果您改用 Default DirectSound Device(您可以通过在代码中使用 device[NNN] 中的不同索引快速获取),您将听到您期望听到的声音。

DirectShow.NET 以某种方式令人困惑地进行枚举,默认的 DirectSound 设备通常具有最高的价值并列在第一位,并且您似乎以不同的顺序获得设备。