Создание системы DSP с нуля - PullRequest
21 голосов
/ 13 июня 2011

Я люблю электронную музыку, и мне интересно, как все это тикает.Я нашел много полезных вопросов о переполнении стека в библиотеках, которые можно использовать для воспроизведения аудио, фильтров и т. Д. Но что мне действительно интересно, так это то, что происходит на самом деле: как данные передаются между эффектами и осцилляторами?Я провел исследование математической стороны dsp, и у меня есть подозрение, что проблема решена, но я не уверен, какую систему буферизации использовать и т. Д. Конечная цель - создать простую объектную иерархию эффектов и осцилляторов, которые передают данные.между друг другом (возможно, используя многопоточность, если я не вырываю все свои волосы, пытаясь это реализовать).Это не будет следующей Причиной Propellerhead, но меня интересует, как все это работает, и это скорее упражнение, чем то, что даст конечный продукт.

В настоящее время я использую .net и C # и недавно изучил F # (что может или не может привести к некоторым интересным способам обработки данных), но если они не подходят для работы, я могу изучить другойСистема при необходимости.

Вопрос в том, каков наилучший способ получения больших объемов данных сигнала через программу с использованием буферов?Например, мне лучше использовать Очередь, Массив, Связанный список и т. Д.?Должен ли я сделать образцы неизменяемыми и создавать новый набор данных каждый раз, когда применяю эффект к системе или просто редактирую значения в буфере?Неужели у меня есть объект стиля диспетчера / пула потоков, который организует передачу данных или функции эффекта передают данные непосредственно между собой?

Спасибо.

РЕДАКТИРОВАТЬ: еще один связанный вопрос: как мне тогдаиспользовать Windows API для воспроизведения этого массива?Я действительно не хочу использовать DirectShow, потому что Microsoft почти оставила его умирать

EDIT2: спасибо за все ответы.Посмотрев на все технологии, я буду либо использовать XNA 4 (я потратил некоторое время на траление в Интернете и нашел этот сайт , который объясняет, как это сделать), либо NAudio для вывода музыки ... не знаю, какая именнотем не менее, зависит от того, насколько продвинутой окажется система.Когда выйдет C # 5.0, я буду использовать его асинхронные возможности для создания архитектуры эффектов.Я в значительной степени использовал ответы всех одинаково, так что теперь у меня есть загадка, кому отдать награду ...

Ответы [ 8 ]

7 голосов
/ 17 июня 2011

