Я пишу приложение, которое должно записывать массив поплавков в файл WAVE. Я использую для этого QDataStream, но это приводит к очень маловероятному результату, который я не могу объяснить. Кажется, что QDataStream иногда выбирает 32-битные числа с плавающей запятой, а иногда 40-битные числа с плавающей запятой. Это портит весь выходной файл, поскольку он должен подчиняться строгому формату.
Мой код примерно выглядит так:
float* array;
unsigned int nSamples;
void saveWAV(const QString& fileName) const
{
QFile outFile(fileName);
if (outFile.open(QIODevice::WriteOnly | QIODevice::Text))
{
QDataStream dataStream(&outFile);
dataStream.setByteOrder(QDataStream::LittleEndian);
dataStream.setFloatingPointPrecision(QDataStream::SinglePrecision);
// ... do all the WAV file header stuff ...
for(int ii = 0; ii < nSamples; ++ii)
dataStream << array[ii];
}
}
Я не могу придумать причину, по которой этот код мог иметь такой побочный эффект. Поэтому я сделал минимальный пример, чтобы выяснить, что происходит. Я заменил цикл for на это:
float temp1 = 1.63006e-33f;
float temp2 = 1.55949e-32f;
dataStream << temp1;
dataStream << temp1;
dataStream << temp2;
dataStream << temp1;
dataStream << temp2;
Затем я открыл выходной файл с помощью Matlab и посмотрел на байты, записанные в файл. Это были:
8b 6b 07 09 // this is indeed 1.63006e-33f (notice it's Little Endian)
8b 6b 07 09
5b f2 a1 0d 0a // I don't know what this is but it's a byte to long
8b 6b 07 09
5b f2 a1 0d 0a
Я выбрал значения довольно произвольно, они просто имели такой эффект. Некоторые значения экспортируются как 4-байтовые, а другие как 5-байтовые числа. Кто-нибудь знает, что может быть причиной этого?
Изменить: при проверке размера обоих чисел с плавающей запятой оказалось, что они имеют длину 4 char
s:
qDebug() << sizeof(temp1); // prints '4'
qDebug() << sizeof(temp2); // prints '4'