istream :: read и wav форматные биты на образец

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

У меня вопрос, как я могу прочитать оставшиеся 8-битные без знака, 24-битные со знаком и 32-битные поплавок WAVs?

Прочитайте один пример 16-битного подписанного wav:

short buffer;

file.read( ( char * ) &readbuffer, 2 );

Прочитайте один пример 32-битного подписанного wav:

int buffer;

file.read( ( char * ) &readbuffer, 4 );

1

Решение

Вы делаете несколько предположений о целевой машине. По данным Microsoft Формат WAV, Все образцы данных имеют порядок байтов. Вы также ожидаете, что различные типы данных будут иметь желаемый размер, что может не всегда иметь место.

Но так как ваши текущие процедуры работают на вас, мы пока не будем на этом фокусироваться (но вам, вероятно, следует исправить это в какой-то момент)

32-разрядный поплавок

Если мы забудем о страшном порядке байтов и нестандартных размерах, 32-битный случай с плавающей запятой становится относительно простым, если использовать другой код в качестве шаблона:

float buffer;
file.read( ( char * ) &buffer, 4 );

Этот вопрос более подробно описывает чтение плавающих объектов из двоичного источника.

х бит без знака

Так как мы знаем, что ваша машина правильно интерпретирует 16- и 32-битные случаи, мы можем предположить, что это little-endian. Это означает, что вы можете просто прочитать все в unsigned int, которое было инициализировано нулем, а остальные байты уже правильно заполнены для вас:

unsigned int buffer = 0;
file.read( ( char * ) &buffer, 1 );   // 8bit unsigned integer

buffer = 0;
file.read( ( char * ) &buffer, 3 );   // 24bit unsigned integer

х бит подписан

Наконец, если вы читаете целое число со знаком, вам нужно заполнить оставшиеся байты буферной переменной в зависимости от значения только что прочитанного числа:

  • Если число было положительным, вы можете просто набрать 0
  • Если число было отрицательным (установлен старший бит старшего значащего байта), то вы дополняете байтами \ xFF.

Этот код работает с 24-битным целым числом со знаком:

long buffer;
int number_of_bytes = 3;             // 24 bit signed integer

file.read( (char *) &buffer, number_of_bytes);

// Determine the padding byte
unsigned char padding_byte = 0;
if ( ((char*) &buffer)[number_of_bytes - 1] & 128) {
padding_byte = 255;
}

// Pad the data
for (int i = number_of_bytes; i < sizeof(buffer); i++) {
((char*) &buffer)[i] = padding_byte;
}

Опять же, я чувствую, что должен указать, что этот код не будет работать на некоторых машинах, потому что вы не проверяете порядок байтов. Но все, что вам нужно сделать, чтобы это исправить, это проверить порядок байтов машины, на которой выполняется код и обратный порядок байтов, если вы находитесь на машине с прямым порядком байтов.

1

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

Других решений пока нет …

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