CSL, стандартиризованный API для работы со звуком
 
Автор: (C) Jeff Tranter
Перевод: (C) Владимир Меренков


Проблема

Представим себе, что Вы пишете новую крутую игру для Linux, и, подобно всем современным играм, в ней есть поддержка звука. Существует множество программных инструментов для работы со звуком, но если Вы похожи на многих других "гейм-программеров", то Вы просто напрямую обращаетесь к аудио устройству /dev/dsp, что дает максимум гибкости и возможностей.

Игра отлично выглядит и Вы даете копию для испытаний Вашему другу. Странно, звук не работает. Оказывается, Ваш друг работает с десктопом GNOME, а под GNOME доступ к аудиоустройству можно получить через аудио сервер esd. Предполагается, что приложения GNOME обращаются к esd, а не напрямую к устройству. Так что Вы возвращаетесь, изучаете API esd, и добавляете в Вашу программу опции для работы с esd.

Теперь Вы передаете игру для тестирования Вашей подружке, и звук опять не работает. Ей нравится работать с десктопом KDE, а под KDE звуковое устройство управляется сервером artsd. Итак, Вы провели пару вечеров изучая интерфейс программирования artsd и добавляя в Вашу игру возможность работы и с KDE тоже.

Ваш третий друг прослышал об этой великой игре и тоже хочет ее попробовать. Он работает на рабочей станции Sun под управлением Solaris, но это ничего, ведь он может просто перекомпилировать код для своей архитектуры. Неудача, звук не работает как ожидалось, потому что в Solaris звуковое устройство и API для работы с ним не такие, как в Linux. Вы могли бы поработать над добавлением поддержки и для Solaris (если бы у вас был доступ к машине под "Соляркой"), но что делать с теми друзьями, кто работают с AIX, и с теми, кто используют сетевой аудио сервер (NAS - Network Audio Server)? А с теми, кто используют драйверы ALSA? Просто обеспечение базовой поддержки звука потребует большой работы. Что не есть хорошо: Вы не сможете написать программу один раз, и чтобы она работала на всех платформах.

Выход -- использовать стандартизированный интерфейс программирования для работы со звуком: Common Sound Layer, сокращенно CSL.

Что такое CSL?

CSL создан как раз для решения описанной проблемы. CSL, или Common Sound Layer, это ориентированный на язык программирования C API для программирования звука. CSL предназначен для решения проблем обеспечения поддержки звука в приложениях, независимо от применяемых низкоуровневых звуковых драйверов. Есть надежда, что CSL станет общей библиотекой поддержки звука в проектах KDE и GNOME.

В настоящее время CSL работает на Linux системах, используя звуковые драйверы OSS и библиотеку aRts (которая работает под десктопами KDE и GNOME). Приложения, использующие CSL, больше не зависят ни от каких библиотек или компонент.

CSL разрабатывался так, чтобы обеспечить эффективность, сопоставимую с кодом, написанным для каждой конкретной платформы, возможность управления задержками [latency] и полный дуплексный режим. Это делает CSL пригодным для таких приложений реального времени, как игры.

В этом смысле CSL довольно уникален в том смысле, что, несмотря на все разговоры о "войне десктопов" KDE и GNOME, он был создан совместно разработчиком KDE Стефаном Вестерфилдом [Stefan Westerfeld] и разработчиком GNOME Тимом Джаник [Tim Janik].

Возможности

В настоящее время CSL доступен, как preview version 0.1.2, включающую:
  • C-API для цифровой записи и воспроризведения звука
  • интерфейсы для звуковых драйверов Linux kernel OSS и aRts (под KDE и GNOME)
  • прозрачную поддержку сети и сетевую аутентификацию при использовании с aRts
  • поддержку многопоточности
  • сгенерированную с использованием Doxygen документацию
  • HOWTO/FAQ
  • несколько утилит и примеры программ

