Форматы данных

Android использует множество внутренних форматов аудиоданных, некоторые из которых доступны в общедоступных API, форматах файлов и на аппаратно-зависимом уровне.

Свойства

Форматы аудиоданных классифицируются по следующим свойствам:

Сжатие
Несжатый, сжатый без потери качества или сжатый с потерей качества. PCM – самый распространенный формат несжатого аудио. FLAC – это формат сжатия без потерь, а MP3 и AAC – сжатия с потерями.
Битовая глубина
Количество значимых битов в аудиосемпле.
Размер контейнера
Количество битов, используемых для хранения или передачи семпла. Обычно это значение совпадает с глубиной цвета, но иногда для выравнивания выделяются дополнительные биты. Например, 24-битный фрагмент может содержаться в 32-битном слове.
Выравнивание
Если размер контейнера точно равен глубине цвета, представление называется упакованным. В противном случае представление будет распакованным. Значимые биты образца обычно выравниваются по левому (наиболее значимому) или правому (наименее значимому) биту контейнера. Термины упакованный и неупакованный обычно используются, когда глубина цвета не является степенью двойки.
Signedness
Подписаны ли образцы.
Способ отображения
Фиксированная или плавающая точка (см. ниже).

Представление с фиксированной точкой

Фиксированная запятая – наиболее распространенный способ представления несжатых аудиоданных PCM, особенно в аппаратных интерфейсах.

Число с фиксированной точкой имеет постоянное количество цифр до и после точки основания системы счисления. Во всех наших представлениях используется основание 2, поэтому мы заменяем цифру на бит, а десятичную точку на двоичную точку или просто точку. Биты слева от точки – это целая часть, а биты справа – дробная часть.

Мы говорим о целочисленном PCM, поскольку значения с фиксированной точкой обычно хранятся и обрабатываются как целые числа. Интерпретация как числа с фиксированной точкой подразумевается.

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

|largest negative value| = |largest positive value| + 1

Запись через Q и U

Существуют разные обозначения для представления чисел с фиксированной запятой в виде целых чисел. Мы используем Q-формат: Qm.n означает m целых битов и n дробных битов. "Q" считается одним битом, хотя значение выражается в дополнительном коде. Общее количество битов равно m + n + 1.

Um.n – для беззнаковых чисел: m – целая часть, n – дробная часть, а "U" считается как ноль битов. Общее количество битов – m + n.

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

Запись с плавающей запятой

Числа с плавающей запятой – это альтернатива числам с фиксированной запятой, в которых положение запятой может меняться. Основные преимущества записи с плавающей запятой:

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

Раньше операции с плавающей запятой выполнялись медленнее, чем операции с целыми числами или числами с фиксированной запятой, но сейчас они часто выполняются быстрее, если решения о потоке управления не зависят от результатов вычислений.

Форматы аудиофайлов для Android

Основные форматы аудиофайлов для Android перечислены в таблице ниже.

Нотация
Свойство Q0.15 Q0.7 1 Q0.23 Q0.31 float
Контейнер
бит
16 8 24 или 32 2 32 32
Значимые биты
включая знак
16 8 24 24 или 32 2 25 3
Запас по уровню
в дБ
0 0 0 0 126 4
Динамический диапазон
в дБ
90 42 138 138–186 900 5

Все перечисленные выше форматы с фиксированной запятой имеют номинальный диапазон от -1,0 до +1,0 минус один младший значащий бит. Отрицательных значений на одно больше, чем положительных, из-за представления в дополнительном коде.

