如何混合多个输入并保持同步?

时间:2017-01-20 08:37:15

标签: c# naudio

我很难搞清楚如何在没有明显延迟的情况下将多个音频源合并到一个流中。我尽可能地遵循了NAudio的文档,并写了以下内容;

    public void Start()
    {
        _format = new WaveFormat(48000, 16, 2);

        _mixingSampleProvider = new MixingSampleProvider(WaveFormat.CreateIeeeFloatWaveFormat(48000, 2));

        _compressorStream = new SimpleCompressorStream(new MixingWaveStream(_mixingSampleProvider.ToWaveProvider()));
        _compressorStream.Enabled = true;

        foreach (var p in _activeRenderers)
        {
            p.Start(_compressorStream);
        }
    }

    public void RegisterProvider(IAudioProvider provider)
    {
        var audioWaveProvider = new AudioWaveProvider(provider, _format);
        _providers.Add(audioWaveProvider);
        _mixingSampleProvider.AddMixerInput(audioWaveProvider.WaveProvider);
    }

MixingWaveStream是从IWaveProvider到WaveStream的转换。 p.Start()此时只需初始化WasapiOut并调用Play()。现在只有一个(我意识到当前设置不适用于多个输出)。 和我的AudioWaveProvider;

    public AudioWaveProvider(IAudioProvider provider, WaveFormat format)
    {
        // Resample if necessary
        if (provider.BitDepth != format.BitsPerSample || provider.Channels != format.Channels || provider.SampleRate != format.SampleRate)
        {
            _waveProviderToSendSamples = new BufferedWaveProvider(new WaveFormat(provider.SampleRate, provider.BitDepth, provider.Channels));
            WaveProvider = new MediaFoundationResampler(_waveProviderToSendSamples, format);
        }
        else
        {
            WaveProvider = new BufferedWaveProvider(format);
            _waveProviderToSendSamples = (BufferedWaveProvider)WaveProvider;
        }

        AudioProvider = provider;
        provider.ProvideSamples += Provider_ProvideSamples;
    }

    private void Provider_ProvideSamples(IAudioProvider provider, AudioSamples samples)
    {
        _waveProviderToSendSamples.AddSamples(samples.Samples, 0, (int)samples.Samples.Length);
    }

我的音频提供商(在这种情况下只是一个libvlc播放的视频)通过一个事件提供样本。

一切正常但是有明显的延迟(在观看我输出的视频帧时大约100毫秒)。我意识到添加混音器,BufferedWaveProvider和(可能)重新采样器会增加很多开销,但我想知道保持视频和音频同步的最佳做法。

编辑:我的输入是44100Hz,因此使用了MediaFoundationResampler。经过一些测试后,这是大部分延迟的原因,但我有多种不同格式的输入。

那么,如何保持音频和视频同步?或者我如何降低MediaFoundationResampler重新采样的时间?这里的最佳做法是什么?我可以使用多个输出,但建议使用混音器。

1 个答案:

答案 0 :(得分:1)

是的,MediaFoundationTransform的硬编码读取大小为一秒音频,因此可以很容易地计算出源缓冲区和目标缓冲区的大小。我总是打算在试验最佳尺寸之后将其配置为未来,但由于我只是在可以提前阅读的情况下使用它,我从来没有接受它。

如果您可以创建自己的NAudio自定义版本,那么您可以尝试使用较小的sourceBuffer尺寸。