减少使用C一个WAV音频文件的音量 [英] Reduce the volume of a Wav audio file using C

查看:284
本文介绍了减少使用C一个WAV音频文件的音量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写编辑WAV音频文件的C程序。
我已经加载的所有文件中DATAS无符号整型值的数组(UINT16_T)。

现在,我想,以减少文件的体积。
我认为这是足以降低(一定比例的)单一数值的价值。但是,如果我这样做,我得到噪声的音频文件(我想我明白被称为静态或点击噪音)

为什么呢?这是正确的程序?

感谢您!

这是影响到了一块code的:

  FILE * FP;
    FILE * FP2;    / *我的文件*的尺寸/
    的#define BUFFER_SIZE 28242852    / *数组与文件数据* /
    无符号字符*缓冲区;    / *用于在一个unsigned int *转换两个字节数组/
    unsigned char型uintBytes [2];    / *获得将unsigned int * /
    uint16_t * CONV;    / *新的值来计算* /
    uint16_t nuovoValore;    / *用于反向转换阵列,形式UINT为字节* /
    无符号字符* nuovoValArray;    对于(I = 44; I< BUFFER_SIZE;我++){    如果(ⅰ%2 == 0){        / *我读2个字节组成的阵列和转换它一个unsigned int * /
        uintBytes [0] =缓冲液[I];
        uintBytes [1] =缓冲第[i + 1];        CONV =(uint16_t *)及uintBytes [0];          / *计算新的值(-30%),在新文件*写/        nuovoValore = * CONV - ((浮点)* CONV * 30/100);
                  如果(nuovoValore℃,)nuovoValore = 0;                     nuovoValArray = malloc的(2);
         memset的(nuovoValArray,'\\ 0',2);
        nuovoValArray =(无符号字符*)及nuovoValore;
            / *写新文件*的两个字节/
        的fwrite(&放大器; nuovoValArray [0],1,1,FP2);
        的fwrite(&放大器; nuovoValArray [1],1,1,FP2);
    }
}


解决方案

为了简单起见,编译程序前检查您的音频文件的所有规格。一个普通的 .WAV 文件具有以下属性:


  • 没有COM pression(音频格式将PCM)

  • 16位采样

  • 单声道(虽然你的程序可能会与立体声工作)

所以确保你解析音频文件中包含这些属性。一旦验证这些属性是常见的音频文件,然后就可以开始测试。如果您的文件不包含这些属性,你可能要考虑让无畏,或类似的东西,使测试 .WAV 文件。

您code是一个有些奇怪。首先,你投的数据作为字符,然后 INT ,然后进入浮动。那将会给你一些严重的错误。所有这些数据类型都在大小不同。 浮动也有完全不同的二进制格式。 A INT 的价值 65 可能是一个浮动 -34564.23 (或类似的东西)。只需使用
int16_t

我也看到你已经开了两个文件到您的code - 不用麻烦了,因为它使code大。保持你的code简单,只要你可以直到你想要做什么 - 然后添加辅助属性

此外,在你的 fwrites 你写 FWRITE(安培; nuovoValArray [0],1,1,FP2),但它应该是 FWRITE(安培; nuovoValArray [0],2个,1个,FP2),因为大小 int16_t 为2个字节,而不是1。

当谈到减少文件体积,下面是应该工作的一般方法:


  • 获取样本 SAMP [I] (16位或2个字节)

  • 降低音量: SAMP [I] - =(int16_t)(SAMP [I] *百分比);

  • 增量 I

  • 重复

下面是code的片段,可以帮助:

  //打开文件
//读成char * fileBufferINT sampleCount =((档案大小 - dataOffset)/的sizeof(int16_t));
int16_t * SAMP =(int16_t *)及fileBuffer [dataOffset];
浮动百分比= 0.6f;的for(int i = 0; I< sampleCount;我++){
    SAMP [Ⅰ] - =(int16_t)(SAMP [I] *百分比); //应该工作+/-值
}// 保存存档

