PDA

View Full Version : Error in reading wav-file header



davidlamhauge
18th November 2012, 01:30
I try to extract information from a wav-file, and it works for most info.
Here is some of my code:


QFile audioFil(fileName);
if (audioFil.open(QIODevice::ReadOnly)){
QByteArray tst;
audioFil.seek(0);
tst = audioFil.read(4);
qDebug() << "RIFF..? : " << tst;
.....
audioFil.seek(20);
tst = audioFil.read(2);
audioFormat = GetLittleEndianInteger(tst,0);
qDebug() << "audioformat (1 = PCM): " << audioFormat;

audioFil.seek(22);
tst = audioFil.read(2);
channels = GetLittleEndianInteger(tst,0);
qDebug() << "Channels: " << channels;

audioFil.seek(24);
tst = audioFil.read(4);
sampleRate = GetLittleEndianInteger(tst,0);
qDebug() << "sampleRate: " << sampleRate;

audioFil.seek(28);
tst = audioFil.read(4);
byteRate = GetLittleEndianInteger(tst,0);
qDebug() << "ByteRate: " << byteRate;

audioFil.seek(32);
tst = audioFil.read(2);
blockAlign = GetLittleEndianInteger(tst,0);
qDebug() << "BlockAlign: " << blockAlign;

The GetLittleEndianInteger function is here


int MainWindow::GetLittleEndianInteger(QByteArray data, int startIndex)
{
return (data[startIndex + 3] << 24)
| (data[startIndex + 2] << 16)
| (data[startIndex + 1] << 8)
| data[startIndex];
}


84258426
As you can see from the two images, it extracts the correct values, except when it comes to SampleRate and ByteRate.
SampleRate should be 44100 (44 ac 00 00). How does it become -21436?
ByteRate should be 176400 (10 b1 02 00). How does it become -20208?

This has driven me crazy the last hours :( Any ideas?

wysota
18th November 2012, 03:27
Why don't you just use qFromLittleEndian()?

davidlamhauge
18th November 2012, 11:42
I didn't know about qFromLittleEndian().
I have read about, but can't make it work. Could you give me a hint on how to use in my context?

And - it still puzzles me that the the function GetLittleEndianInteger returns a negative samplerate.
I tried to debug, and the value of my QByteArray tst, shows that 0xAC is read as '-84 / 172' (see image)
8427
Why?

wysota
18th November 2012, 11:59
I didn't know about qFromLittleEndian().
I have read about, but can't make it work. Could you give me a hint on how to use in my context?

Read four bytes, cast them to uchar* and pass to qFromLittleEndian().

davidlamhauge
18th November 2012, 14:09
Read four bytes, cast them to uchar* and pass to qFromLittleEndian().
Is it possible to elaborate a little?
I've tried many combinations, and read many posts on the net, but...
Is it like this you mean?


audioFil.seek(24);
tst = audioFil.read(4);
tst[0] = (uchar)tst[0];
tst[1] = (uchar)tst[1];
tst[2] = (uchar)tst[2];
tst[3] = (uchar)tst[3];
sampleRate = qFromLittleEndian<quint32>(*tst);
// sampleRate = GetLittleEndianInteger(tst,0);
qDebug() << "sampleRate: " << sampleRate;

The debug-output is 'sampleRate: 68'. 68 = 'D' = tst[0].
I don't really get it. Hence 'Beginner'...

EDITED:
when I read my reply it dawned a little. This works:

uchar* cc;
audioFil.seek(24);
tst = audioFil.read(4);
cc[0] = tst[0];
cc[1] = tst[1];
cc[2] = tst[2];
cc[3] = tst[3];
sampleRate = qFromLittleEndian<qint32>(cc);
// sampleRate = GetLittleEndianInteger(tst,0);
qDebug() << "sampleRate: " << sampleRate;

...but could it be done more effectively?

wysota
18th November 2012, 14:35
QByteArray ba = audoFil.read(4);
qint32 sampleRate = qFromLittleEndian((const uchar*)ba.constData());