Общий режим WASAPI: Какую амплитуду ожидает звуковой движок? - PullRequest
0 голосов
/ 25 августа 2018

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

WASAPI дает мне информацию о аудиоформате, который аудио движок принимает в режиме совместного использования.Я знаю ожидаемую битовую глубину сэмплов, которые я предоставляю в буфер. Чего я не знаю, так это ожидаемого представления амплитуды сигнала в выборках. Например, если звуковой движок ожидает 32-битные выборки, означает ли это, что я должен представлять амплитуду синусоидальной волны как:

  • long в диапазоне [min, max]
  • unsigned long в диапазоне [0, max]
  • float в диапазоне [min, max]
  • или даже что-то вроде float в диапазоне [-1, 1]?

(max = std::numeric_limits<type>::max() и min = ...::min() в C++)

Пока я экспериментировалс этим с различными значениями методом проб и ошибок.Кажется, что только когда мои семплы содержат числа max/2 или -min/2 (как long), чередующиеся (наряду с другими числами), он производит звук.Четные числа, близкие к этим (+ - несколько целых чисел), дают одинаковые результаты.Когда эти два числа (или числа, близкие к ним) не присутствуют в примерах, результатом является молчание независимо от того, что я делаю.

Это может быть неуместно, но я заметил, что эти числа '(max/2 и min/2) битовое представление (как long с) идентично IEEE float битовому представлению 2.0 и -2.0.Мне все еще не имеет смысла, почему это так работает.

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

После более глубокого изучения структуры WAVEFORMATEXTENSIBLE я обнаружил, что необходимая мне информация может храниться в свойстве SubFormat.В моем случае это было KSDATAFORMAT_SUBTYPE_IEEE_FLOAT.Таким образом, аудио движок ожидал 32 бит float с в диапазоне [-1, +1].По какой-то причине мой предыдущий тест со значениями с плавающей запятой оказался неудачным, поэтому я продолжил попытки с целыми числами.Теперь простая функция синуса в диапазоне [-1, +1] обеспечивает правильный результат.В звуке есть некоторые глюки, но это может быть связано с некоторыми проблемами синхронизации при ожидании буфера.

0 голосов
/ 28 августа 2018

Типичное представление - это число с плавающей точкой от 1 до 1, масштабированное до представления с фиксированной точкой. Для 32-разрядных подписей в идеале вам нужно, чтобы 1 отображался на 0x7fffffff, а -1 - на 0x8000000. Тем не менее, вы должны иметь в виду, что асимметрия около 0 такова, что существует еще одно отрицательное значение, чем положительные значения. Другими словами, вы не должны использовать 0x80000000, иначе вы рискуете переполнением на положительной стороне.

int xfixed = (int)(xfloat * 0x7fffffff);

Более подробно:

int xfixed = (int)(xfloat * ((1<<(32-1)) - 1));
...