Давно что-то не писал про программирование звука. На этот раз напишу о языке программирования звука
ChucK.
Как почти всегда с подобными языками бывает, родился он где-то в недрах университетов, где пару людей на нем сделали диссертацию, и целая орава студентов делали на нем дипломные работы. PureData, CLAM, кстати, в этом не исключение, SuperCollider по-моему, тоже.
Основная фишки языка - можно программно контролировать звук вплоть до семпла (авторы назвали это «strongly timed»), готовая многопоточность, которую легко использовать, встроено большое количество готовых
STK-инструментов и эффектов - plucked string, mandolin, woodwind и т.д.
Из минусов - язык довольно молодой (лет 5 ему), т.е. многое в нем еще сырое, многого нет, иногда падает. Мне также показался несколько неудобным синтаксис - он несколько жестковат, смахивая на C/Паскаль. Из-за этого писать на нем несколько напряжно после всяких современных руби и питонов, в которых "элементы оформления" сведены к минимуму.
Вот пример программы на нем (синтез kick):
SinOsc s => dac;
200 => int startFreq;
20 => int stopFreq;
100::ms => dur length;
startFreq - stopFreq => int freqRange;
1::samp => dur stepDur;
stepDur / length => float step;
1 => float i;
while (i > 0) {
i * freqRange + stopFreq => s.freq;
i => s.gain;
i - step => i;
stepDur => now;
}
Здесь меняя значения переменных startFreq, stopFreq задается начальная и конечная частоты "слайда", значением переменной length (здесь 100::ms) - его длительность. Частота осцилятора меняется каждый семпл - эта длительность задается значением переменной stepDur, равная здесь 1::samp - это и называется «strongly timed».
Если вместо синусоиды нужна, например пила - вместо SinOsc используем SawOsc. Если на все это хозяйство еще нужно положить ревер, этак конструкция будет выглядеть как
SawOsc s => JCRev r => dac;
Стоит подробнее остановиться на этом «strongly timed». ChucK запускается в виде звукового сервера. Затем (или одновременно с этим) на нем запускается проигрывание одной или нескольких программ (здесь они называются shred). Время в них общее - длительности, события и т.д. гарантированно синхронны вплоть до семпла.
Это можно увидеть во включенных примерах программ - otf*.ck :
.5::second => dur T;
T - (now % T) => now;
В переменную T заносится длительность полсекунды.
now % T - остаток от деления "текущего времени" на длительность.
Эта конструкция включена в начало каждого из файлов-примеров и при старте шреда добавляет паузу до ближайшей границы в полсекунды. В результате можно запускать эти файлы как угодно, и они всегда будут синхронизированы по долям.
Из этого следует следующий важный принцип языка (исповедуемый авторами языка чуть-ли не религиозно) - on-the-fly programming - написание звуковых программ в реальном времени. Существует даже несколько
Laptop Orchestra (
фото), в которых несколько человек с лэптопами пишут программу на ChucK в реальном времени сообразуясь с задумкой автора музыкального произведения и командами дирижера.
Помимо собственно звукового сервера, от тех же авторов есть пара IDE для написания программ в нем, в которых есть подсветка синтаксиса, автоматизированно добавление/удаление звучащих шредов, есть какие-то средства визуализации звука.
Резюме: мне ChucK показался неудобным в программировании, поэтому серьезно я заниматься им не стал, хотя продолжаю наблюдать за ним. Можно попробовать его преподавать в институтах как "первый язык программирования" - на эту роль он определенно будет хорош - повеселее, чем часто используемые для этого Паскаль и Си + заодно познакомит с основами синтеза звука.
P.S.: один из авторов языка, Ge Wang, написал
обзор истории языков программирования звука (первая часть
этого PDF) - интересующимся этой темой весьма рекомендую.