2015-03-30 1 views
1

Этот вопрос касается не плагина, а самостоятельной разработки прикладной программы и связано с несколькими вопросами, которые я задавал раньше.Потоки производителей аудио с потребительской нитью и обратным вызовом OSX AudioComponent в C

Я должен написать многопоточного аудио функции синтезирования, чье количество данных хруст намного превышает, что может получить размещены на CoreAudio визуализации нить: несколько тысяч независимых амплитуды и фазы интерполирования с точностью до сэмпла синус -волновых генераторов в реальном времени. Это требует большей мощности ЦП, чем любое ядро ​​одного процессора, которое может иметь все доступные оптимизации.

Я делаю все возможное, чтобы изучить его, но это, кажется, стена, а не кривая. Потребительская нить может быть простой CA Принимать обратный вызов приоритета приоритета в реальном времени AudioBufferList iodata и т. Д. ... но какой должна быть нить производителя? Если вы выбираете другой AudioComponent, он не лучше, чем все это в выходном потоке - он только усложняется и вводит дополнительную задержку.

Если положить п параллельных AudioComponents в графа, который питает кольцевой буфер, который питает потребительскую нить, как можно гарантировать, что это не будет в конечном итоге в том же потоке, оставаться в синхронизации и с точностью до сэмпла ?

При написании n традиционные потоки POSIX с соединительными выходами, как достичь модели pull-Core CoreAudio, будет сосуществовать с такой моделью push в реальном времени?

Есть ли такой бесплатный код примера? Есть ли ссылка, учебник или учебник в написании такого кода? Я не нашел общедоступной информации. Меня удивляет, что такого вопроса не задавали раньше?

Заранее благодарен!

ответ

1

Моей стратегией было бы иметь отдельный поток (или потоки), генерирующий ваш аудиосигнал LPCM в реальном времени и записывающий его в кольцевой буфер соответствующего размера. Основной звуковой поток будет считываться из этого кольцевого буфера.

Если читатель (основная звуковая нить) запрашивает больше аудио, чем доступно, то вы получаете выпадание (buffer underrun), потому что читатель не может ждать. Это указывает на то, что вам нужен больший буфер, или что ваш алгоритм генерации звука не в реальном времени и нуждается в оптимизации.

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

Я знаю два классных реализаций ringbuffer, которые используют трюки виртуальной памяти для эффективной реализации модульного доступа к памяти:

Если вы ищете для чего-то более портативного, есть CBuffer для unix-подобных систем и Magic Ring Buffer для Windows.

Однако! Вам не нужно использовать сложные кольцевые буферы MMU, вы можете использовать обычную старую портативную версию C, если хотите.

+0

Спасибо, это очень разумное направление. Я изучил TPCircularBuffer М. Тайсона. Тем не менее, я немного смущен тем, как писать поток (non-CoreAudio), который будет постоянно запускаться и заполнять круговой буфер с помощью вычисленных выборок или нулей и будет связываться с потоком рендеринга, не блокируя ничего. Я бы предпочел не быть слишком OSX конкретным. Заранее спасибо. – user3078414

+1

Я добавил несколько заметок о блокировании и не-osx vm кольцевых буферах. –

+0

Спасибо за ваш комментарий, но не могли бы вы так любезно сообщить, где вы добавили заметки, пожалуйста? – user3078414