我在c ++程序中读取.wav文件。
.wav格式是样本为uint8_t
或int16_t
。是否可以根据特定文件的格式声明变量?
一种解决方案是:
int16_t sample;
if (bits==8)
{
uint8_t temp8;
in.read((char*)&temp8,bits);
sample = (int16_t) temp8;
}
else
{
in.read((char*)&sample,bits);
}
从现在开始我可以使用sample
。然而,这似乎并不是很方便,在8位情况下,变量sample
比需要的更大。
我相信这也可以通过union完成,但它仍会使变量占用2个字节,无论如何。
我真正想要的是:
if(bits==8)
uint8_t sample;
else
int16_t sample;
但是范围超出条件陈述。
答案 0 :(得分:3)
您可以使用抽象基类和模板类来提供示例阅读器的不同实现。使用抽象接口,以后的代码不需要知道它是否处理8位或16位样本。
#include <fstream>
#include <vector>
#include <exception>
class SampleReader
{
public:
virtual void readSample( std::ifstream &in ) = 0;
};
template<class T>
class SampleReaderT : public SampleReader
{
public:
virtual void readSample( std::ifstream &in )
{
while (!in.eof()) {
const T value = readOneValue(in);
if (in) {
_sample.push_back();
} else {
break;
}
}
}
private:
T readOneValue( std::ifstream &in )
{
T inputUnit;
in.read((char*)&inputUnit,sizeof(T));
}
private:
std::vector<T> _sample;
};
typedef SampleReaderT<int8_t> SampleReader8Bit;
typedef SampleReaderT<int16_t> SampleReader16Bit;
int main(int argc, char** argv)
{
int sampleBits = 8;
SampleReader *sampleReader = nullptr;
if (sampleBits == 8) {
sampleReader = new SampleReader8Bit();
} else if (sampleBits == 16) {
sampleReader = new SampleReader16Bit();
} else {
throw std::out_of_range("unknown bit number");
}
std::ifstream in("test.dat");
sampleReader->readSample(in);
}
请注意此示例中的以下内容:
SampleReader
的指针,而不必知道这是一个8位还是16位的样本阅读器。