所以我从来没有真正使用过二进制文件,而我刚刚接触C++。我想读取一个wav文件并将其数据部分输出到txt中(用逗号分隔每个样本的值)。我也设法阅读标题部分,但这段代码在这里并不重要,所以我不会包含它。C++ RIFF WAVE阅读器很痛苦
我的wav文件以32bps的速度存储IEEE 754标准的数据(浮点数)。我首先将整个wav文件读入char向量,然后尝试使用它。该程序的输出是我期望的结果,我可以通过阅读txt而无任何问题地播放Python中的声音。该程序的速度非常慢(需要几分钟才能完成一个长达几秒的wav文件)。
这是wavReader.cpp
:
#include "stdafx.h"
#include "wavFile.h"
#include <fstream>
#include <iostream>
#include <vector>
int main()
{
std::ifstream file("file.wav", std::ios::binary);
std::vector<char> buffer((
std::istreambuf_iterator<char>(file)),
(std::istreambuf_iterator<char>()));
std::cout << "Loading complete!\n";
WavFile wavFile = setWavFile(buffer);
return 0;
}
这是wavFile.h
:
#pragma once
#include <iostream>
#include <vector>
struct WavFile
{
uint32_t dataSize;
};
WavFile setWavFile(std::vector<char> buffer);
uint32_t getUint32(std::vector<char> buffer, std::vector<char>::iterator it);
这是wavFile.cpp
:
#include "stdafx.h"
#include "WavFile.h"
#include <fstream>
WavFile setWavFile(std::vector<char> buffer) {
WavFile wavFile;
std::vector<char>::iterator it = buffer.begin();
// Beginning of data chunk is marked with "data"
it += 4;
while (*(it - 4) != 'd' ||
*(it - 3) != 'a' ||
*(it - 2) != 't' ||
*(it - 1) != 'a')
it++;
wavFile.dataSize = getUint32(buffer, it), it += 4;
std::ofstream output("data.txt");
while (it != buffer.end())
{
char outputChar[4];
for (int i = 0; i < 4; (i++, it++))
outputChar[i] = *it;
char* outputStr = outputChar;
char** outputStrPtr = &outputStr;
float** outputPtr = reinterpret_cast<float**>(outputStrPtr);
output << **outputPtr << ", ";
std::cout << static_cast<double>(std::distance(buffer.begin(), it)) * 100/wavFile.dataSize << "\%\n";
}
return wavFile;
}
uint32_t getUint32(std::vector<char> buffer, std::vector<char>::iterator it)
{
char outputChar[4];
for (int i = 0; i < 4; (i++, it++))
outputChar[i] = *it;
char* outputStr = outputChar;
char** outputStrPtr = &outputStr;
uint32_t** outputPtr = reinterpret_cast<uint32_t**>(outputStrPtr);
return **outputPtr;
}
我制作的节目打印进展控制台。请注意,这只适用于具有一个通道的wav文件,并将样本存储在IEEE 754标准中。你可以找到我使用的文件here。我只是一个业余爱好程序员,所以请原谅我,我不知道是什么让我的程序变得很慢......是矢量迭代吗?或者它是与reinterpret_cast有点乱的变量声明?
其实你为什么不用python读它?将音频值转换为文本然后再转换为值似乎是一种矫枉过正。 – VTT
@VTT这不是一些实用的用途,而是我为了理解WAVE文件的文件结构以及如何将二进制文件转换为通常可读的文件而进行的练习。 – Keno