Разработка интерактивных систем на OpenFrameworks: Интерактивный звук
Про настройку и визуализацию музыки с помощью openFrameworks мы недавно рассказывали. К сожалению русскоязычной информации по фреймворку OpenFrameworks достаточно мало. Для заполнения этого вакуума — начинаем серию публикаций лекций, что были прочитаны в Екатеринбурге в Институте математики и механики им. Н.Н. Красовского (УрО РАН) Денисом Переваловым.
В этой лекции будут рассказаны теоретические основы цифрового звука, и показан пример создания интерактивного приложения по генерации звука на базе захвата изображения с камеры.
Что такое цифровой звук, и звук вообще?
Звук, в широком смысле — упругие волны, продольно распространяющиеся в среде и создающие в ней механические колебания; в узком смысле — субъективное восприятие этих колебаний специальными органами чувств животных или человека. Как и любая волна, звук характеризуется амплитудой и частотой.
Представление звука в цифровом виде Реальный звук захватывается микрофоном, затем подвергается аналого-цифровому преобразованию.Оно характеризуетсяразрешением по времени — частота дискретизации, [процедура — дискретизация]разрешением по амплитуде — разрядность. [процедура — квантование]
Частота дискретизации8 000 Гц — телефон, достаточно для речи.11 025 Гц — игры, сэмплы для электронной музыки.22 050 Гц — то же, что и 11 025 Гц.44 100 Гц — многие синтезаторы и библиотеки сэмплов. Audio CD.48 000 Гц — студии звукозаписи, живые инструменты, вокал. DVD.96 000 Гц — DVD-Audio (MLP 5.1).192 000 Гц — DVD-Audio (MLP 2.0).
РазрядностьРазрядность — число бит, используемых для представления отсчетов сигнала при квантовании (в нашем случае — при квантовании амплитуды).
8 бит сэмплы электронной музыки.12 бит студийные звуковые эффекты.16 бит компьютерные игры, плееры, сэмплы, Audio CD.18 бит студийные звуковые эффекты24 бит живые звуки, вокал, DVD-Audio32 бит представление с плавающей точкой, поэтому точность не теряется для тихих звуков, поэтому используется для внутренней обработки звука.64 бит также с плавающей точкой, обработка звука.
Представление звука в памятиПример1 секунду 16-битного звука с частотой дискретизации 44100 Гц можно представить в виде вектораX = (x _1, x _2, …, …, x _44100), где 0 <= x _i <= 2^16-1 = 65535.Представление звуков таких способом — с помощью вектора — называется PCM (Pulse Code Modulation).Оно является наиболее распространенным и аналогично пиксельному представлению изображений.
Фундаментальное различие звука и изображенийС изображениями очень удобно работать на уровне пикселов. В частности:1. два изображения мы считаем одинаковыми, если значения их пикселов близки.2. можно изменять изображения, основываясь назначениях соседних пикселов (например, операция сглаживания).
Для звука в PCM формате обе возможности неприменимы, покажем это на примере:
Последние два звука звучат одинаково. А их функции амплитуды — существенно различные. Таким образом, человеческое ухо воспринимает спектр звука, то есть состав его частот, а не амплитудное представление звука.
Что легко/трудно делать «прямо» со звуком в формате PCM
Легко: Изменение и перестановка отдельных отсчетов, без учета соседей— переставлять кусочки, — менять громкость кусочков, — делать реверс — переворот звука от конца к началу, — смешивать несколько звуков, — смешивать и менять стерео-каналы, — делать простейшую компрессию, — добавлять простейшее эхо.
Сэмплеры, портастудии и студийные программы делают это виртуозно.
Трудно: Учет соседних отсчетов— сравнивать два звука на похожесть, — подавлять низкие или высокие частоты, — добавлять реверберацию.
Это обычно делается не прямо в PCM, а через спектральное представление звука (оконное преобразование Фурье).
Форматы хранения звукаWAVwav = заголовок + байты PCMХранит звук без потери качества (аналог в изображениях — bmp)
MP3Данные с потерями, хорошо подходит для хранения музыки.(аналог в изображениях — jpg)
AMRДанные с потерями, предназначен для хранения речи.Используется в мобильной телефонии (2011).(аналог в изображениях — png)
Способы генерации цифрового звука Есть следующие способы построения PCM-представления некоторого звука или музыки:1. СэмплированиеИспользуется для производства всей музыки. Устройства — сэмплеры
2. (Субтрактивный) СинтезИспользуется преимущественно для современной электронной музыки. Устройства — синтезаторы.
3. FM-синтез4. Аддитивный синтез5. Гранулярный синтез6. S&S — Sample & Synthesis — сэмплирование, анализ, последующий синтез — сегодня одна из наиболее лучших технологий воспроизведения«живых» инструментов.
Рассмотри три способа генерации звука: сэмплирование, субтрактивный и аддитивный синтез.
СэмплированиеЗапись: «Живой звук» — микрофон — АЦП — PCM-формат.
Воспроизведение: PCM-формат — ЦАП — динамик.
Дополнительные возможности: можно менять скорость воспроизведения, тогда повысится тон и скорость сэмпла.Современные алгоритмы также позволяют менять тон сэмпла без изменения его скорости, и наоборот.
Сэмплер Akai MPC1000:
Субтрактивный СинтезВ докомпьютерное время: несколько простых волн (прямоугольная, синусоидальная, треугольная) обрабатывались набором фильтров (НЧ, ВЧ, вырезание нужной частоты). Полученный звук шел на динамики.
Сейчас: делается в цифровом виде.Есть трудности — нужно аккуратно учитывать известные проблемы, связанные с цифровым представлением звука («алиасинг»).
Синтезатор Minimoog:
Аддитивный синтезАддитивный синтез основан на построении звука с помощью суммирования множества гармоник (т.е. синусоид разной частоты) с изменяющейся громкостью.
Любой звук можно представить с произвольной точностью как сумму большого числа гармоник с меняющейся громкостью. Но на практике работа с большим числом гармоник требует больших вычислительных ресурсов. Хотя, в настоящее время существует несколько аппаратных и программных аддитивных синтезаторов.
Примеры проектов на базе openFrameworks Про установку, настройку фреймворка, и IDE для сборки проектов, можно прочитать здесь.Воспроизведение сэмплов в openFrameworks — проект «звуковой ландшафт» Суть проекта: пользователь тыкает мышью в разные части экрана и начинает доноситься некоторый звук
//Объявление переменных ofSoundPlayer sample; //проигрыватель сэмпла ofPoint p; //точка и радиус — для рисования кружка float rad;
void testApp: setup (){ sample.loadSound («sound.wav»); //Загрузка сэмпла из папки bin/data sample.setVolume (0.5f); //громкость, [0, 1] sample.setMultiPlay (true); //разрешаем запускать несколько сэмплов ofSetFrameRate (60); //скорость рисования кадров ofSetBackgroundAuto (false); //выключаем стирание фона ofBackground (255,255,255); }
void testApp: update (){ ofSoundUpdate (); //обновляем состояние звуковой системы }
void testApp: draw (){ //если звук играет, рисовать прозрачный кружок ofEnableAlphaBlending (); if (sample.getIsPlaying ()) { //случайный цвет ofSetColor (ofRandom (0, 255), ofRandom (0, 255), ofRandom (0, 255), 20); ofCircle (p.x, p.y, rad); } ofDisableAlphaBlending (); }
//нажата мышь void testApp: mousePressed (int x, int y, int button){ float h = ofGetHeight (); //высота экрана //вычисляем желаемую скорость воспроизведения сэмпла, //при этом 1.0 — это оригинальная скорость сэмпла float speed = (h — y) / h * 3.0; if (speed > 0) { sample.play (); //запуск нового сэмпла sample.setSpeed (speed); //установка скорости воспроизведения
//запоминаем точку и радиус кружка для рисования p = ofPoint (x, y); rad = (3 — speed); rad = 20 * rad * rad; } } Сценарий проекта«Аддитивный синтезатор» Суть проекта: пользователь на белом фоне машет руками перед камерой. Имеется n гармоник. Экран разделен на nвертикальных полосок, в каждой считается число пикселов, яркость которых меньше некоторого порога. Это число определяет громкость соответствующих гармоник.Используем n = 20 синусоидальных гармоник, с частотами100 Гц,200 Гц, …2000 Гц
Гармоники играются с помощью зацикленных сэмплов, у которых просто меняется громкость.
Исходный код проекта:
//Объявляем переменные
//видео-граббер для «захвата» видеокадров ofVideoGrabber grabber; int w; //ширина кадра int h; //высота кадра
const int n = 20; //число гармоник ofSoundPlayer sample[ n ]; //сэмплы гармоник float volume[ n ]; //громкость гармоник int N[ n ]; //число пикселов, играющих в этой гармонике
ofSoundPlayer sampleLoop; //сэмпл барабанной петли
//Инициализация void testApp: setup (){
w = 320;
h = 240;
grabber.initGrabber (w, h); //подключение камеры
//загрузка сэмплов гармоник
for (int i=0; i //Обновление состояния
void testApp: update (){
grabber.grabFrame (); //захват кадра
if (grabber.isFrameNew ()){ //если пришел новый кадр
for (int i=0; i //Рисование
void testApp: draw () {
ofBackground (255,255,255); //задаем цвет фона
float w = ofGetWidth (); //высота и ширина экрана
float h = ofGetHeight ();
ofSetColor (255, 255, 255); //иначе картинка кадра нарисуется неверно
grabber.draw (0, 0, w, h); //вывод кадра //рисование гармоник
ofEnableAlphaBlending (); //включение прозрачности
ofSetColor (0, 0, 255, 80); //синий цвет с непрозрачностью 80
for (int i=0; i Если вам интересна тематика интерактивных систем, и openFrameworks в частности — то приглашаем в русскоязычную группу по openFrameworks.