Найти тему
ZDG

Как запрограммировать звук

Читайте также: Музыкальный ликбез, Компьютерная музыка

Начнём с истории того, какими способами в компьютерных программах делали звук.

1. PC Speaker

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

Кроме того, в языке Бейсик, например, была команда BEEP, которая заставляла этот же динамик издавать писк. А также, если вывести в текстовой консоли строку с символом, ASCII-код которого равен 7, вы тоже услышите писк. У этого символа нет внешнего вида, но есть соответствующее название – BELL (колокольчик, звонок).

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

Управлять динамиком можно было и напрямую. Подробности я опущу, потому что они уже не актуальны.

Можно условно представить, что динамик соединён напрямую с неким адресом памяти. Если мы записываем в этот адрес 1, то на динамик поступает напряжение, и его мембрана качается вперёд. Если записываем 0, напряжение на динамике исчезает и его мембрана возвращается назад.

Качаясь вперёд и назад, мембрана создаёт акустическую волну, которую мы слышим как щелчок.

Теперь, если заставить её качаться в цикле, мы услышим много щелчков, которые следуют с определённой частотой. Если мембрана будет качаться с частотой 440 щелчков в секунду (она же 440 Герц), то мы услышим камертонную ноту "ля".

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

Но во многих старых играх можно слышать музыку, где одновременно играет несколько инструментов, а также довольно разборчивую запись речи, выстрелов и других звуковых эффектов – и всё это на спикере компьютера. Какая техника используется для этого?

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

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

Однако эта задача не так проста. Спикер как звуковое устройство очень ограничен и добиться чёткого, качественного звука удавалось не всем. В качестве примера игр с хорошим спикерным звуком я могу привести Budokan, Xenon 2 Megablast, Another World, World Class Leader Board Golf, а также, само собой, музыкальный трекер Scream Tracker.

Потом наступила эра звуковых карт, наиболее популярной из которых стал

2. SoundBlaster

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

Изменился и формат данных. Для спикера были возможны только 2 положения: 1 и 0 (то есть "громко" и "тихо"), а для саунд-карты можно было использовать уже 8- или 16-битные значения. Это значит, что появились градации громкости, которые значительно обогатили звук.

Если ранее звуковые данные выглядели как азбука Морзе, то теперь они выглядят так:

-2

Каждая вертикальная линия – это один сэмпл, или интенсивность звука, измеренная и записанная в дискретный момент времени. Таких моментов столько, сколько мы видим линий.

Работа с несколькими звуками не изменилась – по-прежнему, чтобы звучали одновременно два звука, их надо сложить. Но теперь они действительно складываются арифметически, то есть мы берём первый сэмпл первого звука (допустим, 64), затем берём первый сэмпл второго звука (допустим, 128), и складываем их. В результате мы получили первый сэмпл общего звукового буфера: 192. Так же вычисляем второй, третий и т.д.

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

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

3. Системные функции

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

playSound(file)

И это всё, что требуется. Кроме того, вы скорей всего сможете вызвать функцию несколько раз, чтобы сыграть несколько звуков одновременно. О том, как их смикшировать, позаботится сама система.

А теперь вернёмся к проблеме. Если система сама микширует множество звуков, звучащих одновременно, то в чём проблема? Ни в чём, пока нам не придётся для каких-то целей осуществлять микширование самостоятельно. Что это может быть? Например, когда вам нужно управлять характеристиками звука "на лету", то есть прямо в тот момент, пока он играется. Обычная функция типа playSound() не даст вам такой возможности.

Читайте также:

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

В общем, это довольно редкая задача, но всё же она возникает, плюс нам надо просто понять, как это делать. Поэтому будем разбираться.

Читайте дальше: