Чтение Wav файлов, неправильный вывод

Я уже публиковал симуляционную проблему (подумал, что было бы лучше начать все заново и, надеюсь, получить больше мнений по этому поводу). По сути, проблема в том, что я пытаюсь прочитать данные из WAV-файла, однако вывод отличается от того, что есть в MatLab.

В C ++ вывод таков:

-128

В то время как в Matlab:

0

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

**** WAV FILE *****
Chunk IDRIFFN?
Chunk Size: 57934
Format: WAVEfmt
Format: IDfmt
FormatSize: 18
Format2: 1
Channel Num: 1
Sample Rate: 22050
Byte Rate: 22050
Align: 1
Bits Per Sample: 8

И код:

file.read(this->chunkId,                                 4);
file.read(reinterpret_cast<char*>(&this->chunkSize),     4);
file.read(this->format,                                  4);

file.read(this->formatId,                                4);
file.read(reinterpret_cast<char*>(&this->formatSize),    4);
file.read(reinterpret_cast<char*>(&this->format2),       2);
file.read(reinterpret_cast<char*>(&this->numChannels),   2);
file.read(reinterpret_cast<char*>(&this->sampleRate),    4);
file.read(reinterpret_cast<char*>(&this->byteRate),      4);
file.read(reinterpret_cast<char*>(&this->align),         2);
file.read(reinterpret_cast<char*>(&this->bitsPerSample), 4);

char testing[4] = {0};
int testingSize = 0;

while(file.read(testing, 4) && (testing[0] != 'd' ||
testing[1] != 'a' ||
testing[2] != 't' ||
testing[3] != 'a'))
{

file.read(reinterpret_cast<char*>(&testingSize), 4);
file.seekg(testingSize, std::ios_base::cur);

}

this->dataId[0] = testing[0];
this->dataId[1] = testing[1];
this->dataId[2] = testing[2];
this->dataId[3] = testing[3];file.read(reinterpret_cast<char*>(&this->dataSize),     4);

this->data = new char[this->dataSize];

file.read(data,this->dataSize);

cout << "**** WAV FILE *****" << endl;
cout << "Chunk ID" << this->chunkId << endl;
cout << "Chunk Size" << this->chunkSize << endl;
cout << "Format: " << this->format << endl;
cout << "Format ID" << this->formatId << endl;
cout << "FormatSize" << this->formatSize << endl;
cout << "Format2 " << this->format2 << endl;
cout << "Channel Num" << this->numChannels << endl;
cout << "Sample Rate" << this->sampleRate << endl;
cout << "Byte Rate" << this->byteRate << endl;
cout << "Align" << this->align << endl;
cout << "Bits Per Sample" << this->bitsPerSample << endl;
cout << "Size" << testingSize << endl;for(unsigned i=0; (i < 20); i++){
cout << (float) data[i] << endl;
}

return true;

Кто-нибудь может увидеть, где я иду не так? Я пытался отладить его, но не было радости (я использую g ++ для компиляции). Любая помощь будет принята с благодарностью 🙂 Извините, я продолжаю спрашивать это, это действительно раздражает меня сейчас!

Спасибо

1

Решение

Я считаю, что куски в файле WAV должны быть выровнены по ближайшей границе WORD. Если после раздела формата, который вы проанализировали, нет границы следующего слова, вы не войдете в цикл while, и ваш код будет предполагать, что вы находитесь в разделе данных.

Точно так же, если какой-либо из ваших кусков имеет нечетное число байтов, вы можете столкнуться с проблемой.

0

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

Хорошо, глядя на код, это похоже на ошибку приведения. Вы явно пытаетесь вывести двадцать поплавков (состоящих из четырех байтов каждый), но на самом деле вы выводите только двадцать байтов, каждый байт преобразуется в один поплавок. Я думаю, что вы могли бы хотеть этого

for(unsigned i=0; (i < 20); i++){
cout << ((float*) data)[i] << endl;
}

Другими словами, вы конвертируете данные в указатель с плавающей точкой, а затем применяете индекс. Не применять индекс сначала, а затем преобразовать в число с плавающей точкой.

0

Я думаю, что в Matlab значения нормализуются в диапазоне от -1 до 1, поэтому для получения аналогичных выходных данных в C ++ вам необходимо масштабировать их.
Пример для семплов, которые являются 16-битными в диапазоне от -32768 до 32767, и вы хотите, чтобы их масштабировали от -1,0 до 1,0. Способ сделать это — разделить на 32768,0 (-32768 / 32768.0 == -1, 32767 / 32768.0 немного меньше 1).

for(unsigned i=0; (i < 20); i++){
cout << ((float) data[i])/32768.0 << endl;
}
0
По вопросам рекламы [email protected]