Создание простых сигналов с помощью CoreAudio
Я новичок в CoreAudio, и я хотел бы вывести простую синусоидальную и прямоугольную волны с заданной частотой и амплитудой через динамики, используя CA. Я не хочу использовать звуковые файлы, поскольку я хочу синтезировать звук.
Что мне для этого нужно? И можете ли вы дать мне пример или учебник? Благодарю.
5 ответов
В предыдущем ответе есть ряд ошибок. Я, легендарный:-) Джеймс Маккартни, а не Джеймс Харкинс написал sinewavedemo, я также написал SuperCollider, о котором рассказывает сайт audiosynth.com. Я также сейчас работаю в Apple над CoreAudio. Sinewavedemo использует CoreAudio, так как он использует AudioHardware.h из CoreAudio.framework в качестве способа воспроизведения звука.
Вы не должны использовать sinewavedemo. Это очень старый код, и он делает опасные предположения о расположении буфера аудиооборудования. В настоящее время самый простой способ воспроизвести генерируемый вами звук - это использовать AudioQueue или использовать выходной аудиоустройство с установленным обратным вызовом рендеринга.
Лучший и самый простой способ сделать это без файлов - это подготовить буфер с одним циклом, содержащий один цикл волны (это технически называется волновой таблицей)
В функции воспроизведения, вызываемой потоком CoreAudio, заполните выходной буфер сэмплами, считанными из волнового буфера.
Тем не менее, обратите внимание, что вы очень быстро столкнетесь с двумя проблемами: - для синусоидальной волны, если частота воспроизведения не является целым числом, кратным требуемой синусоидальной частоте, вам, вероятно, потребуется реализовать интерполятор, если вы хотите иметь хорошее качество. Использование только целочисленных указателей приведет к значительному уровню гармонического шума.
- для прямоугольной волны избегайте просто программировать массив со значениями +1 / -1. Такой сигнал не ограничен полосой пропускания и будет многозначным. Не забывайте, что спектр прямоугольной волны практически бесконечен!
Чтобы получить хорошие алгоритмы для генерации сигнала, взгляните на musicdsp.org, это, вероятно, один из лучших ресурсов для этого
Если вы не делаете это в режиме реального времени, используя sin()
функция от math.h
неплохая идея Просто заполняйте столько сэмплов, сколько вам нужно, с помощью sin() заранее, когда пришло время его воспроизвести, просто отправьте его в аудио-буфер. Функция sin() может быть довольно медленной, чтобы вызывать один раз каждый сэмпл, если вы выполняете это в реальном времени, поскольку использование метода интерполированного волнового поиска намного быстрее, но результирующий звук не будет таким спектрально чистым.
Вы новичок в звуковом программировании в целом? В качестве отправной точки я хотел бы проверить
http://www.audiosynth.com/sinewavedemo.html
Это минимальная реализация osx sinewave от легендарного Джеймса Харкинса. Обратите внимание, что он не использует CoreAudio вообще.
Если вы специально хотите использовать CoreAudio для своей синусоиды, вам нужно создать модуль вывода (RemoteIO на iphone, AUHAL на osx) и предоставить обратный вызов ввода, где вы можете в значительной степени использовать код из приведенного выше примера. Проверять, выписываться
http://developer.apple.com/mac/library/technotes/tn2002/tn2091.html
Преимущества CoreAudio в основном заключаются в том, чтобы связывать другие эффекты с помощью синусоиды, писать плагины для хостов, таких как Logic, и предоставлять интерфейсы для них, писать хост (например, Logic) для плагинов, которые можно связать воедино.
Если вы не хотите писать плагин или хост-плагин, тогда CoreAudio может вам не подойти. Но одно из лучших преимуществ использования CoreAudio заключается в том, что после того, как ваш обратный вызов синусоиды работает, можно легко добавлять эффекты или смешивать несколько синусов вместе.
Для этого вам нужно поместить свой выходной блок в график, на котором вы можете эффекты, микшеры и т. Д.
Вот некоторая помощь по настройке графиков http://timbolstad.com/2010/03/16/core-audio-getting-started-pt2/
Это не так сложно, как кажется. Apple предоставляет вспомогательные классы C++ для многих вещей (/Developer/ examples/CoreAudio/PublicUtility), и даже если вы не хотите использовать C++ (вам не нужно!), Они могут быть полезным руководством по API CoreAudio.
В главе 7 книги Adamson/Avila "Learning Core Audio", опубликованной Addison-Wesley Professional (ISBN-10: 0-321-63684-8), есть хороший и хорошо документированный пример кода проигрывателя синусоидальной волны:
Это довольно новая публикация (2012), и она касается именно вопроса этого вопроса. Это только отправная точка, но это ценная отправная точка.
КСТАТИ. Не переходите к графикам, пока не найдете этот базовый урок (который включает в себя некоторую математику).
Что касается примера кода, быстрый и эффективный метод, который я часто использую, имеет дело с предварительно заполненной синусоидальной таблицей поиска, которая имеет столько же элементов, сколько частота дискретизации, для 44100 Гц таблица имеет размер 44100. Другими словами, длина цикла равна частоте выборки. Это дает приемлемый компромисс между скоростью и качеством во многих случаях. Вы можете инициализировать его с помощью программы.
Если вы генерируете образцы с плавающей запятой (по умолчанию в OSX) и используете математические функции, используйте sinf(), а не (float) sin (). Акции в циклах внутреннего цикла обратного вызова рендеринга всегда дороги. Таковы повторяющиеся умножения констант, такие как 2.0 * M_PI, которые слишком часто можно найти в примерах кода.