Два види ДИКМ-кодування

Складна і захоплююча завдання, що виникає в процесі розробки якісної ДИКМ-технології, являє собою балансування між двома вимогами Щоб ваш алгоритм зберігав звуки максимально точно, необхідно мати можливість точно записувати кожне з збільшень, особливо, невеликі Однак, оскільки потенційно можливі величини займають більший діапазон, вам, ймовірно, знадобиться зберігати іноді зустрічаються великі прирости Зазвичай це означає, що таке прирощення саме по собі закодовано B табл 121 як приклад наведені коди, використовувані

двома методами компресії, розробленими для компютера Amiga Кожна з цих схем дозволяє перейти від запису 8-бітних моментальних значень до запису 4-бітових кодованих збільшень

Таблиця 121 Кодовані приросту для алгоритмів компресії IFF/8SVX

типу 1 і типу 2

Значення коду

-8

-7

-6

-5

-4

-3

-2

-1

0

1

2

3

4

5

6

7

Фібоначчі

-34

-21

-13

-8

-5

-3

-2

-1

0

1

2

3

5

8

13

21

Експоненціальне

-128

-64

-32

-16

-8

-4

-2

-1

0

1

2

4

8

16

32

64

Зверніть увагу, що при залученні обох кодувань виходить безліч маленьких значень (в цілому, невеликі прирости зустрічаються набагато частіше) і окремі великі значення

B Зокрема, відзначимо, що показане в цій таблиці експоненціальне кодування (що використовує ступеня числа 2), за своєю концепцією аналогічно крокової таблиці в більш витонченому алгоритмі кодування IMA ADPCM (в якому застосовуються ступеня числа 11 докладніше про нього розповідається в главі 13)

Лістинг 121 Програма dpcmh

#ifndef DPCM_H_INCLUDED

#define DPCM_H_INCLUDED

#include &quotaudioh&quot

#include &quotcompressh&quot

class DecompressDpcmFibonacci: public AbstractDecompressor {

private:

AudioSample _previousValue

public:

DecompressDpcmFibonacci(AudioAbstract &ampa): AbstractDecompressor(a) {

/ / Кодування: ДИКМ Фібоначчі

cerr &lt&lt &quotEncoding: Fibonacci Dpcm\n"

_previousValue = 0

}

size_t GetSamples(AudioSample * buffer, size_t length)

}

class DecompressDpcmExponential: public AbstractDecompressor {

private:

AudioSample _previousValue

public:

DecompressDpcmExponential(AudioAbstract &ampa): AbstractDecompressor(a) {

/ / Кодування: експонентна ДИКМ

cerr &lt&lt &quotEncoding: Exponential Dpcm\n"

_previousValue = 0

}

size_t GetSamples(AudioSample * buffer, size_t length)

}

#endif

Лістинг 122 Програма dpcmcpp

#include &quotaudioh&quot

#include &quotcompressh&quot

#include &quotdpcmh&quot

static const signed char fibonacci[] = {

-34, 21, 13, 8, 5, 3, 2, 1, 0, 1, 2, 3, 5, 8,

13, 21

}

static const signed char exponential[] = {

-128, 64, 32, 16, 8, 4, 2, 1, 0, 1, 2, 4, 8, 16,

32, 64

}

Процес безпосередньо декомпресії простий Для кожного полубайта ми знаходимо декодований інкремент в таблиці і додаємо його до _previousValue, що дає нам черговий відлік C метою оптимізації цієї процедури зчитування стислих даних проводиться в кінець передбаченого буфера, після чого здійснюється перетворення даних на місці Стислі дані необхідно зчитувати в кінець буфера, щоб вони не затиралися ході конвертації Крім того, відзначимо, що оскільки апаратне забезпечення компютерів Amiga може обробляти тільки 8-бітові відліки, всі процедури компресії для цього формату налаштовані на роботу з 8-бітними величинами Перед складанням мені довелося зрушувати прирощення в область старшого байта

Лістинг 123 Метод GetSamples для ДИКМ з кодуванням Фібоначчі

size_t DecompressDpcmFibonacci::GetSamples(AudioSample * buffer, size_t length) {

AudioByte *byteBuffer =

reinterpret_cast&ltAudioByte *&gt(buffer)

+ Length * sizeof (AudioSample) / / Довжина буфера

length / 2 / / Необхідне для зберігання

/ / Кодованих даних місце

AudioSample *sampleBuffer = buffer

/ / Прочитуємо закодовані дані в буфер

size_t bytesRead = ReadBytes(byteBuffer,length/2)

for(size_t i=0 i&ltbytesRead i++) {

/ / Декодируем молодший напівбайт

int nybble = (static_cast&ltint&gt(*byteBuffer&gt&gt4)+8)&amp0xF

_previousValue +=

static_cast&ltAudioSample&gt(fibonacci[nybble])

&lt&lt ((sizeof(AudioSample)-1)*8)

*sampleBuffer++ = _previousValue

/ / Декодируем старший напівбайт

nybble = (static_cast&ltint&gt(*byteBuffer)+8)&amp0xF

_previousValue +=

static_cast&ltAudioSample&gt(fibonacci[nybble])

&lt&lt ((sizeof(AudioSample)-1)*8)

*sampleBuffer++ = _previousValue

}

return bytesRead * 2

}

Декодер для експоненційної ДИКМ ідентичний розглянутому раніше, за

винятком того, що він використовує іншу таблицю

Лістинг 124 Метод GetSamples для ДИКМ з експоненціальною кодуванням

size_t DecompressDpcmExponential::GetSamples(AudioSample *

buffer,

size_t length) { AudioByte *byteBuffer =

reinterpret_cast&ltAudioByte *&gt(buffer)

+ Length * sizeof (AudioSample) / / Довжина буфера

length / 2 / / Необхідне місце для

/ / Закодованих даних

AudioSample *sampleBuffer = buffer

/ / Прочитуємо закодовані дані в буфер

size_t bytesRead = ReadBytes(byteBuffer,length/2)

for(size_t i=0 i&ltbytesRead i++) {

/ / Декодируем молодший напівбайт

int nybble = (static_cast&ltint&gt(*byteBuffer&gt&gt4)+8)&amp0xF

_previousValue +=

static_cast&ltAudioSample&gt(exponential[nybble])

&lt&lt ((sizeof(AudioSample)-1)*8)

*sampleBuffer++ = _previousValue

/ / Декодируем старший напівбайт

nybble = (static_cast&ltint&gt(*byteBuffer)+8)&amp0xF

_previousValue +=

static_cast&ltAudioSample&gt(exponential[nybble])

&lt&lt ((sizeof(AudioSample)-1)*8)

*sampleBuffer++ = _previousValue

}

return bytesRead * 2

}

Джерело: Кінтцель Т Керівництво програміста по роботі зі звуком = A Programmers Guide to Sound: Пер з англ М: ДМК Пресс, 2000 432 с, іл (Серія «Для програмістів»)

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*