Итак, наш сегодняшний гость ChucK, придуманный Пери Куком (Perry Cook) и Ги Вонгом (Ge Wang) из университета Принстон в 2003 году, последняя версия вышла в 2009 году.
ChucK — один из языков программирования, предназначенный для написания музыки, синтеза звука в реальном времени и организации взаимодействия различной специализированной периферии.

ChucK является интерпретируемым языком. Нативно поддерживает параллельное исполнение нескольких потоков (так называемых «шредов») программы, причем исполнение шредов происходит в соответствии с определенными циклами (sample rate, control rate), что позволяет производить их синхронизацию силами самого Чака. К слову, в описании авторов сказано, что «ChucK is on-the-fly programming language», что на деле позволяет вносить изменения в программу прямо во время исполнения и дает возможность некоторым вытворять удивительные вещи на сцене. (Да, да! Гики строчащие на сцене код, который тут же превращается в музыку — это реальность!)
ChucK является мультипарадигменным языком со строгой типизацией данных и не совсем обычным синтаксисом, связанным с особенностью области применения (об этом чуть позже). Удобнее всего подходить к Чаку с позиции ООП, особенно тем, кто уже сталкивался с модульными студиями синтеза.
Начнем?
Распространяется ChucK под лицензией GNU GPL и доступен для платформ Windows, Linux, Mac OS X, а с недавнего времени еще и iOS (с закрытым кодом).
Для начала обзаведемся инструментами. За необходимым софтом идем сюда.
По ссылке можно найти бинарники консольного интерпретатора под Mac OS X и Windows, для Linux представлены исходные коды для самостоятельной компиляции (со всеми необходимыми инструкциями, так что разберется даже новичок). Но блокнот + консоль не самая удобная связка, для комфортной работы нам потребуется среда разработки. Тут на выбор дается два варианта:
• miniAudicle – редактор с подсветкой синтаксиса, отладчик и виртуальная машина в одном флаконе. Уже давно в стадии бета версии, поэтому готовьтесь к множеству сюрпризов. Например, мне (и не только) так и не удалось собрать эту поделку под Linux с поддержкой JACK, а в Windows при выходе приходится вручную сносить процесс miniAudicle.exe, т.к. программа завершается некорректно.
Скриншот
• Audicle – экспериментальная среда модульной разработки, может показаться удобнее тем, кто знаком с Max/MSP. Однако, тем кто привык работать в классических IDE, Audicle покажется малопонятной. К тому же оно еще более сырое и глючное, чем miniAudicle.
Я лично остановился на первом варианте ввиду большей стабильности и большему (субъективно) удобству. Скриншот
Версии под iOS на сайте нет, вероятно, ее можно найти в AppStore. Я не буду останавливаться подробно на сборке и установке необходимого ПО, надеюсь, что тот, кто захочет — разберется в этом сам, благо все инструкции на сайте имеются, а на хабре сидят люди образованные. Для тех, у кого все же возникли трудности в конце я дам ссылку на форум чакистов.
10 HELLO, WORLD!
Перед тем как строчить код, давайте условимся, что все действия у нас будут выполняться в программе miniAudicle. Перед работой, запустите виртуальную машину (ChucK -> Start Virtual Machine в главном меню программы). Запуск шреда осуществляется большой зеленой кнопкой «Add Shred», а остановка – красной «Remove Shred». Если ваш шред выполняется, а вы нажимаете «Add Shred», вы тем самым добавляете еще одну копию, для перезапуска существует кнопка «Replace Shred».
Итак. С чего принято начинать знакомство с новым языком программирования? Ну конечно же, с банального «Hello, World!»:
<<< "Hello,World!" >>>;
Не совсем обычный синтаксис объясняется очень просто: Чак просто не предназначен для работы со стандартным текстовым выводом и то, что заключено в символы <<< >>>, по сути, является выводом отладочной информации. Посмотрим на следующий пример:
.5 => float hello; // вещественной переменной hello присваивается значение 5
Обратите внимание на запись вещественных чисел. Такая запись не является обязательной, однако в документации используется именно она. Кстати, вот и первый пример «не совсем обычного» синтаксиса, оператор =>.
Оператор => называется chuck, и выполняет не только функции оператора присваивания. По сути, он выполняет роль соединительного шнура между объектами, а присваивание будет лишь одним из частных случаев «соединения». Например, модель классического синтезатора, записанная с помощью этой конструкции, выглядела бы так: 440 => Oscillator => Envelope => Filter => AudioOut.
Попробуем разобраться в этом вот на таком типичном примере (а заодно разберемся в привязке к временным промежуткам):
SinOsc S => JCRev R => dac;
.2 => S.gain;
440 => S.freq;
.3 => R.mix;
5::second + now => time later;
while( now < later )
{
1::second => now;
}
Попробуйте запустить этот кусок кода. Вы услышите 5 секунд синусоиды частотой 440Hz, пропущенной через ревербератор. Разберем все по порядку. В первой строчке представлена следующая конструкция: инициализируется экземпляр синусоидального осциллятора S, далее, с помощью оператора =>, сигнал направляется в экземпляр ревербератора JCReverb R, а из него сигнал поступает на dac (стандартный вывод звука в ChucK). В строках 2 и 3 мы устанавливаем параметры звука: gain – громкость, mix – степень смешения оригинальной (так называемой, сухой) синусоиды и сигнала обработанного ревербератором. Так же, как и в жизни: мы слышим как прямой, так и отраженный звук. (Ревербератор же имитирует отражения от поверхностей, позволяя добиваться эффекта звучания в каком-либо помещении). В S.freq – задается частота.
А дальше начинается самое интересное. Дело в том, что в Чаке существуют два специальных типов данных для управления синхронизацией и некоторых других нужд. Это тип time и тип dur (duration). Тип time – время абсолютное, а dur – относительное. Строкой
5::second + now => time later;
мы отсчитываем 5 секунд с текущего момента (специальная переменная now (типа time) служит для определения текущего времени) и присваиваем это значение переменной later. Как не сложно догадаться, дальше идет цикл, каждый шаг которого выполняется за строго определенный период времени (здесь в одну секунду). Здесь данный цикл приведен для наглядности привязки к времени, и в реальной ситуации то же самое запишется много проще:
SinOsc S => JCRev R => dac;
.2 => S.gain;
440 => S.freq;
.3 => R.mix;
5::second => now;
Время можно задавать не только в секундах, но и в семплах, миллисекундах, минутах, часах и даже днях, неделях и годах. Тут разработчики явно подошли к предмету с юмором.
Пожалуй, хватит
На этом закончим знакомство с Чаком. Думаю, в качестве введения хватит и этого. Добавлю только, что ChucK не ограничивается лишь простым синтезом. Он позволяет работать с протоколом MIDI, внешними звуковыми файлами и секвенсорами.
Для тех, кто захочет продолжить знакомство, приложу несколько полезных ссылок:
chuck.cs.princeton.edu/doc/language — официальная спецификация языка, крайне рекомендуется к полному прочтению
wiki.cs.princeton.edu/index.php/ChucK — wiki
chuck.cs.princeton.edu/doc/examples — примеры кода. (Также мануал в pdf и множество примеров можно найти в папке с miniAudicle.)
electro-music.com/forum/forum-140.html — немногочисленное, но чуть ли не единственное живое сообщество чакистов.
На русском языке, к сожалению, полезной информации нет вообще.
На самом деле, ChucK не единственный ЯП, специально предназначенный для звукоизвлечения, так же существуют и другие решения, в том числе чисто коммерческие и более дружественные. Для тех, кто хочет втянуться, но кому Чак кажется слишком сложным для освоения (хотя на самом деле, там нет ничего сложного, главное втянуться и разобраться) или не подходит в силу иных причин, можно посоветовать другие решения: en.wikipedia.org/wiki/Audio_programming_language
А если вы вдруг захотите присоединиться к разработке, ищите ChucK на sourceforge.net.

