Главная » Программирование звука » Общее описание работы

0

B  IMA  ADPCM  для  хранения  каждого  отсчета  используются 4  бита.  Кодирующий модуль берет разницу между двумя отсчетами, делит ее на текущий размер шага и использует получившуюся величину в качестве очередного сжатого 4-битного  выходного  значения.  Декомпрессор,  наоборот,  берет  это  4-битное  значение, умножает  его  на  текущую  величину  шага  и  прибавляет  получившийся  результат к  предыдущему  отсчету,  получая  тем  самым  очередной  отсчет.  Изменяя  размер шага, с помощью 4-битного кода можно записать большой диапазон значений.

Для  сокращения  объема  информации  сам  размер  шага  не  хранится.  Вместо него  компрессор  сохраняет  индекс  в  таблицу,  содержащую  88  возможных  значений  размера  шага.  Величины  размеров  шага  следуют  приблизительно  экспоненциальной кривой интересно сравнить эти значения с графиком функции 1.1n.

Листинг 13.1. Таблица допустимых значений размера шага для IMA ADPCM

static const int _stepSizeTable[89] = {

7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,

34,

37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130,

143,

157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449,

494,

544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411,

1552,

1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026,

4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,

11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623,

27086, 29794, 32767

};

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

Листинг 13.2. Информация состояния IMA ADPCM

struct ImaState {

int index;         // Индекс в  таблице  значений размера  шага.

int previousValue; // Величина последней  выборки.

};

Важным  элементом  IMA  ADPCM  является  механизм  управления  размером шага. B 4-битный  отсчет записывается  представленное  в  прямом  коде  со  знаком число  в  диапазоне  от  -7  до  +7.  Поскольку  декомпрессору  неизвестна  величина следующего отсчета, он должен сделать выбор, основываясь на предыдущих значениях. Если полученное в результате преобразования приращения 4-битное число велико, возможно, что следующее будет еще больше и для его размещения не хватит  четырех  бит.  Если  4-битное  представление  приращения   величина  небольшая, значит, вы не в полной мере используете имеющиеся у вас 4 бита информации.  B  результате,  если  величина,  получающаяся  при  делении  приращения на размер шага, приближается к нулю размер шага уменьшается, если она возрастает шаг увеличивается.

Каждый  4-битный  полубайт  представляет  собой  число,  записанное  в  прямом ходе со знаком; старший бит это знак числа, а остальные биты содержат число от нуля  до  7. (B отличие от более  широко  распространенного  формата,  использующего дополнительный код, при записи в прямом коде со знаком делается различие между +0 и -0.)

Листинг 13.3. Таблица коррекции индекса IMA ADPCM

static const int indexAdjustTable[16] = {

-1, 1, 1, 1,    // +0 +3, уменьшение  шага.

2, 4, 6, 8,          // + 4 + 7, увеличение шага.

-1, 1, 1, 1,    // -0 -3, уменьшение  шага.

2, 4, 6, 8,          // -4 -7,   увеличение шага.

};

Декомпрессия

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

Листинг 13.4. Функция декодирования IMA ADPCM

AudioSample ImaAdpcmDecode(AudioByte deltaCode, ImaState &state)

{

// Получаем  значение  текущей величины шага. int step = _stepSizeTable[state.index];

// Создаем  приращение, масштабируя  текущую величину  шага.

// Приблизительно  так: приращение  = (deltaCode+.5)*шаг/4.

int difference = step>>3;

if (deltaCode & 1 ) difference += step>>2; if (deltaCode & 2 ) difference += step>>1; if (deltaCode & 4 ) difference += step;

if (deltaCode & 8 ) difference = difference;

// Вычисляем  новую   выборку.

state.previousValue += difference;

if (state.previousValue > 32767) state.previousValue = 32767;

else if (state.previousValue < 32768) state.previousValue = -32768;

// Обновляем величину  шага для  обработки  следующей выборки.

state.index += indexAdjustTable[deltaCode];

if (state.index < 0) state.index = 0;

else if (state.index > 88) state.index = 88;

return state.previousValue;

}

Компрессия

Практически  работа  компрессора  идет  именно  так,  как  можно  было  бы  ожи-

дать.   Сначала   вычисляется   приращение,   а   затем   посредством   последовательности битовых   операций   производится   приблизительное   деление   на   текущий   размер шага.   (Ha   многих   микропроцессорах   битовые   операции   выполняются   гораздо быстрее,  чем  реальная  операция  деления.)  Обратите  внимание  на  использование непосредственного   вызова   ImaAdpcmDecode  для   обеспечения   гарантии   корректности обновления информации о состоянии.

Листинг 13.5. Функция кодирования IMA ADPCM

AudioByte ImaAdpcmEncode(AudioSample sample, ImaState &state) {

int diff = sample state.previousValue; int step = _stepSizeTable[state.index]; int deltaCode = 0;

// Записываем  знаковый  бит.

if (diff < 0) { deltaCode = 8; diff = diff; }

// B сущности,  получается deltaCode = (diff<<2)/mar,

// за  исключением того, что округление обрабатывается  особо.

if (diff >= step ) { deltaCode |= 4; diff = step; }

step >>= 1;

if (diff >= step ) { deltaCode |= 2; diff = step; }

step >>= 1;

if (diff >= step ) { deltaCode |= 1; diff = step; } ImaAdpcmDecode(deltaCode,state); // Обновляем  состояние. return deltaCode;

}

Источник: Кинтцель Т.  Руководство программиста по работе со звуком = A Programmer’s Guide to Sound: Пер. с англ. М.: ДМК Пресс, 2000. 432 с, ил. (Серия «Для программистов»).

По теме:

  • Комментарии