我previously写了一个应用程序,图形 .WAV 文件波形分析。所有我不得不读学习文件格式这个页面 - 它应该帮助你。

I am writing a C program for editing a Wav audio file. I have loaded all file datas in an array of unsigned integer values (UINT16_T).

Now, i would like to reduce the volume of the file. I thought it was enough to decrease the value (of a certain percentage) of the single values. But if i do that, i obtain an audio file with noise (I think I understand is called "static" or "click noise")

Why? Which is the right procedure?

Thank You!

This is the piece of code affected:

    FILE* fp;
    FILE* fp2;

    /*Size of my file*/
    #define BUFFER_SIZE 28242852

    /*Array with file data*/
    unsigned char *buffer;

    /*Array used for converting two bytes in an unsigned int*/
    unsigned char uintBytes[2];

    /*The unsigned int obtained*/
    uint16_t * conv;

    /*The new value calculated*/
    uint16_t nuovoValore;

    /*Array used for the reverse conversion, form UINT to bytes*/
    unsigned char* nuovoValArray;



    for(i=44; i<BUFFER_SIZE;i++){

    if(i%2==0){

        /*I read 2 bytes form the array and "convert" it in an unsigned int*/
        uintBytes[0]=buffer[i];
        uintBytes[1]=buffer[i+1];

        conv=(uint16_t *) &uintBytes[0];

          /*Calculate the new value (-30%) to write in the new file*/

        nuovoValore= *conv - ((float)*conv*30/100);
                  if(nuovoValore<0) nuovoValore=0;

                     nuovoValArray=malloc(2);
         memset(nuovoValArray,'\0',2);
        nuovoValArray=(unsigned char*)&nuovoValore;


            /*Write the two bytes of the new file*/
        fwrite(&nuovoValArray[0], 1, 1, fp2); 
        fwrite(&nuovoValArray[1], 1, 1, fp2);


    }
}

解决方案

To keep things simple, check all the specs of your audio file before compiling your program. A plain .wav file has the following attributes:

  • No compression (Audio format would be PCM)
  • 16 bit samples
  • Mono-channel (although your program might work with stereo)

So make sure the audio file you're parsing contains these attributes. Once you have verified that these attributes are common to your audio file, then you can begin testing. If your file does not contain these attributes, you may want to consider getting Audacity, or something similar, to make test .wav files.

Your code is a little strange. First you cast the data as a char, then to int, and then into float. That's going to give you some serious errors. All of these data types are different in size. Float also has a completely different binary format. A int of value 65 may be a float of -34564.23 (or something like that). Just use int16_t.

I also see that you've opened two files for your code - don't bother, since it makes the code bigger. Keep your code as simple as you can until it does what you want - then add the auxiliary attributes.

Also, on your fwrites you've written fwrite (&nuovoValArray[0], 1, 1, fp2) but it should be fwrite (&nuovoValArray[0], 2, 1, fp2) since the size of int16_t is 2 bytes and not 1.

When it comes to reducing the volume of the file, here's a general approach that should work:

  • Get sample samp[i] (16-bit or 2 bytes)
  • Reduce the volume: samp[i] -= (int16_t) (samp[i] * percent);
  • Increment i
  • Repeat

Here's a snippet of code that might help:

// open file
// read into char * fileBuffer

int sampleCount = ((fileSize - dataOffset) / sizeof (int16_t)); 
int16_t * samp  = (int16_t *) &fileBuffer[dataOffset];
float percent   = 0.6f;

for (int i = 0; i < sampleCount; i++){
    samp[i] -= (int16_t) (samp[i] * percent); // Should work +/- values
}

// save file

I previously had written an applications that graphs .wav files for waveform analysis. All I had to read to learn the file format was this page - it should help you as well.

这篇关于减少使用C一个WAV音频文件的音量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