Введение

Symbian OS предоставляет в распоряжения разработчиков богатые возможности для работы со звуком. В данной статье рассмотрены вопросы воспроизведения и записи звука в Symbian OS C++ приложениях.

Для работы со звуком в Symbian OS v7.0 добавлен новый межуровневый компонент, называемых Multimedia Framework (MMF). MMF базируется на ECOM plug-in архитектуре. MMF работает с Symbian Audio контроллером. Этот контроллер имеет каждое Symbian OS v7.0 устройство. (Кроме него в системе могут существовать и другие аудио контроллеры, например Advanced Audio Controller (в устройствах фирмы Nokia), но работа с ними останется за рамками этой статьи.)

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

Воспроизведение звукового контента

MMF способен обеспечить локальное и потоковое воспроизведение звуковой информации различных форматов. Программисты могут использовать эти возможности через специальный API, включающий в себя такие функции как Play, Stop и Pause, а также функции по управлению метаданными.

Поддержка локальных звуковых форматов

MMF использует plug-in архитектуру, то есть позволяет проводить распознавание форматов и динамическую загрузку необходимых кодеров/декодеров перед непосредственным воспроизведением звука. Это позволяет устройству поддерживать любые аудио форматы, для которых имеются подходящие декодеры.

Несмотря на то, что MMF использует plug-in архитектуру, Wave формат поддерживается по-умолчанию всеми устройствами. Многие устройства поддерживают и другие популярные форматы (Wave, AMR, MIDI, MP3, AAC, Real Audio).

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

MMF не способна работать с форматами-оболочками (MP4, 3GP, ...).

API для воспроизведения звука

MMF предоставляет в распоряжение разработчика простой API, который не зависит ни от формата, ни от типа аудио данных. Этот API используется для работы как с локальным, так и с потоковым контентом. Он обеспечивается следующими классами:

  • CMdaAudioPlayerUtility - Audio Player API для работы с звуковым контентом, а также для некоторых операций над метаданными.
  • MMdaAudioPlayerCallback - Callback API для класса CMdaAudioPlayerUtility, который сообщает об ошибках и уведомляет приложения о статусе операции открытия файла или завершения его проигрывания.

Эти классы расположены в библиотеке MediaClientAudio.lib.

Работа со звуковым контентом

В этом разделе мы обсудим использования класса CMdaAudioPlaybackUtility для решения следующих задач:

  • Выбор файла для открытия.
  • Начало воспроизведения.
  • Управление громкостью.
  • Работа с паузой.
  • Остановка воспроизведения.
  • Запрос метаданных.

Все операции, реализованные классом CMdaAudioPlaybackUtility являются асинхронными. Observer callback API состоит из следующих двух методов:

  • void MapcInitComplete(TInt aError, const TTImeIntervalMicroSeconds& aDuration);
  • void MapcPlayComplete(TInt aError);

Эти методы вызываются после завершения инициализации воспроизведения и завершения воспроизведения аудиотрека.

Чтобы выполнить операции воспроизведения, необходимо первым делом создать объект класса CMdaAudioPlayerUtility.

CMdaAudioPlayerUtility* iPlayer = CMdaAudioPlayerUtility::NewL(*this);

Замечание: При создании объекта класса CMdaAudioPlayerUtiltiy можно задать приоритет и предпочтение. Эти параметры являются дополнительными и по умолчанию имеют значения EPriorityNormal и EMdaPriorityPreferenceTimeAndQuality.

После создания объекта, необходимо инициализировать плеер и открыть файл или URL. Файл можно открыть используя его полное имя, либо указатель.

  • iPlayer->OpenFileL( aFilename );
  • iPlayer->OpenDesL( aDescriptor );
  • iPlayer->OpenUrlL( aUrl );

Выполнить операцию открытия файла можно непосредственно при создании объекта плеера:

  • CMdaAudioPlayerUtility* iPlayer = CMdaAudioPlayerUtility::NewFilePlayerL(aFilename, *this);
  • CMdaAudioPlayerUtility* iPlayer = CMdaAudioPlayerUtility::NewDesPlayerL(aDescriptor, *this);
  • CMdaAudioPlayerUtility* iPlayer = CMdaAudioPlayerUtility::NewDesPlayerReadOnlyL(aDescriptor, *this);

После завершения операции открытия, нужно вызвать метод MapcInitComplete(). Этот метод возвращает информацию об ошибках, произошедших в процессе открытия. Если все прошло успешно, будет возвращено значение KErrNone. После этого можно приступать к воспроизведению:

iPlayer->Play();

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

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

  • iPlayer->SetVolume( aVolume );
  • iPlayer->SetRepeats( aRepeatNumberOfTimes, aTrailingSilenceMicroSeconds );
  • iPlayer->SetVolumeRamp( aRampDuration );
  • iPlayer->SetPriority( aPriority );
  • iPlayer->SetPosition( aPositionMicroSeconds );

Для получения информации о воспроизведении используйте методы:

  • TTimeIntervalMicroSeconds aDuration = iPlayer->Duration();
  • TTimeIntervalMicroSeconds apposition = iPlayer->Position();
  • TInt aVolume = iPlayer->MaxVolume();

Для остановки(паузы) и продолжения воспроизведения:

  • iPlayer->Pause();
  • iPlayer->Play();

Для завершения воспроизведения

iPlayer->Stop();

После завершения воспроизведения, вызывается метод MapcComplete(), содержащий информацию об ошибках.

После завершения работы с контентом, необходимо закрыть файл и очистить память:

iPlayer->Close();

Поддержка метаданных

Метаданными мы будем называть информацию о аудиотреке, встроенную в заголовок звукового файла. Наибольшее распространенным типом метаданных на сегодняшний день является ID3Tag, используемый в MP3 файлах. Операции CMMFMetaDataEntry API основаны на конвертировании информации, извлеченной из трека. Этот API физически расположен в библиотеке MMFControllerFramework.lib.

Помимо ID3Tag CMMFMetaDataEntry API поддерживает и другие типы метаданных.

При использовании CMMFMetaDataEntry API нужно сначала запросить систему о количестве доступных для указанного файла метаданных.

CMdaAudioPlayerUtility* iPlayerHelper = CMdaAudioPlayerUtility::NewL( *this );
iPlayerHelper->OpenFileL( aFilename );
User::LeaveIfError( iPlayerHelper->GetNumberOfMetaDataEntries( aNumEntries ));

Каждая порция метаданных ставится в соответствие поддерживаемым ID3Tag полям (табл 1).

EntryName элементы Описание
KMMFMetaEntrySongTitle Название песни
KMMFMetaEntryAlbum Название альбома
KMMFMetaEntryArtist Имя исполнителя
KMMFMetaEntryAlbumTrack Номер трека в альбоме
KMMFMetaEntryYear Год выхода альбома
KMMFMetaEntryGenre Жанр музыки
KMMFMetaEntryCopyright Информация о правообладателе
KMMFMetaEntryComment Комментарии к треку
KMMFMetaEntryComposer Информация о композиторе
KMMFMetaOriginalArtist Информация об артисте, исполняющем оригинал

HBufC* metadataValue=NULL;
for( TInt j=0; j< aNumEntries; j++)
{
CMMFMetaDataEntry* entry=NULL;
TRAPD( errorValue, entry= iPlayerHelper->GetMetaDataEntryL(j));
CleanupStack::PushL(entry);
if(( errorValue== KErrNone)&amp;&amp;( entry))
{
TName name( entry->Name());
TName value( entry->Value());
CleanupStack::PopAndDestroy(entry);
if( name.CompareF( aMetadataName)==0)
{
//Нуль-конец строки
TInt i= value.LocateF('\0');
if(i!= KErrNotFound)
{
value.SetLength(i);
}
metadataValue= value.AllocLC();
break;
}
}
else
{
CleanupStack::PopAndDestroy(entry);
if(( errorValue!= KErrNotFound)&amp;( errorValue!= KErrNotSupported))
{
User::LeaveIfError( errorValue);
}
}
}

Воспроизведение потоковых данных

Возможность работы с потоками данных позволяет разработчику воспользоваться альтернативным способом получения звукового контента. Использование потоковых данных имеет два преимущества по сравнению с локальным контентом. Во-первых, поскольку контент не сохраняется в файловой системе устройства, он не может быть скопирован; во-вторых, потоковый контент легче обновлять.

Устройства поддерживают несколько потоковых форматов. Практически все устройства по-умолчанию умеют работать с mp3 и Real Audio.

API для работы с потоковым звуком

Для проигрывания потокового контента используются интерфейсы CMdaAudioPlayerUtility,CMdaAudioOutputStream и CMdaAudioInputStream. Единственным отличием от проигрывания локального контента является способ открытия и инициализации. Метаданные для потокового контента могут быть получены аналогично локальному.

