从二进制文件中读取一个Int

时间:2013-08-18 21:02:50

标签: c++ wav binary-data ifstream fread

我一直在从.Wav文件中读取一个int。我一直在遵循Here列出的.wav规范。我正在尝试从头部读取一个int(Subchunk2Size),然后将数据读入一个short数组。我遇到了fread()和ifstream.read()的障碍。我将列出我的阅读技巧问题,但实际上只需要一个答案。

的fread()

    sprintf(filename, "C:\\Users\\MacbookWin7\\wavs\\%s.wav", word);
FILE * infile = fopen(filename, "rb");
if (infile != NULL)
{
    int f = ferror(infile);
    int d = fseek(infile, 40, SEEK_SET);
    int * subChunk2Size = new int[1];
    int i = fread(subChunk2Size, sizeof(int), 1, infile);
    int g = ferror(infile);

问题:fread没有读取任何内容,我总是初始化为0.

我尝试了许多不同的声明subChunk2Size的组合,试图声明一个指针,一个数组 - 包含单个和多个元素,声明一个nullptr,并声明一个int并传入它的引用。

ifstream.read()

    sprintf(filename, "C:\\Users\\MacbookWin7\\wavs\\%s.wav", word);
ifstream sampleStream(filename,ios::binary);
char * samplesStr;

if (sampleStream.is_open())
{
    sampleStream.seekg(40);
    char * subChunk2SizeStr = new char[4];
    sampleStream.read(subChunk2SizeStr, 4);
    int subChunk2Size = 0;
    for (int i = 3; i >= 0; i--)
    {
        subChunk2Size = (subChunk2Size << 8) + subChunk2SizeStr[i];
    }
    int numBytes = subChunk2Size + *nsamples * 2;
    char * samplesStr = new char[numBytes];
    sampleStream.read(samplesStr, numBytes);
    sampleStream.close();
    short * samples = new short[numBytes / 2];
    for (int i = 0; i < numBytes / 2; i++)
    {
        int b = i * 2;
        samples[i] = samplesStr[b+1];
        samples[i] = (samples[i] << 8) + samplesStr[b];
    }

问题:我的第一次读取和位移会产生大约22,000的正确答案,但我无法通过第二次循环读取短片。

我要感谢任何人对我的问题进行一些考虑。

1 个答案:

答案 0 :(得分:3)

我接受了你的代码,稍微破坏了它,当我使用每个样本16位的立体声输入时,它似乎显示出合理的结果,例如this

#include <fstream>
#include <cstdio>
#include <iostream>
#include <climits>

using namespace std;

int main()
{
    const char *filename = "audio/M1F1-int16-AFsp.wav";
    ifstream sampleStream(filename,ios::binary);
    int nsamples = 10000;
    short * samples;
    if (sampleStream.is_open())
    {
        sampleStream.seekg(44);  // Skip all of the header. 
        samples = new short[nsamples];
        sampleStream.read(reinterpret_cast<char *>(samples), sizeof(short)*nsamples);
        sampleStream.close();
    }
    short max = 0; 
    short min = 32767;
    int min_at = 0; 
    int max_at = 0;
    for(int i = 0; i < nsamples; i++)
    {
        if (samples[i] > max) 
        {
            max = samples[i];
            max_at = i;
        }
        if (samples[i] < min)
        {
            min = samples[i];
            min_at = i;
        }
    }
    cout << "Max=" << max << " at " << max_at << endl;
    cout << "Min=" << min << " at " << min_at << endl;
}

它显示样品990处的14325处的顶峰[立体声中的样品495],以及8766处的最低水平-7125,当与audacity软件中的值相比时,两者都匹配。请注意,我依赖于我的机器上的x86处理器是小端。如果你在Mac上运行,那也是如此,除非它是一台非常古老的PowerPC Mac。