Вы смотрели на VST.NET (http://vstnet.codeplex.com/)? Это библиотека для написания VST с использованием C #, и в ней есть несколько примеров. Вы также можете рассмотреть написание VST, чтобы ваш код мог использоваться из любого хост-приложения (но дажеесли вы не хотите, просмотр их кода может быть полезен).

Сигнальные данные обычно большие и требуют большой обработки. Не используйте связанный список! Большинство известных мне библиотек просто используют массив дляпоместите все аудиоданные (в конце концов, именно этого и ожидает звуковая карта).

Из примера VST.NET:

    public override void Process(VstAudioBuffer[] inChannels, VstAudioBuffer[] outChannels)
    {
        VstAudioBuffer audioChannel = outChannels[0];

        for (int n = 0; n < audioChannel.SampleCount; n++)
        {
            audioChannel[n] = Delay.ProcessSample(inChannels[0][n]);
        }
    }

audioChannel - это обертка вокруг неуправляемого буфера float *.

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

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

Я знаю два низкоуровневых способа воспроизведения вашего массива: DirectSound иWaveOut Fиз Windows API. C # Пример использования DirectSound . C # пример с WaveOut .Однако вы можете предпочесть использовать внешнюю библиотеку более высокого уровня, например NAudio .NAudio удобен для обработки аудио .NET - см. сообщение в блоге для отправки синусоидальной волны на звуковую карту.Вы можете видеть, что они также используют массив с плавающей точкой, что я и рекомендую (если вы будете выполнять вычисления с использованием байтов, вы получите много псевдонимов в звуке).

4 голосов
/ 22 июня 2011

F #, вероятно, является хорошим выбором, поскольку он хорошо приспособлен для манипулирования функциями.Функции, вероятно, являются хорошими строительными блоками для создания и обработки сигналов.

F # также хорош для манипулирования коллекциями в целом и массивами в частности, благодаря функциям высшего порядка в модуле Array.

Эти качества делают F # популярным в финансовом секторе, и я думаю, что он также полезен для обработки сигналов.

Visual F # 2010 для технических вычислений имеет раздел, посвященныйпреобразование Фурье, которое может иметь отношение к тому, что вы хотите сделать.Я думаю, что в сети достаточно информации о преобразовании.

Наконец, для воспроизведения сэмплов вы можете использовать XNA .Я думаю, что последняя версия API (4.0) также позволяет записывать, но я никогда не использовал это.Существует известное приложение для редактирования музыки для Xbox под названием ezmuse + Hamst3r Edition , которое использует XNA, так что это определенно возможно.

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

Я сделал довольно много DSP в реальном времени, но не со звуком.Хотя любая из ваших идей (неизменный буфер) и v (изменяемый буфер, измененный на месте) может сработать, я предпочитаю создать один постоянный буфер для каждой ссылки в сигнальном пути.Большинство эффектов плохо поддаются модификации, поскольку каждая входная выборка влияет на несколько выходных выборок.Техника буфера для каждой ссылки работает особенно хорошо, когда у вас есть этапы повторной выборки.

Здесь, когда поступают выборки, первый буфер перезаписывается.Затем первый фильтр считывает новые данные из своего входного буфера (первый буфер) и записывает на его выход (второй буфер).Затем он вызывает второй этап для чтения из второго буфера и записи в третий.

Этот шаблон полностью исключает динамическое распределение, позволяет каждому этапу сохранять переменное количество истории (поскольку для эффектов требуется некоторое количество памяти), иочень гибок, поскольку позволяет переставлять фильтры в пути.

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

Я не знаю, действительно ли это то, что вы ищете, но это был один из моих личных проектов в колледже.Я действительно не понимал, как работают звук и DSP, пока я сам не реализовал это.Я пытался подойти как можно ближе к динамику, поэтому я сделал это, используя только libsndfile, для обработки сложностей с форматами файлов.

По сути, мой первый проект заключался в создании большого массива двойников,заполните его синусоидальной волной, затем используйте sf_writef_double (), чтобы записать этот массив в файл, чтобы создать что-то, что я мог бы воспроизвести, и посмотреть результат в редакторе сигналов.

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

Таким образом, вы начинаете играть с осцилляторами и эффектами очень низкого уровня, и вы можете сразу увидеть результаты.Плюс, очень мало кода, чтобы заставить что-то подобное работать.

Лично я бы начал с самого простого из возможных решений, а затем медленно добавил бы.Попробуйте просто записать файл и использовать его для воспроизведения, чтобы вам не приходилось иметь дело с аудио интерфейсом.Просто используйте один массив для запуска и модифицируйте на месте.Определенно начните с однопоточного.По мере роста вашего проекта вы можете начать переходить к другим решениям, таким как конвейеры вместо массива, многопоточность или работа с аудио API.

Если вы хотите создать проект, вы можете отправить егов зависимости от того, что именно, вам, вероятно, придется перейти к более сложным библиотекам, таким как некоторая обработка звука в реальном времени.Но основы, которые вы изучите, выполнив приведенный выше простой способ, определенно помогут, когда вы дойдете до этого момента.

Удачи!

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

Что касается проблем с буферизацией и асинхронностью / многопоточностью / синхронизацией, я предлагаю вам взглянуть на новую библиотеку потока данных TPL.С его блочными примитивами, параллельными структурами данных, сетями потоков данных, асинхронной обработкой сообщений и абстракцией на основе задач TPL (которые могут использоваться с функциями async / await C # 5), он очень хорошо подходит для приложений такого типа.

1 голос
/ 26 июня 2011

Хорошо, тогда я тоже получу удар в награду:)

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

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

Я - парень из Linux, поэтому я начал писать плагины LADSPA на C. Я думаю, что было бы хорошо начать с этого базового уровня, чтобы действительно понять, что происходит. Если бы я работал в Windows, я бы скачал VST SDK от Steinberg и написал бы быстрое доказательство концептуального плагина, который просто добавляет шум или что-то в этом роде.

Еще одно преимущество выбора фреймворка, такого как VST или LADSPA, заключается в том, что вы можете сразу использовать свои плагины в своем обычном аудио-комплекте. Удовлетворение применения вашего первого самодельного плагина для звуковой дорожки непобедимо. Кроме того, вы сможете поделиться своими плагинами с другими музыкантами.

Вероятно, есть способы сделать это в C # / F #, но я бы порекомендовал C ++, если вы планируете писать плагины VST, чтобы избежать ненужных накладных расходов. Это, кажется, отраслевой стандарт.

С точки зрения буферизации, я использовал циклические буферы (хорошая статья здесь: http://www.dspguide.com/ch28/2.htm).. Хорошее упражнение - реализовать фильтр с конечным откликом (то, что Штейглиц называет фильтром прямой связи) - они полагаются на буферизацию и с ним довольно весело играть.

У меня есть репозиторий на Github с несколькими очень простыми плагинами LADSPA. Помимо архитектурных различий, они потенциально могут быть полезны для тех, кто пишет плагины VST. https://github.com/andreasjansson/my_ladspa_plugins

Другим хорошим источником примера кода является проект CSound. Там есть тонны DSP-кода, и программное обеспечение предназначено в первую очередь для музыкантов.

0 голосов
/ 10 ноября 2013

Вы можете взглянуть на BYOND . Это среда для программирования аудио / миди инструментов и создания эффектов в C #. Он доступен как автономный, так и в качестве инструментария и эффекта VST.

ПОЛНОЕ РАСКРЫТИЕ Я разработчик BYOND.

0 голосов
/ 14 июня 2011

Начните с чтения этого и этого .

Это даст вам представление о том, ЧТО вам нужно сделать.

Затем изучите DirectShowархитектура - и научитесь, КАК не делать этого, а попытайтесь создать свою упрощенную версию.

...