Деинтерлейсинг PCM (* .wav) стереофонических аудиоданных

Я понимаю, что данные PCM хранятся как [left][right][left][right]..., Я пытаюсь преобразовать стерео PCM в моно Vorbis (* .ogg), что, как я понимаю, достижимо путем деления левого и правого каналов вдвое ((левый + правый) * 0,5). На самом деле я добился этого, внеся изменения в пример кодировщика в libvorbis SDK следующим образом:

#define READ 1024
signed char readbuffer[READ*4];

и данные PCM читаются таким образом

fread(readbuffer, 1, READ*4, stdin)

Затем я разделил пополам два канала,

buffer[0][i] = ((((readbuffer[i*4+1]<<8) | (0x00ff&(int)readbuffer[i*4]))/32768.f) + (((readbuffer[i*4+3]<<8) | (0x00ff&(int)readbuffer[i*4+2]))/32768.f)) * 0.5f;

Это сработало отлично, но я не понимаю, как они перемежают левый и правый канал от данных PCM (то есть все битовые сдвиги и «И» и «ИЛИ»).

5

Решение

Файл .wav обычно хранит свои данные PCM в немного порядковый номер формат, с 16 битами на выборку на канал. Для обычного подписанного 16-битного файла PCM это означает, что данные физически хранятся как

[LEFT LSB] [LEFT MSB] [RIGHT LSB] [RIGHT MSB] ...

так что каждая группа из 4 байтов составляет одну выборку стерео ИКМ. Следовательно, вы можете найти образец i глядя на байты 4*i через 4*i+3включительно.

Чтобы декодировать одно 16-битное значение из двух байтов, вы делаете это:

(MSB << 8) | LSB

Потому что ваши значения буфера чтения хранятся как подписанный Вы должны быть немного осторожны, потому что оба MSB а также LSB будет продлен знак Это нежелательно для LSB; поэтому код использует

0xff & (int)LSB

чтобы получить беззнаковую версию младшего байта (технически это работает путем выгрузки до int и выбора младших 8 битов; альтернативной формулировкой будет просто записать (uint8_t)LSB).

Обратите внимание, что MSB имеют индексы 1 и 3, а LSB имеют индексы 0 и 2. Итак,

((readbuffer[i*4+1]<<8) | (0x00ff&(int)readbuffer[i*4]))

а также

((readbuffer[i*4+3]<<8) | (0x00ff&(int)readbuffer[i*4+2]))

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

Затем каждое из этих значений делится на 32768,0. Обратите внимание, что 16-разрядное значение со знаком имеет диапазон [-32768, 32767], Таким образом, деление на 32768 дает диапазон приблизительно [-1, 1]. Два разделенных значения добавляются, чтобы получить число в диапазоне [-2, 2], а затем все умножается на 0,5, чтобы получить среднее значение (значение с плавающей запятой в диапазоне [-1, 1]).

6

Другие решения


По вопросам рекламы [email protected]