Войти
ДельфинарийСтатьи

Работа со звуковой библиотекой Audiere

Автор:

Интродукшн

Почему Audiere? Главный критерий для меня был бесплатность библы, а таковых на данный момент (лично что нашел я) было три - OpenAL, Squall и Audiere. ОпенАЛ отпал сразу из-за своей низкоуровневости и сложности, к Squal'у я так и не нашел делфефских хидеров :)
Остановился я именно на Audiere, там более что и функциональность меня полностью устраивала:

* Поддержка MP3, OGG,  MOD, S3M, XM, IT.
* Стриминг/полная загрузка данных, контроль громкости, баланса, частоты.
* Загрузка файлов как с диска так и из буффера в памяти.

Файлы

Не буду тут рассказывать о шаманских танцах, которые понадобились чтобы все это заработало :) Скачать саму библиотеку версии
1.9.3, Doxygen'овский хелп и пофикшеные рабочие заголовочные файлы к ней можно по ссылке

http://vivat99.ru/Audiere.zip

Общая информация

Библиотека предоставляет нам несколько классов и функций, рассмотрим основные классы:

* TAdrAudioDevice - устройство воспроизведения
* TAdrFile - абстрактный файл с данными: файл на диске или буффер в памяти.
* TAdrSampleSource - данные семпла.
* TAdrOutputStream - звуковой поток.
* TAdrSoundEffect - звуковой эффект

В принципе этого уже достаточно чтобы полноценно работать с библиотекой. Про остальные методы и классы можно почитать в хелпе, особой ценности они ИМХО не представляют ;)
Менеджмент всех классов библиотеки осуществляется с помощью механизма подсчета ссылок (Reference counting),
тоесть объект живет до тех пор пока его внутренний счетчик ссылок на него больше нуля.
Получив указатель на экземпляр класса мы должны вызвать у него метод Ref увеличивающий счетчик ссылок на единицу, когда он нам больше не нужен то вызываем у него метод UnRef уменьшающий счетчик ссылок на единицу.

Принцип работы

Работа с Audiere осуществляется примерно таким образом:

1. Создание устройства воспроизведения
2. Создание файла с данными
3. Загрузка данных семпла из созданного в п.2 файла
  4а. Создание потока из созданных в п.3 данных семпла
  4б. Создание эффекта из созданных в п.3 данных семпла
5. Работа с созданными потоками/эффектами.
6. Завершение работы

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

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

Получив поток или эффект, мы можем делать с ним все что угодно - проигрывать, менять параметры итд.
Далее подробно рассмотрим каждый пункт:

1. Создание устройства воспроизведения

Устройство воспроизведения создается функцией AdrOpenDevice которая возвращает указатель на созданный экземпляр
класса TAdrAudioDevice:

AudioDevice := AdrOpenDevice(nil, nil);
AudioDevict.Ref;

Первым параметром функции передается название устройства воспроизведения, которое должно быть использованно.
Второй параметр - строка со списком параметров устройства воспроизведения через запятую, например "buffer=100,rate=44100"
Если параметры не указывать то будут использованны значения по умолчанию.

2. Создание файла с данными

Файл с данными создается с помощью двух функций: AdrOpenFile для файла на диске и AdrCreateMemoryFile для файла в памяти,
возвращающих указатель на экземпляр класса TAdrFile:

  // Файл на диске

  SoundFile := AdrOpenFile('test.wav', False);
  SoundFile.Ref;

Первым параметром функции передается указатель на строку с именем файла.
Второй параметр - возможность записи в этот файл.

  // Файл в памяти

  SoundFile := AdrCreateMemoryFile(Buffer, BufferLength);
  SoundFile.Ref;

Первым параметром функции передается указатель на буффер в памяти.
Второй параметр - размер буффера.

3. Загрузка данных семпла

Данные семпла загружаются с помощью функции AdrOpenSampleSourceFromFile которая возвращает указатель на созданный экземпляр класса TAdrSampleSource.

  SampleSource := AdrOpenSampleSourceFromFile(SoundFile, FF_AUTODETECT);
  SampleSource.Ref;
 

Первым параметром функции передается экземпляр класса TArdFile, который мы создали в п.2.
Второй параметр - тип файла (константа типа TAdrFileFormat), в вышеприведенном коде использована константа FF_AUTODETECT для автоматического определения типа файла.

4а. Создание потока

Поток создается с помощью функции AdrOpenSound которая возвращает указатель на созданный экземпляр класса TAdrOutputStream.

  OutputStream := AdrOpenSound(AudioDevice, SampleSource, False);
  OutputStream.Ref;
 

Первым параметров функции передается экземпляр класса TAdrAudioDevice который мы создали в п.1.
Второй параметр - экземпляр класса TAdrSampleSource, который мы создали в п.3.
Третий параметр - флаг принудительного включения стриминга, если этот параметр = False то семпл по возможности будет загружен целиком, но при нехватке памяти будет, опять же, подкачиваться по частям.

4б. Создание эффекта

Эффект создается с помощью функции AdrOpenSoundEffect которая возвращает указатель на созданный экземпляр класса TAdrSoundEffect.

  SoundEffect := AdrOpenSoundEffect(AudioDevice, SampleSource, Adr_SoundEffectType_Multiple);
  SoundEffect.Ref;
 

Первым параметров функции передается экземпляр класса TAdrAudioDevice который мы создали в п.1.
Второй параметр - экземпляр класса TAdrSampleSource, который мы создали в п.3.
Третий параметр - тип эффекта. Adr_SoundEffectType_Single - при каждом новом вызове метода Play если уже существует проигрывающийся поток этого эффекта, то он будет замещен. Adr_SoundEffectType_Multiple - при каждом новом вызове метода Play будет создан новый поток, или замещен уже полностью проигравшийся поток из ранее созданных потоков этого эффекта.

5. Работа с созданными потоками/эффектами

Ну вот у нас есть наш канал/эффект, что же с ним делать?
А вот что:

* Проиграть/остановить - методы Play и Stop cоответственно.
Для эффекта вызов метода Play породит новый (или перезапишет старый) поток в котором будет проигрываться
копия его данных семпла, метод Stop отсутствует - как было сказано ранее мы не можем управлять созданными с помошью эффекта потоками.
* Управлять громкостью - методы SetVolume и GetVolume
* Управлять балансом - методы SetPan и GetPan
* Управлять частотой - методы SetPitchShift и GetPitchShift
* Для потока - управлять зацикливанием - методы SetRepeat и GetRepeat

Информацию об остальных методах можно посмотреть в прилагающимся хелпе.

6. Завершение работы

Чтобы освободить ресурсы надо просто вызвать UnRef всем тем экземплярам классов, у которых был вызван метод Ref.
Устройство воспроизведения, естесственно, освобождается в последнюю очередь.

  SoundEffect.UnRef;
  OutputStream.UnRef;
  SampleSource.UnRef;
  SoundFile.UnRef;
  AudioDevice.UnRef;
 

Вот в принципе и все. Все остальное можно посмотреть в хелпе, там все очевидно ;)

Афтар статьи - dRake (), если кто-то когда-то куда-то то б/п давайте сцылку на http://gamedev.ru и аффтара :)

17 ноября 2005

Комментарии [16]