Разработка интерактивных систем на OpenFrameworks: Интерактивный звук

Про настройку и визуализацию музыки с помощью openFrameworks мы недавно рассказывали. К сожалению русскоязычной информации по фреймворку OpenFrameworks достаточно мало. Для заполнения этого вакуума — начинаем серию публикаций лекций, что были прочитаны в Екатеринбурге в Институте математики и механики им. Н.Н. Красовского (УрО РАН) Денисом Переваловым.

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

Что такое цифровой звук, и звук вообще? bbf08b720c2c43229255baaf48ba3fba.jpg

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

Представление звука в цифровом виде Реальный звук захватывается микрофоном, затем подвергается аналого-цифровому преобразованию.Оно характеризуетсяразрешением по времени — частота дискретизации, [процедура — дискретизация]разрешением по амплитуде — разрядность. [процедура — квантование]

a3e580be488340e5bae6cf6155e8acd9.png

Частота дискретизации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 формате обе возможности неприменимы, покажем это на примере:

4baa96cb25f74051b3e3bc9a5009ba0e.jpg

Последние два звука звучат одинаково. А их функции амплитуды — существенно различные. Таким образом, человеческое ухо воспринимает спектр звука, то есть состав его частот, а не амплитудное представление звука.

Что легко/трудно делать «прямо» со звуком в формате 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: 1e4e1d398dc745cdbb281f73b67411a5.jpg

Субтрактивный СинтезВ докомпьютерное время: несколько простых волн (прямоугольная, синусоидальная, треугольная) обрабатывались набором фильтров (НЧ, ВЧ, вырезание нужной частоты). Полученный звук шел на динамики.

Сейчас: делается в цифровом виде.Есть трудности — нужно аккуратно учитывать известные проблемы, связанные с цифровым представлением звука («алиасинг»).

Синтезатор Minimoog: f73ff4e0d2cb4bb0be0ea57e6181daeb.jpg

Аддитивный синтезАддитивный синтез основан на построении звука с помощью суммирования множества гармоник (т.е. синусоид разной частоты) с изменяющейся громкостью.

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

Примеры проектов на базе openFrameworks Про установку, настройку фреймворка, и IDE для сборки проектов, можно прочитать здесь.Воспроизведение сэмплов в openFrameworks — проект «звуковой ландшафт» Суть проекта: пользователь тыкает мышью в разные части экрана и начинает доноситься некоторый звук40c349b386c941308f656391f20eb2a3.jpg

//Объявление переменных 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 400) ? 0: 1; //пороговая обработка int i = (x * n / w);//в какую гармонику писать результат volume[ i ] += result; N[ i ]++; } } //устанавливаем новые громкости гармоник for (int i=0; i 0) { volume[ i ] /= N[ i ]; } //нормируем громкости в [0, 1] sample[ i ].setVolume (volume[ i ] / n); //громкость. //Делим на n, иначе будет искажение выходного звука } } ofSoundUpdate ();//обновляем состояние звуковой системы}

//Рисование 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.

© Habrahabr.ru