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

В этой статье мы рассмотрим один из простейших способов работы со звуком при помощи кроссплатформенной библиотеки с открытым кодом Audiere.

Скачать свежую версию библиотеки Audiere можно с домашней страницы библиотеки http://audiere.sourceforge.net или http://aegisknight.org.

Audiere предоставляет простой и удобный объектно-ориентированный интерфейс для работы со звуком и поддерживает ряд основных форматов звуковых файлов, включая wav, mp3 и ogg.

Для работы со объектами библиотека использует smart pointer'ы, заворачивающие внутри себя указатели на объекты. При этом все объекты Audiere используют схему подсчета указателей (reference counting) позволяющую эффективно владеть объектами сразу из нескольких мест и удалять объекты, как только они становятся никому не нужными.

Ниже приводится исходный текст простейшей программы на С++, проигрывающей заданный в командной строке звук.

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <audiere.h>

using namespace audiere;

inline void sleepSecond ()
{
    Sleep ( 1000 );
}

int main ( int argc, const char * argv [] )
{
    if ( argc != 2 && argc != 3 )
    {
        printf ( "usage: simple <filename> [<device>]\n" );

	    return 1;
    }

    printf ( "initializing...\n" );

    const char * deviceName = "";

    if ( argc == 3 )
        deviceName = argv [2];

    AudioDevicePtr device = OpenDevice ( deviceName );

                                                   // check for errors
    if ( !device )
    {
        printf ( "OpenDevice() failed\n" );

        return 1;
    }

    printf ( "opened device %s\n", device -> getName () );

    OutputStreamPtr sound = OpenSound ( device, argv [1] );

    if ( !sound )
    {
        printf ( "OpenSound() failed\n" );

        return 1;
    }

    printf ( "opened sound\n" );

    sound -> play ();

    printf ( "started playback\n" );

    while ( sound -> isPlaying () )
    {
        sleepSecond ();

        if ( sound -> isSeekable () )
            printf ( "position: %d\n", sound -> getPosition () );
    }

    return 0;
}

Первое, что нужно сделать для использования Audiere это подключить ее заголовочный файл - audiere.h.

Поскольку библиотека помещает все свои объекты в пространство имен (namespace) audiere, то при работе с библиотекой надо или для каждого класса указывать его имя вместе с соответствующим пространством имен, т.е. писать вместо

audiere :: AudioDevicePtr device = audiere :: OpenDevice ( deviceName );

Альтернативой этому является после подключения заголовочного файла включить все определяемые имена из пространства имен audiere к текущему пространству имен при помощи команды

using namespace audiere;

Я лично предпочитаю второй способ, как обеспечивающий более компактную запись.

Кроме заголовочного файла audiere.h необходимо также подключить библиотеку audiere.lib.

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

В качестве имени устройств может выступать "autodetect", предоставляющее библиотеке самой выбрать наиболее подходящее устройство.

Под Windows в качестве имени устройства можно использовать "directsound" или "winmm", обеспечивающее вывод звука через DirectSound или через стандартную мультимедийную библиотеку winmm.lib.

Под Linux в качестве имени устройства может выступать "oss", обозначающее работу через Open Sound System.

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

Поэтому запись

AudioDevicePtr device = OpenDevice ();

вполне допустима и возвращает (smart) указатель на устройство, которое может в дальнейшем использоваться для воспроизведения звука.

Выражение !device вернет значение true, если устройство не удалось создать (это принятая в Audiere практика для любого smart-указателя на объект).

Следующим шагом после создания устройства является создание объектов, соответствующим звуковым файлам.

Для этого служит функция OpenSound, получающая в качестве первого параметра указатель на устройство, используемое для вывода звука. В качестве второго параметра может выступает имя файла или же указатель на объект, обеспечивающий загрузку звуковых данных.

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

Функция OpenSound возвращает указатель на объект, используемый для воспроизведения соответствующего звука.

Доступными пользователю методами являются:

void	play      ();
void	stop      ();
bool	isPlaying ();
void	reset     ();
void	setRepeat ( bool repeat );
bool	getRepeat ();
void	setVolume ( float volume );
float	getVolume ();
void	setPan    ( float pan );
float	getPan    ();
void	setPitchShift ( float shift );
float	getPitchShift ();
bool	isSeekable    ();
int     getLength     ();
void	setPosition   ( int pos );
int     getPosition   ();

Метод play включает воспроизведение данного звука. При этом воспроизведение происходит асинхронно, т.е. управление сразу же возвращается программе, а звук(музыка) начинает играть параллельно выполнению программы.

Обратите внимание, что в связи с этим в ключах компилятору и линкеру следует указать, что собирается многонитевое (multithreaded) приложение.

Метод stop останавливает воспроизведение звука.

Метод isPlaying возвращает значение true, если данный звук(музыка) в настоящий момент воспроизводится.

Метод reset сбрасывает звук и возвращает его к началу.

Метод setRepeat позволяет задать режим повторения звука, т.е. по окончании воспроизведения, звук снова проигрывается с самого начала и так далее.

Метод getRepeat возвращает текущее значение флага повторения звука.

Метод setVolume служит для задания громкости звучания, при этом значению 0.0 соответствует полная тишина (для данного звука), а значению 1.0 - максимальная громкость.

Метод getVolume позволяет узнать текущую громкость для данного звука.

Метод setPan служит для задания баланса. Значению -1.0 соответствует только левый канал, значению 1.0 соответствует только правый работающий канал. Значению 0.0 соответствует нормальный баланс (одинаковые значения для правого и левого каналов). По умолчанию установлено значение 0.0.

При помощи метода getPan можно узнать текущее значение баланса.

Метод setPitchShift позволяет задать сдвиг тональности и принимает значения от 0.5 до 2.0. По умолчанию установлено значение 1.0.

При помощи метода getPitchShift можно узнать текущее значение сдвига тона.

При помощи метода isSeekable можно узнать поддерживается ли для данного звука позиционирование. Само позиционирование осуществляется при помощи метода setPosition. Текущую позицию можно узнать при помощи метода getPosition.

Метод getLength возвращает длину звука.

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

При использовании smart-указателей для работы с объектом, как только соответствующий указатель выходит из области своего определения и уничтожается, вместе с ним уничтожается и соответствующий объект библиотеки Audiere.

Если необходимо явно уничтожить какой-либо объект библиотеки Audiere то достаточно будет просто присвоить соответствующему указателю значение NULL. Это приведет к уничтожению соответствующего объекта.

По этой ссылке можно скачать весь исходный код к этой статье. Также доступны для скачивания откомпилированные версии для M$ Windows, Linux.

Используются технологии uCoz