我正在编写一个应用程序,它应该将一个浮点数组写入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];
}
}
Run Code Online (Sandbox Code Playgroud)
我认为没有理由说这个代码会产生这样的副作用.所以我做了一个最小的例子来找出发生了什么.我用这个替换了for循环:
float temp1 = 1.63006e-33f;
float temp2 = 1.55949e-32f;
dataStream << temp1;
dataStream << temp1;
dataStream << temp2;
dataStream << temp1;
dataStream << temp2;
Run Code Online (Sandbox Code Playgroud)
然后我用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
Run Code Online (Sandbox Code Playgroud)
我非常随意地选择了这些值,他们恰好有这种效果.某些值导出为4字节,其他值导出为5字节数字.有谁知道这可能是什么原因?
编辑:
当检查两个花车的大小时,它们似乎确实是4 char秒长,但是:
qDebug() << sizeof(temp1); // prints '4'
qDebug() << sizeof(temp2); // prints '4'
Run Code Online (Sandbox Code Playgroud)
答案在于打开输出文件:QIODevice::Text标志应该被省略,因为它是一个二进制文件.如果包含text-flag,0d则在每个之前插入一个字符0a.因此,包含0a角色的每个浮点数都会因此而char延长.
此答案的所有学分将转到给出的答案: 浮点长度在32到40位之间变化