Дилемма потоковой передачи, по крайней мере, я так думаю

#c# #audio #waveout

#c# #Аудио #waveout

Вопрос:

Я пытаюсь выводить звуковые сэмплы и делаю это с помощью cswavplay из http://www.codeproject.com/KB/audio-video/cswavplay.aspx которые, в свою очередь, похоже, используют DllImports из winmm.dll.

Я заставил его воспроизводиться, используя 8-битные сэмплы, однако он с треском проваливается, когда я пытаюсь скормить ему 16-битные сэмплы. Я изучил код как можно лучше, и я понимаю это следующим образом:

Я получаю указатель на буфер для заполнения каждый раз, когда cswavplay заканчивает воспроизведение последнего буфера. Это работает в течение одной итерации, иногда воспроизводится один буфер… Я получаю всевозможные забавные исключения, AccessViolationException только сейчас, например, когда я попытался использовать размер буфера 44100, чтобы более четко слышать, сколько воспроизводится. Но когда я размещаю точки останова в разных местах внутри класса WaveOut (часть cswavplay), кажется, что ни один из объектов, которые он использует, таких как буферы и экземпляр AutoResetEvent, все еще активен на второй итерации. Мое лучшее предположение заключается в том, что эти проблемы связаны с потоковой обработкой или GC. Исключения кажутся довольно случайными, и я слишком неопытен, чтобы полностью понять, что происходит.

Я прошу о любом из следующих:

1) Дикие предположения относительно того, в чем может быть проблема

2) Обоснованные предположения относительно того, в чем может быть проблема

3) Указывает на альтернативный способ вывода звука в реальном времени с использованием C#

Я не прошу тщательного отслеживания ошибок в программном обеспечении, которое я не писал, так что не обращайте внимания на cswavplay…

В конце концов, я, возможно, делаю здесь что-то не так, но трудно понять, когда я не получаю соответствующее исключение (типа BufferAllocationException или что-то в этом роде)…

Редактировать:

Спасибо за все предложения по другим звуковым API. Все они, похоже, предполагают наличие файла .wav. Прошу прощения за неясность, я не воспроизводю файлы .wav, я синтезирую сэмплы в реальном времени.

Комментарии:

1. GC. Так не думаю. Многопоточность? Может быть, вы используете потоки?

2. Я могу предложить только (II), но использование 8-битного кода на выборку при 16-битной операции на выборку может привести к переполнению буфера. Исключения с нарушением доступа и отсутствующие объекты — вы, вероятно, на правильном пути, что GC преждевременно использует ваши данные — выглядит как непродуманные попытки небезопасного кода. Это то, что вы можете сделать в небезопасном коде, с нуля, с правильным маршалингом?

3. Вы пробовали SoundPlayer класс? msdn.microsoft.com/en-us/library/system.media.soundplayer.aspx

4. @ssamuel Я выводил 8-битные выборки с сигналом, настроенным на 8 бит в то время. Однако, похоже, это не работает в 16-битном режиме…

5. @ssamuel Проблема в том, что я вообще не в состоянии даже начать что-либо переделывать, не говоря уже о том, чтобы начать с нуля 😉 Может быть, мне стоит просто сдаться и купить домашнее животное … : (

Ответ №1:

DirectSound и для .NET мне приходит на ум XNA framework. Существует множество очень высококачественных примеров одновременного воспроизведения звука и анимации графики с помощью .NET.

Комментарии:

1. Спасибо, хотя это кажется таким громоздким по сравнению с тем, что у меня уже есть, что «почти» работает… Завтра я сварю себе немного крепкого кофе, закатаю рукава и посмотрю, смогу ли я включить этот чертов DirectSound…