У CSL есть некоторые ограничения, в основном связанные с его дизайном: это API для языка С, так что не ожидайте объектно ориентированного интерфейса. Это низкоуровневый интерфейс, причем только для цифрового звука (никаких MIDI, миксеров, кодеков для комплексных форматов типа MP3). Если хотите использовать особенности типа 3D-звука, то обратите внимание на что-то вроде OpenAL.

В настоящий момент, CSL поддерживает только звуковые драйверы OSS или сервер звука aRts (aRts используется в KDE, существует и GNOME версия). Много мультимедиа-приложений, подобных xmms и RealVideo player, будут работать и под aRts).

Хотя CSL еще не закончен, API довольно стабилен и имеет широкую функциональность.

Получение и установка CSL

Чтобы использовать CSL, вы должны иметь Linux систему с работающими драйверами звука (OSS или совместимые: OSS/4Front или ALSA с эмуляцией OSS). Если Вам нужна поддержка aRts, то нужна версия aRts 0.5.4 или более свежая, поставляемая в составе KDE 2.2 или полученная отдельно с http://www.arts-project.org. Если вы используете GNOME, то существует специальная версия aRts для GNOME, которую можно взять там же. Сверх того Вам нужны только обычные инструменты разработки: gcc, gld и GNU auto.

В настоящее время CSL распространяется только в виде исходных текстов. Вам нужно скачать архив tar http://www.arts-project.org/download/csl-0.1.2.tar.gz (на момент, когда Вы будете читать это, может существовать более новая версия).

Сборка и установка CSL выполняется по простой процедуре сборки в GNU, документированной в файле INSTALL. Вкратце -- надо выполнить следующие команды:

%./configure
% make
% make install

Последняя команда должна быть выполнена с правами root-а. Протестировать CSL вы можно двумя утилитами, включенными в поставку. Программа testsine генерирует "сырые" сэмплы с синусоидой частотой 440 Hz, а cslcat берет "сырые" звуковые cэмплы со стандартного входа и посылает их на аудио-устройство. Перенапрвление выхода одной команды на вход другой осуществляется вот так:

% tests/testsine | csl/cslcat

что должно воспроизвести тон частотой 440 Hz длительностью 1 сек (вышеприведенная команда подразумевает, что вы находитесь в главной директории с исходниками CSL).

Если у вас есть любые звуковые файлы .raw, вы можете попытаться воспроизвести их с помощью утилиты cslcat, например:

% cslcat -r 44100 -w 8 -c 1 /usr/lib/games/koules/start.raw

Вы можете так же попробовать программы в директории examples.

Пример

Я пройдсь по короткому, но полнофункциональному примеру программы, использующей CSL. За основу взята программа cslpcm1.c, включенная в релиз (для краткости я удалил коментарии и проверку ошибок). Существуют дополнительные примеры CSL, которые иллюстрируют больше функций API. Текстовая версия программы доступна здесь.

 1  #include <unistd.h>
 2  #include <stdio.h>
 3  #include <fcntl.h>
 4  #include <csl/csl.h>
 5
 6  int main (int argc, char **argv)
 7  {
 8      const int size = 1024;
 9      CslDriver *driver;
10      CslPcmStream *stream;
11      CslOptions options;
12      short buffer[size];
13      int i, j, fd;
14
15      options.n_channels = 2;
16      options.rate = 44100;
17      options.pcm_format = CSL_PCM_FORMAT_S16_LE;
18      csl_driver_init (NULL, &driver);
19      csl_pcm_open_output (driver, "cslpcm1", options.rate, options.n_channels, options.pcm_format, &stream);
20      fd = open("/dev/urandom", O_RDONLY);
21      for (i = 0; i < 500; i++)
22      {
23          read(fd, buffer, size);
24          for (j = 0; j < size; j++)
25              buffer[j] = CLAMP(buffer[j], -4000, 4000);
26              csl_pcm_write (stream, size, buffer);
27      }
28      csl_pcm_close (stream);
29      csl_driver_shutdown (driver);
30      return 0;
31  }

В строке 4 мы включаем заголовочный файл <csl/csl.h>, в котором определены все функции API CSL.

