Разработчики не часто задумываются о высококачественном звуке на планшетах, а зря! Планшеты являются полнофункциональными мобильными развлекательными системами, и, когда пользователи понимают это, звук имеет огромное значение для подачи развлекательного содержимого.
Устройства на платформе Android* составляют свыше половины рынка планшетов, поэтому операционная система корпорации Google становится предпочитаемой платформой не только для портативных мобильных развлекательных устройств, но и для развлечений в целом. На платформе Android выпускается огромное множество устройств, и далеко не все из них способны предоставить хорошие развлекательные возможности.
Давайте посмотрим, каким образом можно повысить качество звука в Android-приложениях на планшетах со встроенным оборудованием Dolby Digital Plus.
В том, что касается высококачественного звука, следует учитывать три основных фактора.
- Производительность ЦП — без мощного процессора звук будет задерживаться или воспроизводиться неравномерно.
- Время работы от аккумулятора — обработка звука, как сказано выше, образует достаточную нагрузку на ЦП, поэтому мобильные развлекательные устройства должны долго работать от аккумуляторов.
- Качество звука — звук должен быть четким, громким, с ясно различимыми нюансами.
Мы выбрали планшет Samsung Galaxy Tab* 3 10.1 с процессором Intel® Atom™. По скорости работы он не уступает или превосходит все прочие устройства, поэтому производительность здесь точно не проблема. Высокая тактовая частота и использование двухъядерного процессора обеспечивают безупречное воспроизведение звука даже при многозадачной работе.
Кроме того, SoC Intel Atom, используемые в устройствах с Android, оптимизированы с точки зрения потребления электроэнергии, поэтому они очень долго работают от аккумулятора, что особенно характерно для Galaxy Tab 3.
Заключительный фактор — качество звука, здесь за него отвечает встроенное звуковое оборудование Dolby Digital Plus*. Аппаратные ресурсы Dolby предоставляют несколько важных компонентов, среди которых отметим следующие: Volume Maximizer — увеличение громкости звука без искажений; Audio Optimizer — существенное улучшение четкости звука с помощью проприетарных алгоритмов обработки звука Dolby.
Также отметим, что поскольку решение Dolby — аппаратное, оно не вызывает добавочной нагрузки на ЦП. При использовании оно практически не расходует вычислительные ресурсы системы.
Понятие «качество звука» как таковое носит в значительной степени субъективный характер, особенно в том, что касается уже записанного содержимого, но применяемый здесь кодек Dolby Digital Plus содержит целый набор технологий, которые стоит рассмотреть более подробно.
Технология аудиокодека Dolby Digital Plus
Звуковой кодек Dolby Digital Plus включает ряд технологий обработки звука, которые воздействуют на звуковое содержимое, воспроизводящееся на мобильном устройстве. Конечная цель кодека состоит в повышении субъективного качества звука. Следует отметить несколько технологий, связанных с воспроизведением музыки.
Volume Leveler
Volume Leveler непрерывно отслеживает воспроизводимый звук с помощью «психоакустической модели восприятия громкости» (в терминологии Dolby), которая определяет, насколько громким звук будет казаться человеку. Это значение используется для динамической регулировки уровня громкости, чтобы обеспечить одинаковую с точки зрения слушателя субъективную громкость. Одновременно применяется еще одна технология, Auditory Scene Analysis; ее цель — избежать неверной регулировки звука, в результате которой могут быть усилены звуки и моменты мелодии, намеренно сделанные тихими.
Специалисты Dolby заявляют, что Volume Leveler может независимо регулировать оба звуковых канала и даже отдельные частотные диапазоны, чтобы избежать эффекта «накачки» и «вибрации» при обработке звука.
Volume Maximizer
Одно из важных преимуществ кодека Dolby Digital Plus — это модуль Volume Maximizing, обеспечивающий достаточно громкий звук из маленьких динамиков, которыми обычно оснащаются мобильные устройства. После обработки звука в Volume Leveler модуль Maximizer увеличивает амплитуду звука на достаточно значительную величину, вплоть до 12 дБ.
Чтобы избежать чрезмерного усиления сигнала, которое может привести к обрезанию частотного диапазона, Volume Maximizer использует «упреждающий ограничитель». Ограничитель сочетает усиление сигнала с многодиапазонным сжатием для увеличения громкости звука без искажений.
Audio Optimizer
Частотный диапазон динамиков, которыми оборудуются мобильные устройства, зачастую далек от идеала. Другими словами, для разных частот может достаточно сильно различаться уровень звука. Из-за этого прослушиваемая музыка может звучать ненатурально или приглушенно. Технология Audio Optimizer применяет набор фильтров для обхода возможного несовершенства динамиков. Эти фильтры индивидуально подбираются для каждой модели устройства. Конечная цель — выдать естественный, сбалансированный звук с одинаковым уровнем воспроизведения всех частот, что для большинства устройств на практике означает повышение уровня низких и высоких частот.
Audio Regulator
Заключительный этап обработки музыки, интересующий нас как слушателей — это Audio Regulator. При увеличении громкости выходного звука на мобильных устройствах могут возникнуть искажения. Этот эффект может быть вызван самими усилителями, перегрузкой динамиков, резонансом или «треском» на смартфонах и планшетах. Такое поведение индивидуально для каждого устройства, оно может различаться для разных частот.
Regulator применяет многодиапазонное сжатие с учетом индивидуальных особенностей каждого конкретного устройства. И Audio Regulator, и Audio Optimizer калибруются в соответствии с уникальными особенностями каждого типа устройств.
Кроме того, для сохранения тембра звука при сжатии применяются ограничения.
И наконец, Regulator зависит от громкости. Можно в меньшей степени задействовать управление искажениями или отключать его при невысокой громкости.
Почему звук важен на мобильных устройствах?
Планшеты и смартфоны все чаще становятся предпочитаемыми устройствами для просмотра и потребления развлекательного содержимого. Хорошее качества звука достаточно сильно влияет на общее восприятие развлекательных материалов. Недавно компания Parks Associates провела исследование (по заказу Dolby) с целью оценки важности высококачественного звука. Это исследование показало, что в большинстве случаев владельцы смартфонов придают некоторое значение качеству звука при выборе смартфона или планшета.
Тем не менее, после прослушивания звуковой демонстрации с устройства с улучшенным воспроизведением многие пользователи признали, что качество звука немаловажно для их мобильных устройств.
После простой демонстрации технологии обработки звука Dolby Digital и вы с этим, скорее всего, согласитесь.
Использование API Dolby Audio в приложениях Android
Технологии Dolby позволяют очень просто повышать качество звука на устройствах Android, оснащенных аппаратным модулем Dolby Digital Plus. Портал Dolby Developer содержит бесплатный API для поддержки обработки звука Dolby в традиционных приложениях Java*, а также на некоторых сторонних платформах, включая Xamarin, Unity 3D* и Cordova*.
Решение Dolby Digital работает на аппаратном уровне, поэтому оно повышает качество звука вне зависимости от того, каким образом звук загружается и воспроизводится в исходном коде.
Для включения обработки звука Dolby Digital выполните следующие действия.
- Загрузите и установите API Dolby Digital в мобильное приложение по адресу developer.dolby.com.
- Получите инстанс объекта DolbyAudioProcessing. Это очень просто: достаточно вызвать GetDolbyAudioProcessing() из API Dolby.
- Создайте объект прослушивателя Dolby. Обычно объектом прослушивателя Dolby делается текущая Activity, чтобы упростить реализацию, но это может быть и отдельный класс.
Фрагмент кода Java показан ниже.
import com.dolby.dap.DolbyAudioProcessing;
import com.dolby.dap.OnDolbyAudioProcessingEventListener;
import com.dolby.dap.DolbyAudioProcessing.PROFILE;
public <strong>class</strong> MainActivity
extends Activity implements OnDolbyAudioProcessingEventListener
{
DolbyAudioProcessing mDolbyAudioProcessing;
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mDolbyAudioProcessing = DolbyAudioProcessing.getDolbyAudioProcessing(this, DolbyAudioProcessing.PROFILE.GAME, this);
if (mDolbyAudioProcessing == null){
Toast.makeText(this, "Dolby isn't available on this device", Toast.LENGTH_SHORT).show();
finish();
return;
}
}
...
}
Описание примера
Мне представилась возможность создать приложение для потоковой передачи звука, чтобы помочь независимым музыкантам в привлечении внимания и в демонстрации своей музыки. Важно было иметь устройство, пригодное для демонстрации как музыки, так и приложения. Поэтому по соображениям производительности, длительности работы от аккумулятора и качеству звука для этого проекта был выбран планшет Galaxy Tab 3 10.1 (86-разрядный).
Музыкальное содержимое передается в виде потока из SoundCloud и воспроизводится с помощью объекта MediaPlayer, входящего в состав API Android.
Чтобы можно было использовать код на других платформах (WPF, Магазин Windows* и т. д.), я использовал стороннее средство разработки, Xamarin Android, позволяющее писать собственные приложения для Android на .NET C#. Тем не менее, поскольку Xamarin использует собственные API Java Android, этапы разработки в целом такие же, как при написании приложений Java.
Пример использования API Dolby
Что касается Android Activity, отвечающей за воспроизведение мелодий, я решил сделать ее прослушивателем API Dolby Digital. Это означает, что она отвечает за прослушивание и реагирование на API Dolby Digital с помощью методов, определенных в IOnDolbyAudioProcessingEventListener. Также я реализовал в Activity интерфейс IOnCompletionListener объекта MediaPlayer, сделав его единой точкой воспроизведения. Такой подход неплохо работает, но можно выделить эти интерфейсы в отдельные классы, если это требуется архитектурой вашего приложения.
Моя подпись класса выглядит так:
public class Activity1 : Activity, MediaPlayer.IOnCompletionListener, IOnDolbyAudioProcessingEventListener.
Я поддерживаю экземпляры обоих объектов MediaPlayer доступными в качестве переменных на уровне классов. Обратите внимание, что объект DoblyAudioProcessing следует сделать статическим и не следует удерживать более одного экземпляра этого объекта в приложении. Если требуется доступ к объекту DolbyAudioProcessing из Activity, следует предоставить доступ к нему с помощью одноэлементного класса или какого-либо типа глобальной ссылки.
Для инициализации обработки звука Dolby я создал вспомогательный метод InitAudio(), чтобы безопасно получить ссылку на объект DolbyAudioProcessing. Поскольку по прежнему необходима совместимость с другими устройствами, этот метод непригоден для устройств, не оборудованных кодеком Dolby.
При запросе объекта обработки я также задаю режим обработки Dolby Digital. В этом случае я выбрал режим музыки, предназначенный для повышения четкости звука, баланса и ощущаемой громкости. Улучшения звука заметны при использовании встроенных динамиков устройства, наушников или линейного выхода на внешнее звуковое оборудование.
void InitAudio()
{
if (mDolbyAudioProcessing != null)
return;
mDolbyAudioProcessing = DolbyAudioProcessing.GetDolbyAudioProcessing(this, DolbyAudioProcessing.PROFILE.Music, this);
if (mDolbyAudioProcessing == null)
{
Toast.MakeText(this, "Dolby Audio Processing load failed", ToastLength.Short).Show();
return;
}
}
}
И наконец, я проверяю и сохраняю состояние обработки Dolby, когда действие запускается, и восстанавливаю состояние, когда наше приложение работает в фоновом режиме или закрывается. Оборудование Dolby Digital влияет на весь звук, воспроизводящийся на устройстве, поэтому это очень важный шаг, и он легко осуществляется с помощью методов управления жизненным циклом действия onResume() и onPause().
API SoundCloud
API SoundCloud позволяет создавать приложения, использующие всю функциональность веб-сайта SoundCloud. HTTP-запросы отправляются к набору URL-адресов конечных точек для запроса информации и выполнения действий.
Работа с API SoundCloud хорошо документирована, но, поскольку сам этот API достаточно сложен, в нем поначалу может быть непросто разобраться. Сначала следует изучить документацию REST.
Самый простой способ начать работу — использовать оболочку API Java, доступную на портале GitHub; тем не менее я опишу процесс внедрения SoundCloud вручную.
Нужно создать идентификатор клиента SoundCloud, который является уникальным идентификатором для вашего приложения. Это следует делать при взаимодействии с другими API REST для доступа к общедоступному содержимому.
Воспроизведение содержимого SoundCloud
Рассмотрим процесс доступа к определенному исполнителю в SoundCloud, загрузки информации об альбоме, чтения отдельных мелодий и воспроизведения. Для этого мы будем взаимодействовать со службой RESTful SoundCloud и декодировать возвращаемые данные JSON.
Шаг 1. Создайте идентификатор клиента
Как было сказано выше, этот идентификатор бесплатен, его можно создать здесь.
Он будет выглядеть примерно так: 7de8bc189e5ba2ab12fa4223951fabb8.
Шаг 2. Найдите идентификатор исполнителя
Нужно найти идентификатор пользователя исполнителя, чью музыку следует воспроизводить. Это можно сделать непосредственно на веб-сайте SoundCloud или с помощью API SoundCloud. Поскольку мы только изучаем API, я покажу способ быстро найти идентификатор вручную. Откройте страницу любого исполнителя непосредственно на сайте SoundCloud, щелкните Share, а затем Embed. В окне Code & Preview вы увидите тег iFrame. Внутри него вы увидите ссылку, которая будет выглядеть примерно так: https%3A//api.soundcloud.com/users/547647. Число — это нужный нам идентификатор исполнителя.
Шаг 3. Создание запроса для загрузки альбомов
Сейчас мы создадим первый запрос к API SoundCloud. Начнем с адреса API, а затем соберем полный URL-адрес с помощью идентификатора исполнителя с шага 2 и нашего собственного идентификатора клиента с шага 1.
string request = "http://api.soundcloud.com/" + "users/" + artistID + "/playlists.json?client_id=" + clientID;
Шаг 4. Отправьте запрос
Теперь просто отправьте запрос. Мое приложение написано на C#, поэтому код выглядит так:
public async Task<string> GetUserPlaylists ()
{
HttpClient client = new HttpClient ();
var request = "http://api.soundcloud.com/" + "users/" + artistID + "/playlists.json?client_id=" + clientID;
HttpResponseMessage response = await client.GetAsync (request);
return await response.Content.ReadAsStringAsync ();
}
Краткое замечание. Этот код может работать на любой современной платформе .NET, которая включает Microsoft HttpClient, в том числе WPF, Магазин Windows или Silverlight*.
Шаг 5. Проведите десериализацию объекта
Здесь можно использовать вашу любимую библиотеку JSON. Когда я пишу код .NET, я использую библиотеку Newtonsoft Json.
_setLists = Newtonsoft.Json.JsonConvert.DeserializeObject<List<AlbumData>>(response);
Переменная response является результатом применения метода GetUserPlaylists() на предыдущем шаге. Мы получим список объектов AlbumData (определенных ниже).
Шаг 6. Создание URL-адреса мелодии
Скорее всего, вы предпочтете представить пользователям набор альбомов, чтобы они выбрали нужный, в ListView; я не буду подробно описывать создание пользовательского интерфейса.
Ниже приведен код объекта передачи данных AlbumData. Обратите внимание, что внизу он содержит список объектов TrackData, представляющих отдельные мелодии.
К счастью, данные, использованные для заполнения объекта TrackData, содержат URL-адрес для воспроизведения.
Шаг 7. Воспроизведение мелодии
И наконец, воспроизведение звука с удаленного URL-адреса с помощью потоковой передачи по протоколу HTTP на платформе Android выглядит так:
String url = myTrack.StreamURL;
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.SetAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.SetDataSource(url);
mediaPlayer.Prepare();
mediaPlayer.Start();
Где myTrack — конкретный экземпляр TrackData мелодии, которую мне нужно воспроизвести.
Объекты передачи данных SoundCloud
На этом этапе я хочу показать объекты AlbumData и TrackData. API SoundCloud очень просто использовать, если у вас нет желания писать значительный объем кода для анализа JSON, но мы будем использовать объекты передачи данных (DTO) для хранения проанализированных данных JSON.
Для просмотра альбомов и воспроизведения мелодий нам потребуется два объекта DTO: один будет представлять данные альбома, а второй — отдельные мелодии. Я включил два моих объекта DTO ниже в коде C#. Они приведены полностью, вы можете использовать их в своих проектах.
Если вам требуется работать с API SoundCloud на более глубоком уровне, то может потребоваться создать дополнительные объекты DTO.
AlbumData.cs
using Newtonsoft.Json;
using System.Collections.Generic;
namespace SoundCloud.Json
{
public class AlbumData
{
[JsonProperty("id")]
public string Id { get; internal set; }
[JsonProperty("created_at")]
public string CreatedAt { get; internal set; }
[JsonProperty("user_id")]
public string UserId { get; internal set; }
[JsonProperty("user")]
public UserData User { get; internal set; }
[JsonProperty("title")]
public string Title { get; internal set; }
[JsonProperty("permalink")]
public string Permalink { get; internal set; }
[JsonProperty("permalink_url")]
public string PermalinkUrl { get; internal set; }
[JsonProperty("uri")]
public string Uri { get; internal set; }
[JsonProperty("sharing")]
public string Sharing { get; internal set; }
[JsonProperty("embeddable_by")]
public string EmbeddableBy { get; internal set; }
[JsonProperty("purchase_url")]
public string PurchaseUrl { get; internal set; }
[JsonProperty("artwork_url")]
public string ArtworkUrl { get; internal set; }
[JsonProperty("description")]
public string Description { get; internal set; }
[JsonProperty("label")]
public UserData Label { get; internal set; }
[JsonProperty("duration")]
public int Duration { get; internal set; }
[JsonProperty("genre")]
public string Genre { get; internal set; }
[JsonProperty("tag_list")]
public string TagList { get; internal set; }
[JsonProperty("label_id")]
public string LabelId { get; internal set; }
[JsonProperty("label_name")]
public string LabelName { get; internal set; }
[JsonProperty("streamable")]
public bool Streamable { get; internal set; }
[JsonProperty("downloadable")]
public bool Downloadable { get; internal set; }
[JsonProperty("tracks")]
public List<TrackData> Tracks { get; internal set; }
}
}
TrackData.cs
using System;
using Newtonsoft.Json;
namespace SoundCloud.Json
{
[JsonObject]
public class TrackData
{
[JsonProperty("id")]
public long Id { get; internal set; }
[JsonProperty("created_at")]
public DateTime CreatedAt { get; internal set; }
[JsonProperty("user_id")]
public long UserId { get; internal set; }
[JsonProperty("duration")]
public long Duration { get; internal set; }
[JsonProperty("commentable")]
public bool Commentable { get; internal set; }
[JsonProperty("state")]
public string State { get; internal set; }
[JsonProperty("sharing")]
public string Sharing { get; internal set; }
[JsonProperty("tag_list")]
public string TagList { get; internal set; }
[JsonProperty("permalink")]
public string Permalink { get; internal set; }
[JsonProperty("description")]
public string Description { get; internal set; }
[JsonProperty("streamable")]
public bool Streamable { get; internal set; }
[JsonProperty("downloadable")]
public bool Downloadable { get; internal set; }
[JsonProperty("genre")]
public string Genre { get; internal set; }
[JsonProperty("release")]
public string Release { get; internal set; }
[JsonProperty("purchase_url")]
public string PurchaseUrl { get; internal set; }
[JsonProperty("label_id")]
public string LabelId { get; internal set; }
[JsonProperty("label_name")]
public string LabelName { get; internal set; }
[JsonProperty("isrc")]
public string ISRC { get; internal set; }
[JsonProperty("video_url")]
public string VideoUrl { get; internal set; }
[JsonProperty("track_type")]
public string TrackType { get; internal set; }
[JsonProperty("key_signature")]
public string KeySignature { get; internal set; }
[JsonProperty("bpm")]
public long? BPM { get; internal set; }
[JsonProperty("title")]
public string Title { get; internal set; }
[JsonProperty("release_year")]
public string ReleaseYear { get; internal set; }
[JsonProperty("release_month")]
public string ReleaseMonth { get; internal set; }
[JsonProperty("Release_day")]
public string ReleaseDay { get; internal set; }
[JsonProperty("original_format")]
public string OriginalFormat { get; internal set; }
[JsonProperty("license")]
public string License { get; internal set; }
[JsonProperty("uri")]
public string Uri { get; internal set; }
[JsonProperty("permalink_url")]
public string PermalinkUrl { get; internal set; }
[JsonProperty("artwork_url")]
public string ArtworkUrl { get; internal set; }
[JsonProperty("waveform_url")]
public string WaveformUrl { get; internal set; }
[JsonProperty("user")]
public UserItemData User { get; internal set; }
[JsonProperty("stream_url")]
public string StreamUrl { get; internal set; }
[JsonProperty("download_url")]
public string DownloadUrl { get; internal set; }
[JsonProperty("playback_count")]
public long PlaybackCount { get; internal set; }
[JsonProperty("download_count")]
public long DownloadCount { get; internal set; }
[JsonProperty("favoritings_count")]
public long FavoritingsCount { get; internal set; }
[JsonProperty("comment_count")]
public long CommentCount { get; internal set; }
[JsonProperty("attachments_uri")]
public string AttachmentsUri { get; internal set; }
}
}
Заключение и выводы
SoundCloud
Приведенная выше информация послужит хорошим фундаментом для начала работы с SoundCloud. Если же требуется более глубокая реализация, например отправка или управление содержимым, потребуется создать дополнительные объекты передачи данных и убедиться, что данные в вашем приложении являются синхронными с SoundCloud. Если вы разрабатываете программы на Java, то имеет смысл заглянуть в Android Sharing Kit.
Dolby Digital и SoundCloud
В службах потоковой передачи звука распространена проблема, связанная с неодинаковым уровнем звука у разных файлов. Это никак не повлияет на предоставление службой содержимого, но очень хорошо, если API Dolby Digital нормализует громкость. Разница в уровнях становится особенно заметна при переключении между мелодиями разных исполнителей.
Android MediaPlayer
Объект MediaPlayer в API Android удобен для воспроизведения локального или потокового звукового содержимого, но его нельзя считать универсальным решением: он работает не всегда. При создании приложений для Android всегда следует проводить тестирование на как можно большем количестве устройств, причем это особенно важно, если речь идет об объекте MediaPlayer. Не следует надеяться на то, что он «просто заработает» на всех устройствах, даже если при тестировании все было идеально. Это особенно касается менее мощных устройств. Попробуйте использовать функции альфа- и бета-тестирования магазина Google Play или используйте службу тестирования, позволяющую запустить ваше приложение на самых разных телефонах и планшетах.
Производительность
Как было сказано выше, будьте осторожнее с MediaPlayer, поскольку на маломощных устройствах он может не работать должным образом. Кроме того, обязательно оптимизируйте другие части вашего приложения, чтобы звук воспроизводился без перерывов. Всегда запускайте код, ожидающий веб-службы, отдельно от пользовательского интерфейса, применяйте такие методики, как повторное использование ячеек и View Holder в списочных элементах управления, чтобы снизить объем используемой памяти и повысить производительность. Полезные советы по оптимизации см. в документации Плавная прокрутка ListView.
Устройства
Планшет Samsung Galaxy Tab 3 10.1 оказался великолепным демонстрационным устройством, и мне очень понравилось улучшение звука, достигнутое аппаратной обработкой потокового содержимого кодеком Dolby Digital. Этот кодек доступен не на всех устройствах, но все равно имеет смысл интегрировать API Dolby Digital в ваши приложения Android. Реализовать такое решение можно очень быстро, при этом оно существенно улучшает четкость выходного звука.
Дальнейшие действия
Планшет Samsung Galaxy Tab 3 10.1 по-прежнему весьма конкурентоспособен, но рынок мобильных устройств стремительно развивается. Скоро на рынке появятся планшеты с новыми четырехъядерными процессорами Intel Atom. Dell Venue* 8 7000 станет ведущим в своем классе устройством после выпуска в IV квартале 2014 года. Кроме того, оборудование Dolby Digital Plus довольно широко распространено. Компания Lenovo, крупный производитель мобильных устройств, выпускает несколько планшетов, оснащенных кодеком Dolby. Я недавно переключился на Lenovo S8-50f в качестве основного устройства для разработки на платформе Android. Это устройство оборудовано четырехъядерным SoC Intel Atom Z3745 архитектуры x86, 2 ГБ оперативной памяти и, разумеется, кодеком Dolby Digital Plus.
Ссылки по теме
- Сообщество Android-разработчиков на IDZ
- Средства разработки Intel
- Оригинал статьи: High-Quality Audio on Intel® Atom™-powered Android* Tablets using the Dolby* Digital API
Автор: saul