Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用C+;读取wav文件时出错+; 我有一个.wav文件,我想用C++来阅读。我对RIFF文件头做了一些研究,并编写了加载代码 #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> using namespace std; #define BUFFER_LEN 4096 int main(int argc,char * argv[]) { // Buffers etc.. char ChunkID[4], Format[4], Subchunk1ID[4],Subchunk2ID[4]; int ChunkSize,Subchunk1Size, SampleRate, ByteRate,Subchunk2Size; short AudioFormat, NumChannels, BlockAlign, BitsPerSample; // Read the wave file FILE *fhandle=fopen(argv[1],"rb"); fread(ChunkID,1,4,fhandle); fread(&ChunkSize,4,1,fhandle); fread(Format,1,4,fhandle); fread(Subchunk1ID,1,4,fhandle); fread(&Subchunk1Size,4,1,fhandle); fread(&AudioFormat,2,1,fhandle); fread(&NumChannels,2,1,fhandle); fread(&SampleRate,4,1,fhandle); fread(&ByteRate,4,1,fhandle); fread(&BlockAlign,2,1,fhandle); fread(&BitsPerSample,2,1,fhandle); fread(&Subchunk2ID,1,4,fhandle); fread(&Subchunk2Size,4,1,fhandle); fclose(fhandle); // print RIFF info printf("\%c",ChunkID[0]); printf("\%c",ChunkID[1]); printf("\%c",ChunkID[2]); printf("\%c",ChunkID[3]); cout << endl; // print chunk size printf("%d",ChunkSize); cout << endl; // print format printf("\%c",Format[0]); printf("\%c",Format[1]); printf("\%c",Format[2]); printf("\%c",Format[3]); cout << endl; // print sub chunk 1 ID printf("\%c",Subchunk1ID[0]); printf("\%c",Subchunk1ID[1]); printf("\%c",Subchunk1ID[2]); printf("\%c",Subchunk1ID[3]); cout << endl; // print sub chunk 1 size printf("%d",Subchunk1Size); cout << endl; // print audio format printf("%hd",AudioFormat); cout << endl; // print number of channels printf("%hd",NumChannels); cout << endl; return 0; }_C++_Audio_Wav_Riff - Fatal编程技术网

使用C+;读取wav文件时出错+; 我有一个.wav文件,我想用C++来阅读。我对RIFF文件头做了一些研究,并编写了加载代码 #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> using namespace std; #define BUFFER_LEN 4096 int main(int argc,char * argv[]) { // Buffers etc.. char ChunkID[4], Format[4], Subchunk1ID[4],Subchunk2ID[4]; int ChunkSize,Subchunk1Size, SampleRate, ByteRate,Subchunk2Size; short AudioFormat, NumChannels, BlockAlign, BitsPerSample; // Read the wave file FILE *fhandle=fopen(argv[1],"rb"); fread(ChunkID,1,4,fhandle); fread(&ChunkSize,4,1,fhandle); fread(Format,1,4,fhandle); fread(Subchunk1ID,1,4,fhandle); fread(&Subchunk1Size,4,1,fhandle); fread(&AudioFormat,2,1,fhandle); fread(&NumChannels,2,1,fhandle); fread(&SampleRate,4,1,fhandle); fread(&ByteRate,4,1,fhandle); fread(&BlockAlign,2,1,fhandle); fread(&BitsPerSample,2,1,fhandle); fread(&Subchunk2ID,1,4,fhandle); fread(&Subchunk2Size,4,1,fhandle); fclose(fhandle); // print RIFF info printf("\%c",ChunkID[0]); printf("\%c",ChunkID[1]); printf("\%c",ChunkID[2]); printf("\%c",ChunkID[3]); cout << endl; // print chunk size printf("%d",ChunkSize); cout << endl; // print format printf("\%c",Format[0]); printf("\%c",Format[1]); printf("\%c",Format[2]); printf("\%c",Format[3]); cout << endl; // print sub chunk 1 ID printf("\%c",Subchunk1ID[0]); printf("\%c",Subchunk1ID[1]); printf("\%c",Subchunk1ID[2]); printf("\%c",Subchunk1ID[3]); cout << endl; // print sub chunk 1 size printf("%d",Subchunk1Size); cout << endl; // print audio format printf("%hd",AudioFormat); cout << endl; // print number of channels printf("%hd",NumChannels); cout << endl; return 0; }