Сноски:

  1. Во всех перечисленных выше форматах используются значения со знаком. 8-битный формат обычно называют "беззнаковым", но на самом деле это знаковое значение со смещением 0.10000000.
  2. Q0.23 может быть упакован в 24 бита (три 8-битных байта, прямой порядок байтов) или распакован в 32 бита. Если данные распакованы, значимые биты выравниваются по правому краю по направлению к младшему значащему биту с дополнением знака по направлению к старшему значащему биту (Q8.23) или выравниваются по левому краю по направлению к старшему значащему биту с заполнением нулями по направлению к младшему значащему биту (Q0.31). Теоретически формат Q0.31 позволяет использовать до 32 значащих битов, но аппаратные интерфейсы, которые принимают данные в этом формате, редко используют все биты.
  3. Число с плавающей запятой одинарной точности имеет 23 явных бита, один скрытый бит и знаковый бит, что в сумме дает 25 значащих битов. Денормализованные числа имеют меньше значащих битов.
  4. Значения с плавающей запятой одинарной точности могут достигать ±1,7e+38, что объясняет большой запас.
  5. Показанный динамический диапазон относится к денормализованным значениям до номинального максимума ±1,0. Обратите внимание, что некоторые реализации чисел с плавающей запятой, относящиеся к определенной архитектуре, например NEON, не поддерживают денормализованные числа.

Конверсии

В этом разделе рассказывается о преобразовании данных между разными представлениями.

Конвертация чисел с плавающей запятой

Чтобы преобразовать значение из формата Qm.n в число с плавающей запятой:

  1. Преобразуйте значение в число с плавающей запятой, как если бы оно было целым числом (игнорируя точку).
  2. Умножьте на 2-n.

Например, чтобы преобразовать внутреннее значение Q4.27 в значение с плавающей запятой, используйте следующий код:

float = integer * (2 ^ -27)

При преобразовании чисел с плавающей запятой в числа с фиксированной запятой действуют следующие правила:

  • Номинальный диапазон значений с плавающей запятой одинарной точности составляет ±1,0, а полный диапазон для промежуточных значений – ±1,7e+38. При преобразовании между форматами с плавающей и фиксированной запятой для внешнего представления (например, при выводе на аудиоустройства) будет учитываться только номинальный диапазон, а значения, выходящие за его пределы, будут ограничиваться. В частности, при преобразовании значения +1,0 в формат с фиксированной точкой оно ограничивается значением +1,0 минус один младший значащий бит.
  • В представлении допускаются денормализованные (субнормальные) числа и +/- 0.0, но при обработке они могут быть незаметно преобразованы в 0.0.
  • Бесконечность будет либо передаваться через операции, либо незаметно ограничиваться значением +/- 1,0. Обычно последний используется для преобразования в формат с фиксированной запятой.
  • Поведение NaN не определено: NaN может распространяться как идентичный NaN, или может быть преобразован в NaN по умолчанию, может быть автоматически жестко ограничен до +/- 1,0, или автоматически преобразован в 0,0, или привести к ошибке.

Конверсии с фиксированной точкой

При преобразовании между разными форматами Qm.n действуют следующие правила:

  • Если значение m увеличивается, целая часть слева дополняется знаком.
  • Если m уменьшается, зафиксируйте целую часть.
  • Если значение n увеличивается, дробная часть дополняется нулями справа.
  • Если значение n уменьшается, лишние дробные биты справа удаляются с помощью дитеринга, округления или усечения.

Например, чтобы преобразовать значение Q4.27 в Q0.15 (без дизеринга или округления), сдвиньте значение Q4.27 вправо на 12 бит и ограничьте все результаты, превышающие 16-битный диапазон со знаком. Это выравнивает точку представления Q.

Чтобы преобразовать число из формата Q7.24 в формат Q7.23, выполните деление на 2 со знаком или, что то же самое, добавьте знаковый бит к целому числу в формате Q7.24, а затем выполните сдвиг вправо на один бит со знаком. Обратите внимание, что простой сдвиг вправо со знаком не эквивалентен делению на 2 со знаком.

Преобразования с потерями и без потерь

Конверсия является без потерь, если она обратима: конверсия из A в B в C приводит к A = C. В противном случае преобразование будет выполнено с потерями.

Конверсии без потери качества позволяют выполнять конвертацию формата с возвратом к исходному.

Конвертация из представления с фиксированной точкой с 25 или меньшим количеством значащих битов в представление с плавающей точкой не приводит к потере данных. При преобразовании из формата с плавающей запятой в любой распространенный формат с фиксированной запятой происходит потеря данных.