Ограничения

Как уже отмечалось ранее, MMF не поддерживает форматы-оболочки, поэтому потоковые файлы, такие как AAC, помещенные внутрь MP4, не могут быть воспроизведены. Ссылки на Real Audio файлы, помещенные внутрь *.ram файла, должны быть предварительно извлечены и открыты с помощью метода OpenUrlL(). MMF не поддерживает автоматическое извлечение ссылок из *.ram файлов. Более подробную информацию об извлечении можно найти в документе"Video And Streaming In Nokia Devices".

Необходимо аккуратно относиться к кодированию потоковых файлов. Так из-за плохой пропускной способности сетей файлы, bit rate которых превосходит 192 Kbps, воспроизводятся с заиканием и заметными задержками.

Запись звука

В Symbian OS v7.0 устройствах MMF помимо воспроизведения позволяет осуществлять и запись аудиоинформации.

Как правило, устройства позволяют сохранять записанный звук в форматах WAV и AMR. С помощью присоединения plug-in-ов может быть добавлена поддержка и других форматов.

API для записи звука

При записи звука используется та же библиотека (MediaClientAudio.lib), что и при его воспроизведении. Для записи используются классы:

  • CMdaAudioRecorderUtility - служит для манипулирования аудио файлами и осуществления операции записи.
  • CMdaAudioPlayerUtility - служит для работы с плеером и исправления метаданных.
  • MMdaObjectStateChangeObserver - Callback API для класса CMdaAudioRecorderUtility, предназначенный для получения информации об ошибках и о состоянии текущей записи.

Класс CMdaAudioPlayerUtility используется при записи для решения вспомогательных задач, например CMdaAudioRecorderUtility не умеет изменять громкость и для этих целей используется CMdaAudioPlayerUtility.

Класс CMdaAudioRecorderUtility реализует набор базовых операций, таких как PlayL(), Stop() и OpenFile(), а также методы для записи Crop() и Record().

Пример записи звука

Процессы записи и воспроизведения очень похожи. Основное внимание в этом разделе будет уделено использованию класса CMdaAudioRecorderUtility.

При реализации класса CMdaAudioRecorderUtility необходимо унаследовать и получить абстрактный класс, состоящий из единственного метода.

void MoscoStateChangeEvent(CBase* aObject, TInt aPreviousState, TInt aCurrentState, TInt aErrorCode);.

Этот метод будет изменяться каждый раз при изменении состояния CMdaAudioRecorderUtility.

Для начала записи необходимо создать экземпляр класса CMdaAudioRecorderUtility:

CMdaAudioRecorderUtility iRecorder = CMdaAudioRecorderUtility::NewL(*this)

Замечание: При создании объекта класса CMdaAudioRecorderUtility можно задать приоритет и предпочтение. Эти параметры являются дополнительными и по умолчанию имеют значения EMdaPriorityNormal и EMdaPriorityPreferenceTimeAndQuality. Для нормальной записи рекомендуется немного повысить приоритет хотя бы до 80 (100-максимальный).

После создания экземпляра класса CMdaAudioRecorderUtility необходимо открыть файл, куда будет сохраняться информация. Это нужно сделать до начала записи. Открыть файл можно либо используя его полное имя, либо указатель на файл.


  • iRecorder->OpenFileL( aFilename );
  • iRecorder->OpenDesL( aDescriptor );


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

iRecorder->RecordL();.

Для остановки процесса записи используется метод Stop():

iRecorder->Stop();

Каждый раз после остановки записи рекомендуется закрывать открытый файл (если конечно не предполагается использовать этот же файл для следующей сессии записи).

iRecorder->Close();

После того как файл открыт и выполнены операции воспроизведения или записи, callback функция MoscoStateChangeEvent() будет возвращать информацию о текущем или предыдущем состоянии процесса.

Ограничения

MMF не позволяет весьти запись во время телефонного разговора.


Оригинал: Symbian OS: Creating Audio Applications In C++ Version 1.0 May 11, 2005.
Перевод:aRix




Наши соцсети

Подписаться Facebook Подписаться Вконтакте Подписаться Twitter Подписаться Google Подписаться Telegram

Популярное

Ссылки

Новости [1] [2] [3]... Android/ iOS/ J2ME[1] [2] [3]) Android / Архив

Рейтинг@Mail.ru Яндекс.Метрика
MobiLab.ru © 2005-2018
При использовании материалов сайта ссылка на www.mobilab.ru обязательна