2011-06-16 119 views
1

我非常想用NAudio来做这项工作,所以请告诉我是否有解决方法。我已经通过串口设备传输原始音频,我试图通过WaveOut播放。使用NAudio播放非PCM原始音频

尝试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。它像贝多芬在奶酪刨上的第5场一样奏效。如果我将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)处理的情况。

+0

问题[使用NAudio解码mu律音频](http://stackoverflow.com/questions/4234665/using-naudio-to-decode-mu-law-audio)非常相似,但流长度在那种情况下是已知的。 – Asti 2011-06-16 19:55:58

回答

2

为了尝试(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方法,对于长度未知且无法重新定位的情况非常有用。

+0

谢谢马克。我确实重写了长度以返回零,但该设备在该时间点没有发送任何数据(原因未知),所以我认为可能长度对于wave提供商是必需的。 – Asti 2011-06-17 12:46:26

+0

IWaveProvider是一个简化的WaveStream,增加了很多清晰度。 – Asti 2011-06-17 12:47:58