Потоковое аудио без PCM с помощью NAudio - PullRequest
1 голос
/ 16 июня 2011

Я чертовски стремлюсь сделать эту работу с 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. Это разыгрывает компандирование как 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).

1 Ответ

2 голосов
/ 16 июня 2011

Чтобы попытка (1) сработала, ваш RawSourceWaveStream должен указать формат, в котором действительно находятся данные. Затем просто используйте другой WaveFormatConversionStream.CreatePcmStream, взяв в качестве входных данных rawStream:

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

Attempt (2) на самом деле очень близко к работе.Вам просто нужно, чтобы MuLawStream.Length возвращал 0. Вам это не нужно для того, что вы делаете.BlockAlignReductionStream также не имеет отношения к mu-law, поскольку выравнивание блоков mu mu равно 1.

Попытка (3) должна работать.Я не знаю, что вы подразумеваете под отсутствием заголовка?

В NAudio вы создаете конвейер аудиоданных.Каждый этап в конвейере может иметь свой формат.Ваш звук начинается в Mu-law, затем преобразуется в PCM, а затем может воспроизводиться.Буферизованный WaveProvider используется для продолжения воспроизведения, даже если ваше устройство перестало предоставлять аудиоданные.

Редактировать Я должен добавить, что интерфейс IWaveProvider в NAudio - это упрощенный WaveStream.Он имеет только формат и метод чтения и полезен в ситуациях, когда длина неизвестна и изменение положения невозможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...