使用C+;读取wav文件时出错+; 我有一个.wav文件,我想用C++来阅读。我对RIFF文件头做了一些研究,并编写了加载代码 #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> using namespace std; #define BUFFER_LEN 4096 int main(int argc,char * argv[]) { // Buffers etc.. char ChunkID[4], Format[4], Subchunk1ID[4],Subchunk2ID[4]; int ChunkSize,Subchunk1Size, SampleRate, ByteRate,Subchunk2Size; short AudioFormat, NumChannels, BlockAlign, BitsPerSample; // Read the wave file FILE *fhandle=fopen(argv[1],"rb"); fread(ChunkID,1,4,fhandle); fread(&ChunkSize,4,1,fhandle); fread(Format,1,4,fhandle); fread(Subchunk1ID,1,4,fhandle); fread(&Subchunk1Size,4,1,fhandle); fread(&AudioFormat,2,1,fhandle); fread(&NumChannels,2,1,fhandle); fread(&SampleRate,4,1,fhandle); fread(&ByteRate,4,1,fhandle); fread(&BlockAlign,2,1,fhandle); fread(&BitsPerSample,2,1,fhandle); fread(&Subchunk2ID,1,4,fhandle); fread(&Subchunk2Size,4,1,fhandle); fclose(fhandle); // print RIFF info printf("\%c",ChunkID[0]); printf("\%c",ChunkID[1]); printf("\%c",ChunkID[2]); printf("\%c",ChunkID[3]); cout << endl; // print chunk size printf("%d",ChunkSize); cout << endl; // print format printf("\%c",Format[0]); printf("\%c",Format[1]); printf("\%c",Format[2]); printf("\%c",Format[3]); cout << endl; // print sub chunk 1 ID printf("\%c",Subchunk1ID[0]); printf("\%c",Subchunk1ID[1]); printf("\%c",Subchunk1ID[2]); printf("\%c",Subchunk1ID[3]); cout << endl; // print sub chunk 1 size printf("%d",Subchunk1Size); cout << endl; // print audio format printf("%hd",AudioFormat); cout << endl; // print number of channels printf("%hd",NumChannels); cout << endl; return 0; },c++,audio,wav,riff,C++,Audio,Wav,Riff,你可以看到“fmt”是“假的” 然后,我使用sox通过以下方式转换此wav文件: sox OS.wav test.wav 然后再次运行我的代码。它有以下信息: RIFF 307201488 WAVE Fake 2 0 28006 RIFF 307200050 WAVE fmt 18 3 2 我没有改变任何事情。但是标题信息是如此不同。有谁能告诉我为什么会这样吗 谢谢。您假设fmt块是RIFF/WAVE块中的第一个子块。这不是一项要求或保证。对RIFF/WAV格式做更多的研究WAVE子块可

你可以看到“fmt”是“假的”

然后,我使用sox通过以下方式转换此wav文件:

sox OS.wav test.wav
然后再次运行我的代码。它有以下信息:

RIFF
307201488
WAVE
Fake
2
0
28006
RIFF
307200050
WAVE
fmt 
18
3
2
我没有改变任何事情。但是标题信息是如此不同。有谁能告诉我为什么会这样吗


谢谢。

您假设
fmt
块是
RIFF/WAVE
块中的第一个子块。这不是一项要求或保证。对RIFF/WAV格式做更多的研究
WAVE
子块可以以任何顺序出现,唯一的规则是
fmt
块必须出现在
data
块之前,但其他块可以出现在它们之前、之后和中间

解析文件的正确方法是一次循环一个子块。读取chunkID和chunkSize,然后读取指定数量的字节(考虑填充),并根据需要根据chunkID进行处理,然后重复,直到EOF。这可以让你处理你感兴趣的块,跳过你不关心的块。不要对它们的顺序做任何假设(但要验证一个特殊情况),并且绝对不要假设
fmt
块是第一个块,因为它可能不是

尝试类似以下内容:

#include <iostream>
#include <istream>
#include <stdexcept>
#include <string>

using namespace std;

struct chunkHdr
{
   char id[4];
   unsigned int size;
   unsigned int pos;
};

bool isChunkID(const chunkHdr &c, char id1, char id2, char id3, char id4)
{
    return ((c.id[0] == id1) &&
            (c.id[1] == id2) &&
            (c.id[2] == id3) &&
            (c.id[3] == id4));
}

void read(ifstream &f, void *buffer, streamsize size, chunkHdr *parent)
{
    if (!f.read(static_cast<char*>(buffer), size))
    {
        if (f.eof())
            throw runtime_error("Unexpected EOF while reading from file");
        throw runtime_error("Unable to read from file");
    }
    if (parent) parent->pos += size;
}

void skip(ifstream &f, streamsize size, chunkHdr *parent)
{
    if (!f.seekg(size, ios_base::cur))
        throw runtime_error("Unable to read from file");
    if (parent) parent->pos += size;
}

void read(ifstream &f, chunkHdr &c, chunkHdr *parent)
{
    read(f, c.id, 4, parent);
    read(f, &(c.size), 4, parent);
    c.pos = 0;
}

