Главная » Программирование звука » 8-битная ИКМ

0

Как  я  уже  говорил  выше,  несмотря  на  то  что  большинство  программистов  считают   ИКМ-данные   «несжатыми»,   правильнее   было   бы   говорить   не   о   компрессии,  а  о  кодировке.  Подобно  другим  методы  представления  звука,  ИКМ  является кодировкой.  K   сожалению,  широкое  распространение   получило   множество   вариантов ИКМ.

Чаще  всего  при  записи  данных  с  применением  ИКМ  для  хранения  одного  от-

счета используется от 8 до 16 бит (1 или 2 байта). Однако даже в том случае, если задействован только один байт, возникают определенные разногласия.

Знаковая

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

B  знаковом  формате  (называемом  еще  дополнительным  кодом)  один  байт  используется  для  представления  отсчетов  в  диапазоне  от  -128  до  +127.  Значения в  диапазоне  от  0  до  +127  записываются  без  изменений   отрицательные,  от  -128 до  -1,  преобразуются  в  двоичные  байты  в  результате  сложения  их  с  числом  256. Этот  формат  совпадает  с  внутренним  представлением  чисел,  которое,  как  правило, предпочитают программисты и используют во многих системах.

Листинг 10.3. Классы для 8-битной ИКМ

class DecompressPcm8Signed: public AbstractDecompressor {

public:

DecompressPcm8Signed(AudioAbstract &a): AbstractDecompressor(a) {

// Кодировка: 8-битная  знаковая (дополнительный  код) ИКМ.

cerr << "Encoding: 8-bit signed (two’s complement) PCM\n";

};

size_t GetSamples(AudioSample * buffer, size_t length);

};

Несмотря на небольшую длину представленной ниже версии реализации метода  GetSamples,  при  ее  написании  пришлось  учесть  ряд  сложных  моментов.  Вопервых, из-за того, что 8-битные отсчеты короче, чем значения типа AudioSample, возможно  повторное  использование  одного  и  того  же  буфера.  Также  необходимо следить  за  тем,  чтобы  не  затереть  необработанные  данные  при  преобразовании

8-битных  отсчетов  в  более  длинные  значения  типа  AudioSample.  Обратите  внимание  на  то,  как  изменяются  типы:  любой  декомпрессор  звуковой  информации считывает  байты,  а  возвращает  выборки.  Также  отметим,  что  короткие  8-битные выборки  сдвигаются  влево,  в  область  наиболее  значимых  битов  более  длинных значений типа AudioSample.

Листинг 10.4. Реализация методов для 8-битной ИКМ

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

AudioByte *byteBuff =

reinterpret_cast<AudioByte *>(buffer);

size_t samplesRead = ReadBytes(byteBuff,length);

for(long i=samplesRead-1; i>=0; i–)

buffer[i] = static_cast<AudioSample>(byteBuff[i])

<< ((sizeof(AudioSample)-1)*8);

return samplesRead;

}

Беззнаковая

При  работе  с  беззнаковым  форматом  (также  называемым  кодом  с  избытком

128) используется тот же диапазон отсчетов, к которым прибавляется число 128,

чтобы получить байт со значением от 0 до 255. B частности в байт, соответствующий  нулевому  значению  выборки,  записывается  128.  Беззнаковый  формат  задается  несколькими  телекоммуникационными  стандартами  и  широко  используется в аппаратном обеспечении.

Листинг 10.3. Классы для 8-битной ИКМ (продолжение)

class DecompressPcm8Unsigned: public AbstractDecompressor {

public:

DecompressPcm8Unsigned(AudioAbstract &a): AbstractDecompressor(a) {

// Кодировка:8-6итная  беззнаковая (код   с  избытком 128)ИKM

cerr << "Encoding: 8-bit unsigned (excess-128) PCM\n";

};

size_t GetSamples(AudioSample * buffer, size_t length);

};

Единственным   реальным   отличием   между   числами   со   знаком   и   числами без  знака  является  старший  бит.  B  знаковом  формате  для  отрицательных  чисел  в  старший  бит  записывается  единица   в  беззнаковом  формате  старший бит  используется  для  положительных  чисел.  Таким  образом,  для  преобразования  беззнаковых  чисел  требуется  считать  блок  байтов,  а  затем  в  каждом  байте сменить  значение  старшего  бита  на  противоположное.  Приведенный  ниже  вариант  метода  GetSamples идентичен  использовавшимся  ранее  версиям,  кроме операции  исключающего  ИЛИ,  с  помощью  которой  изменяются  значения  старшего бита.

Листинг 10.4. Реализация методов для 8-битной ИКМ (продолжение)

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

AudioByte *byteBuff =

reinterpret_cast<AudioByte *>(buffer);

size_t samplesRead = ReadBytes(byteBuff,length);

for(long i=samplesRead-1; i>=0; i–)

buffer[i] = static_cast<AudioSample>(byteBuff[i] ^ 0x80)

<< ((sizeof(AudioSample)-1)*8);

return samplesRead;

}

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

По теме:

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