使用NAudio流式传输非PCM原始音频

时间:2011-06-16 19:41:18

标签: vb.net audio stream naudio

我很想跟NAudio一起工作,所以请告诉我是否有办法解决这个问题。我有来自串口设备的流式原始音频,我正试图通过WaveOut播放。

尝试1:

'Constants 8000, 1, 8000 * 1, 1, 8
Dim CustomWaveOutFormat = WaveFormat.CreateCustomFormat(WaveFormatEncoding.Pcm, SampleRate, Channels, AverageBPS, BlockAlign, BitsPerSample)    
Dim rawStream = New RawSourceWaveStream(VoicePort.BaseStream, CustomWaveOutFormat)

'Run in background
Dim waveOut = New WaveOut(WaveCallbackInfo.FunctionCallback())

'Play stream
waveOut.Init(rawStream)
waveOut.Play()

这段代码有效,但是有一个小问题 - 实际的音频流不是原始的PCM,它是原始的MuLaw。它像贝多芬在奶酪刨丝器上的第五名一样完成了压缩。如果我将WaveFormat更改为WaveFormatEncoding.MuLaw,我会收到错误的格式异常,因为它是原始音频而且没有RIFF标题。

所以我转而将其转换为PCM:

尝试2:

Dim reader = New MuLawWaveStream(VoicePort.BaseStream, SampleRate, Channels)
Dim pcmStream = WaveFormatConversionStream.CreatePcmStream(reader)
Dim waveOutStream = New BlockAlignReductionStream(pcmStream)

waveOut.Init(waveOutStream)

在这里,CreatePcmStream尝试获取流的长度(即使CanSeek = false)并且失败。

尝试3

waveOutStream = New BufferedWaveProvider(WaveFormat.CreateMuLawFormat(SampleRate, Channels))
*add samples when OnDataReceived()*

似乎也缺乏标题。

我希望所有这些都让我错过了一些小事。设备在使用时仅传输音频,否则不会收到数据 - 由(1)处理的情况。

1 个答案:

答案 0 :(得分:2)

要使attempt(1)工作,RawSourceWaveStream应该指定数据的实际格式。然后使用另一个WaveFormatConversionStream.CreatePcmStream,将rawStream作为输入:

Dim muLawStream = New RawSourceWaveStream(VoicePort.BaseStream, WaveFormat.CreateMuLawFormat(SampleRate, Channels))
Dim pcmStream = WaveFormatConversionStream.CreatePcmStream(muLawStream);

尝试(2)实际上非常接近工作。你只需要让MuLawStream.Length返回0.你不需要它来做你正在做的事情。 BlockAlignReductionStream也与mu-law无关,因为mu law block align是1。

尝试(3)应该工作。我不知道你的意思是缺少标题?

在NAudio中,您正在构建音频数据管道。管道中的每个阶段可以具有不同的格式。您的音频以Mu-law开始,然后转换为PCM,然后可以播放。即使您的设备已停止提供音频数据,也会使用缓冲的WaveProvider来继续播放。

编辑我应该补充一点,NAudio中的IWaveProvider接口是一个简化的WaveStream。它只有一种格式和一种Read方法,对于长度未知且无法重新定位的情况非常有用。