【问题标题】:analyzing .WAV files分析 .WAV 文件
【发布时间】:2017-11-19 17:06:04
【问题描述】:

我目前正在处理 .WAV 文件,我有一个问题。

我解决这个问题的方法是创建一个包含信息的结构:

typedef struct header_file{
    char chunk_id[4];
    int chunk_size;
    char format[4];
    char subchunk1_id[4];
    int subchunk1_size;
    short int audio_format;
    short int num_channels;
    int sample_rate;           
    int byte_rate;
    short int block_align;
    short int bits_per_sample;
    char subchunk2_id[4];
    int subchunk2_size; 
}header;

typedef struct header_file* wav_p;

现在,我尝试运行 WAV 文件,如下所示:

    ofstream myFile;
    myFile.open("file.txt");
    FILE * file = fopen("file.wav", "rb");

    const int BUFFSIZE = 256;                           
    int count = 0;                                      
    short int buff[BUFFSIZE];                           
    wav_p wav = (wav_p)malloc(sizeof(header));
    int nb;                                             

    if (file)
    {
        fread(wav, 1, sizeof(header), file);    
        while (!feof(file)){
            nb = fread(buff, 1, BUFFSIZE, file);
            count++;

            for (int i = 0; i<BUFFSIZE; i += 1){
                //the following part i found on the internet so i'm not sure if it is good
                int h = (signed char)buff[i + 1];
                int c = (h << 8) | buff[i];
                double t = c / 32768.0;

                myFile << t << endl;
                if(abs(t)>1){
                //checking that a value is between -1 to 1
                }
            }
        }
    }
    fclose(file);
    myFile.close();

我的问题是:内部for 是否正确?在file.txt 中,我所有的值都在-1 到1 之间,所以我认为这很好,但我不确定,我是否正确地检查了.wav 文件并且我把它放在“file.txt”中的方式是好(“file.txt”是否包含文件函数的“y轴”值,其中“x轴”是时间)

【问题讨论】:

  • 这里发布的代码中有一个错误 - 有一个未声明的变量 hi。此外,如果您能说出出现了什么错误,让您认为您的程序有问题,那将会很有帮助。
  • 我写了hi而不是h,我编辑了它。我没有收到任何错误,但是因为我从互联网上获取了int h = (signed char)buff[i + 1]; int c = (h &lt;&lt; 8) | buff[i]; double t = c / 32768.0;,所以我不知道它是否是正确的计算方法t

标签: c++ audio wav


【解决方案1】:

您的代码大部分是正确的。您没有检查 wav 标头来验证波形文件是否实际包含 16 位样本。

您对 16 位值的计算是错误的,因为 buffshort int 的数组。如果buffchar 数组,那么您使用的计算将是正确的(但您必须将i 增加2)。

使用short int 数组,您可以只说int c = buff[i];,除非您的系统是大端系统。

检查abs(t) &gt; 1 是不必要的,因为-1.0 c

【讨论】:

  • 所以把int h = (signed char)buff[i + 1]; int c = (h &lt;&lt; 8) | buff[i];改成int c = buff[i];?
  • @YuvalPaz 正确。
  • 很抱歉再次打扰您,但有人告诉我for 必须是for (...;...; i += wav-&gt;num_channels) 而不是for (...;...; i += 1),这有关系吗?
  • @YuvalPaz 您只处理循环中的 1 个通道,因此递增 i 将允许您访问所有样本。如果您只想要一个通道的音频数据,则增加通道数是合适的。
猜你喜欢
  • 2015-09-09
  • 2012-05-24
  • 2013-06-13
  • 1970-01-01
  • 2012-01-13
  • 1970-01-01
  • 1970-01-01
  • 2016-10-26
  • 1970-01-01
相关资源
最近更新 更多