В строках 9-11 мы объявляем переменные, которые будут содержать важные типы данных CSL. CslDriver -- это дескриптор [handle], ассоциированный с тем драйвером, с которым CSL будет работать. CslPcmStream -- звуковой поток PCM, ассоциированный с CslDriver, и открытый с определенными параметрами либо для ввода, либо для вывода. Переменная типа CslOptions хранит опции для CslPcmStream. Для удобства CSL может произвести разбор опций сэплирования, полученных из командной строки, и поместить их в переменную типа CslOptions.

Строки 15-17 устанавливают опции PCM: число каналов, частоту дискретизации и формат данных. В нашем случае это два канала (стерео), при частоте 44100 отсчетов в секунду и использовании 16-ти битное числа со знаком для представления данных.

В строке 18 мы получаем дескриптор CslDriver. Можно было бы указать, какой именно драйвер использовать на "той стороне CSL" (например "oss" или "arts"), специальное значение NULL дает CSL инструкцию выбрать драйвер автоматически. Можно запросить у CSL список имеющихся в системе драйверов.

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

В строке 20 мы открыли на чтение генератор случайных чисел Linux. Их мы собираемся посылать на звуковое устройство.

Строки 22-27 формирую цикл, в котором данные из /dev/urandom читаются в буфер и затем пишутся данные в PCM-поток, используя функцию csl_pcm_write. Так как данные являются случайными, они могут содержать большие значения, которые могут быть довольно громкими. Мы используем удобный макрос CLAMP, предоставленный CSL, для того чтобы ограничить диапазон значений (вспомните, что мы работаем с 16-ти битными знаковыми занчениями). Результатом записи случайных данных в устройство будет шипение в динамике. Это белый шум без определенной частоты, что означает -- генератор случайных чисел действительно хороший источник случайных данных.

В стоках 28-29, после прохождения по циклу 500 раз (примерно 3 секунды), мы закрываем поток и освобождаем драйвер.

Изучая этот и другие примеры, просматривая HTML документацию по API, вы быстро "прочувствуете", как использовать эту библиотеку.

Портирование приложений в CSL

Приложения, использующие драйвер OSS, просто портируются на CSL. Вы получите приложение, прекрасно работающее в системе с aRts, и работоспособное с драйверами ядра. В качестве примера я где-то за час портировал звуковое приложение, содержащее около 550 строк кода на С. Многие функции CSL API, csl_pcm_write похожи на низкоуровневые библиотечные С-функции, часто используемые в программировании звука (такие как write).

Текущее состояние и планы на будущее

В настоящее время CSL находится в стадии предварительного рализа. Осталась завершить работу над некоторыми деталями (пока отсутствующими), провести тестирование, и "пофиксить" баги. Возможное направление будущей работы: реализации поддержки artsc (С API для arts) и API esound, используемого в GNOME.

Заключение

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

Ссылки

  1. CSL HOWTO и FAQ (включено в поставку исходного кода CSL)
  2. Документация по CSL API (включено в поставку исходного кода CSL, создана с использованием Doxygen)
  3. Исходный код CSL 0.1.2
  4. Аннонс выхода CSL 0.1.2
  5. Аннонс выхода GNOME aRts 0.1.2
  6. Страница aRts Project

Это список рассылки для CSL. Вы можете присоединиться к нему послав письмо со словом subscribe в теле сообщения по адресу [email protected]. Архив списка на http://www.mail-archive.com/[email protected].


Jeff Tranter

Jeff Tranter использует Linux с 1992 года. Он автор HOWTO по Linux Sound и CD-ROM, а так же является автором книги Linux Multimedia Guide, вышедшей в O'Reilly. Работал в разных областях Linux, последнее время над поддержкой мультимедиа в KDE. В настоящее время работает в новой Linux компании Xandros Corporation.
Copyright (C) 2001, Jeff Tranter.
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 70 of Linux Gazette, September 2001

Вернуться на главную страницу