【问题标题】:NAudio: WaveBadFormat Exception while initializing WaveOut with BufferedWaveProviderNAudio:使用 BufferedWaveProvider 初始化 WaveOut 时出现 WaveBadFormat 异常
【发布时间】:2022-07-30 23:22:57
【问题描述】:

我正在尝试使用 NAudio 播放音频,使用 WaveOut 初始化 BufferedWaveProviderUdpClient 在单独的线程中接收音频数据包,并通过AddSamples() 将它们写入BufferedWaveProvider

到目前为止一切正常。

不幸的是,在切换设备时(根据选择的设备设置WaveOutDeviceId属性并重新初始化WaveOut),出现MmException

BufferedWaveProviderWaveFormat 设置为任何A- 或ULawFormat(例如WaveFormat.CreateALawFormat(8000, 1))时,错误才会以某种方式发生。将其设置为new WaveFormat(8000, 8, 1) 时,切换音频设备可以正常工作,但接收到的音频无法正确播放(因为它是使用 G711A 编解码器发送的 => 需要 ALawFormat)。

这是示例代码(出于演示目的,我在这里使用WaveFileReader 而不是UdpClient):

public class MainViewModel {
    private BufferedWaveProvider _WaveProvider;
    private WaveOut _WaveOut;

    public ObservableCollection<string> AllAudioDevices { get; set; }

    private string _SelectedAudioDevice;
    public string SelectedAudioDevice {
        get => _SelectedAudioDevice;
        set {
            _SelectedAudioDevice = value;
            OnSelectedAudioDeviceChanged(value);
        }
    }

    public MainViewModel() {
        _WaveProvider = new BufferedWaveProvider(new WaveFormat(8000, 1));
        _WaveOut = new WaveOut();

        AllAudioDevices = LoadAllAudioDevices();
        SelectedAudioDevice = AllAudioDevices[0];
    }

    private ObservableCollection<string> LoadAllAudioDevices() {
        var allAudioDevices = new ObservableCollection<string>();

        for (int i = 0; i < WaveOut.DeviceCount; i++) {
            allAudioDevices.Add(WaveOut.GetCapabilities(i).ProductName);
        }

        return allAudioDevices;
    }

    private void OnSelectedAudioDeviceChanged(string newAudioDevice) {
        _WaveOut.Stop();

        _WaveOut = new WaveOut();
        _WaveOut.DeviceNumber = AllAudioDevices.IndexOf(newAudioDevice);
        _WaveOut.Init(_WaveProvider);
        _WaveOut.Play();

        new Thread(ReceiveAudio).Start();
    }

    private void ReceiveAudio() {
        var reader = new WaveFileReader(@"D:\temp\test.wav");

        byte[] readBytes;
        int readCount;

        do {
            readBytes = new byte[1000];
            readCount = reader.Read(readBytes, 0, readBytes.Length);

            if (readCount == 0) {
                break;
            }

            _WaveProvider.AddSamples(readBytes, 0, readBytes.Length);

            Thread.Sleep(100);
        } while (true);
    }
}

【问题讨论】:

  • 并非所有编解码器都相同。机器中使用的芯片可能不支持该模式,和/或驱动程序可能不支持该模式。使用设备管理器检查机器上使用的驱动程序和IC。我通常会找到正在使用的IC,然后从制造商处下载驱动程序。不是通用 Microsoft 驱动程序或 PC 制造商安装驱动程序。从 IC(芯片组)制造商处获取最新信息。

标签: c# exception audio naudio codec


【解决方案1】:

您不能直接使用 u-law 或 a-law 打开输出设备。您需要转换为 16 位 PCM。幸运的是,在 NAudio 中很容易做到这一点 - 只需使用 MuLawDecoderALawDecoder 类。您还可以在 NAudio GitHub 存储库中找到 network chat demo,它显示了与您想要实现的目标非常相似的用例。

【讨论】:

    猜你喜欢
    • 2016-02-17
    • 2019-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    相关资源
    最近更新 更多