int main(int argc, char * argv[])
{
    // Buffers etc..
    chunk riff, wave, chk;
    bool fmtFound = false;

    try
    {
        // Open the wave file
        ifstream wavFile(argv[1], ios_base::binary);
        if (!wavFile)
            throw runtime_error("Unable to open file");

        // check the RIFF header
        read(wavFile, riff, NULL);
        if (!isChunkID(riff, 'R', 'I', 'F', 'F'))
            throw runtime_error("File is not a RIFF file");
        cout << "RIFF Size: " << riff.size << endl;

        // check the WAVE header
        read(wavFile, wave.id, 4, &riff);
        wave.size = riff.size - 4;
        wave.pos = 0;

        cout << "RIFF Type: '" << string(wave.id, 4) << "'" << endl;
        if (!isChunkID(wave, 'W', 'A', 'V', 'E'))
            throw runtime_error("File is not a WAV file");

        // read WAVE chunks
        while (wave.pos < wave.size)
        {
            read(wavFile, chk, &wave);
            cout << "Chunk: '" << string(chk.id, 4) << "', Size: " << chk.size << endl;

            if (isChunkID(chk, 'f', 'm', 't', ' '))
            {
                if (fmtFound)
                    throw runtime_error("More than one FMT chunk encountered");
                fmtFound = true;

                unsigned int SampleRate, ByteRate;
                unsigned short AudioFormat, NumChannels, BlockAlign, BitsPerSample, ExtraSize;

                read(wavFile, &AudioFormat, 2, &chk);
                read(wavFile, &NumChannels, 2, &chk);
                read(wavFile, &SampleRate, 4, &chk);
                read(wavFile, &ByteRate, 4, &chk);
                read(wavFile, &BlockAlign, 2, &chk);

                cout << "  Audio Format: " << AudioFormat << endl;
                cout << "  Channels: " << NumChannels << endl;
                cout << "  Sample Rate: " << SampleRate << endl;
                cout << "  Byte Rate: " << ByteRate << endl;
                cout << "  BlockAlign: " << BlockAlign << endl;

                if (chk.size >= 16)
                {
                    read(wavFile, &BitsPerSample, 2, &chk);
                    cout << "  Bits per Sample: " << BitsPerSample << endl;
                }

                if (chk.size >= 18)
                {
                    read(wavFile, &ExtraSize, 2, &chk);
                    cout << "  Extra Size: " << ExtraSize << endl;

                    if (ExtraSize > 0)
                    {
                        // read and process ExtraSize number of bytes as needed...
                        skip(wavFile, ExtraSize, &chk);
                    }
                }

                if (chk.pos < chk.size)
                    skip(wavFile, chk.size - chk.pos, &chk);
            }
            else if (isChunkID(chk, 'd', 'a', 't', 'a'))
            {
                if (!fmtFound)
                    throw runtime_error("No FMT chunk encountered before DATA chunk");

                // read and process chk.size number of bytes as needed...
                skip(wavFile, chk.size, &chk);
            }

            // read other chunks as needed...

            else
            {
                // skip an unwanted chunk
                skip(wavFile, chk.size, &chk);
            }

            // all done with this chunk
            wave.pos += chk.pos;

            // check for chunk padding
            if (chk.size % 2)
                skip(wavFile, 1, &wave);
        }
    }
    catch (const exception &e)
    {
        cout << "Error! " << e.what() << endl;
    }

    return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
结构chunkHdr
{
字符id[4];
无符号整数大小;
无符号整数位置;
};
bool isChunkID(常量chunkHdr&c、字符id1、字符id2、字符id3、字符id4)
{
返回((c.id[0]==id1)&&
(c.id[1]==id2)&&
(c.id[2]==id3)&&
(c.id[3]==id4));
}
void read(ifstream&f、void*缓冲区、streamsize大小、chunkHdr*父级)
{
如果(!f.read(静态_转换(缓冲区),大小))
{
if(f.eof())
抛出运行时_错误(“读取文件时出现意外EOF”);
抛出运行时_错误(“无法读取文件”);
}
如果(父项)父项->位置+=大小;
}
无效跳过(ifstream&f、streamsize、chunkHdr*父项)
{
如果(!f.seekg(尺寸,ios_基::cur))
抛出运行时_错误(“无法读取文件”);
如果(父项)父项->位置+=大小;
}
无效读取(ifstream&f、chunkHdr&c、chunkHdr*父级)
{
阅读(f,c.id,4,家长);
读取(f和c尺寸),4,父级;
c、 pos=0;
}
int main(int argc,char*argv[])
{
//缓冲器等。。
块裂、波浪、chk;
bool-fmtFound=false;
尝试
{
//打开wave文件
ifstream wavFile(argv[1],ios_base::binary);
如果(!wavFile)
抛出运行时_错误(“无法打开文件”);
//检查里夫头
读取(wavFile、riff、NULL);
如果(!isChunkID(riff,'R,'I,'F,'F'))
抛出运行时_错误(“文件不是RIFF文件”);

原始WAV文件可能是从一个破解程序中导出的吗?它可能是程序员强加的一个演示限制……或者,它可能只是一个自定义的
块,在到达真正的
fmt
块之前不会被跳过。RIFF/WAVE块可以是任何顺序,只要
fmt
chunk在
数据
chunk之前。通过sox运行文件很可能会剥离
chunk。谢谢。我在线获得了格式。在我看来,格式是固定的。你对我可以学习wave文件处理或说音频处理有什么建议吗?格式不是固定的,你的test WAV文件证明了这一点。WAV格式定义了许多块类型(并非所有的WAV文件都使用这些类型),自定义块类型也可以在不影响音频处理的情况下使用,因为
fmt
data
块是独立于其他块处理的。