Подтвердить что ты не робот

Правильно ли считать, что сэмплы с плавающей запятой в файле WAV или AIFF будут нормализованы?

Скажем, у меня есть программа, которая читает файл .WAV или .AIFF, а аудиофайлы файла кодируются как значения выборки с плавающей запятой. Правильно ли для моей программы предположить, что любой хорошо сформированный файл с плавающей запятой .WAV или .AIFF будет содержать выборочные значения только в диапазоне [-1.0f, + 1.0f]? Я не мог найти ничего в спецификациях WAV или AIFF, которые затрагивают этот момент.

И если это неверное предположение, как можно узнать, какой должен быть полный динамический диапазон звука в файле? (Я мог прочитать весь файл и узнать, какие файлы являются фактическими минимальными и максимальными значениями выборки, но есть две проблемы с этим: (1) это будет медленная/дорогая операция, если файл очень большой, и (2), это потеряло бы информацию, поскольку если создатель файла предполагал, что файл имеет некоторый "запас высоты", чтобы не играть в dbFS в самой громкой точке, моя программа не сможет обнаружить это)

4b9b3361

Ответ 1

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

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

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

Например:

Если вы хотите воспроизвести его в 16 бит, вы бы сделали (псевдо, считая подписанный округленный до целочисленного результата):

sample = in < 0 ? in * 0x8000 : in * 0x7fff;

или 24-бит:

sample = in < 0 ? in * 0x800000 : in * 0x7fffff;

или 8-бит:

sample = in < 0 ? in * 0x80 : in * 0x7f;

и т.д.. без необходимости корректировать исходное значение ввода любым способом. -1 и 1 будет представлять значение min/max при преобразовании в цель (1x = x).

Если вы использовали диапазон [-0,5, 0,5], вы сначала (или в какой-то момент) должны отрегулировать входное значение, поэтому для преобразования, например, в 16 бит, потребуются дополнительные шаги - у этого есть дополнительная стоимость, не только для дополнительного шага, но и потому, что мы будем работать в области с плавающей запятой, который тяжелее вычислить (последнее, возможно, является немного устаревшей причиной, поскольку обработка с плавающей запятой в наши дни довольно быстрая, но в любом случае).

in = in * 2;
sample = in < 0 ? in * 0x8000 : in * 0x7fff;

Сохранение в диапазоне [-1, 1], а не в некотором предустановленном диапазоне (например, [-32768, 32767]) также позволяет использовать большее количество бит для точности (с использованием представления IEEE 754).

ОБНОВЛЕНИЕ 2017/07

Испытания

Основываясь на вопросах в комментариях, я решил трижды проверить, выполнив тест, используя три файла с 1-секундной синусоидальной волной:

A) Плавающая точка обрезана
B) Плавающая точка max 0dB, и
C) целочисленное сжатие (преобразованное из A)

Файлы, в которых затем сканируются положительные значения <= -1.0 и >= 1.0, начиная с поля chunk и size data, чтобы значения min/max отображали фактические значения, найденные в аудиоданных.

Результаты подтверждают, что диапазон действительно находится в инклюзивном диапазоне [-1, 1], если он не обрезается (не соответствует истине <= 0 дБ).

Но это также показало еще один аспект -

Файлы WAV, сохраненные как с плавающей запятой, допускают значения, превышающие диапазон 0 дБ. Это означает, что диапазон действительно превышает [-1, 1] для значений, которые обычно будут скопированы.

Объяснением этого может быть то, что форматы с плавающей запятой предназначены для промежуточного использования в производственных настройках из-за очень небольшой потери динамического диапазона, где будущая обработка (усиление, сжатие, ограничение и т.д.) может вернуть значения ( без потерь) в пределах конечного и нормального диапазона -0,2 - 0 дБ; и тем самым сохраняет значения as-is.

В заключение

Файлы WAV с использованием с плавающей запятой сохраняют значения в [-1, 1], если не обрезаются (< = 0dB), но допускают значения, которые считаются обрезанными

Но при преобразовании в целочисленный формат эти значения будут скопированы в эквивалентный диапазон [-1, 1], масштабируемый по битовому диапазону целочисленного формата, независимо. Это естественно из-за ограниченного диапазона, который может удерживать каждая ширина.

Таким образом, он будет поддерживать программное обеспечение проигрывателя /DAW/edit для обработки обрезанных значений с плавающей запятой либо путем нормализации данных, либо просто клика обратно в [-1, 1].

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

file2
Примечания: Произведено как обрезанный поплавок (+6 дБ), затем преобразован в 16-битный и обратно в float

file3
Примечания: сжимается до +6 дБ

file4
Примечания: Обрезано до +12 дБ

Простой тест script и файлы можно найти здесь.

Ответ 2

Я знаю, что вопрос не был специфичным для данного языка программирования или структуры, но я не мог найти ответ в какой-либо спецификации. Я уверен, что библиотека NAudio, которая широко используется для обработки файлов .WAV в приложениях, написанных для платформы .NET, предполагает, что образцы с плавающей точкой находятся в диапазоне [-1.0, + 1.0].

Вот применимый код из исходного кода:

namespace NAudio.Wave
{
    public class WaveFileReader : WaveStream
    {
        ...
        /// <summary>
        /// Attempts to read the next sample or group of samples as floating point normalised into the range -1.0f to 1.0f
        /// </summary>
        /// <returns>An array of samples, 1 for mono, 2 for stereo etc. Null indicates end of file reached
        /// </returns>
        public float[] ReadNextSampleFrame()
        {
            ...
            var sampleFrame = new float[waveFormat.Channels];
            int bytesToRead = waveFormat.Channels*(waveFormat.BitsPerSample/8);
            ...
            for (int channel = 0; channel < waveFormat.Channels; channel++)
            {
                if (waveFormat.BitsPerSample == 16)
                ...
                else if (waveFormat.BitsPerSample == 32 && waveFormat.Encoding == WaveFormatEncoding.IeeeFloat)
                {
                    sampleFrame[channel] = BitConverter.ToSingle(raw, offset);
                    offset += 4;
                }
                ...
            }
            return sampleFrame;
        }
        ...
    }
}

Поэтому он просто копирует float в массив без каких-либо преобразований на нем, а promises он должен находиться в заданном диапазоне.

Ответ 3

Да.

Форматы аудиофайлов действуют как носители для одного или нескольких каналов аудиоданных. Эти аудиоданные были закодированы с использованием специального формата аудиокодирования. В каждом формате кодирования используется алгоритм encoder. Алгоритм является важной частью. Мы можем отбросить значение формата файла и кодирования.

AIFF и WAV используют Импульсно-кодовую модуляцию (PCM) или ее потомков. (Если вы проверите этот документ Oracle, вы заметите, что в разделе "Кодирование/сжатие" перечислены алгоритмы на основе PCM.) PCM работает выборка звуковой синусоидальной волны с фиксированными временными интервалами и выбор ближайшего цифрового представления. Важным моментом здесь является "синусоида".

Синусоидальные волны модулируются между -1 и 1, поэтому все кодировки на основе PCM будут действовать по этому принципу. Рассмотрим реализацию mu-law: уведомление в определяющее уравнение диапазон должен быть от -1 до 1.

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