使用c更改.wav文件的音量?

问题描述

我的代码只是复制标题,但在第二个循环时不更改音量。

// Todo: copy header from the input file to the output file

uint8_t header[HEADER_SIZE];
uint8_t* header_p=malloc(HEADER_SIZE * sizeof(uint8_t));
while(fread(&header_p,sizeof(header[HEADER_SIZE]),1,input))
{
    fwrite(&header_p,output);
}

// Todo: Read samples from the input file and write updated data to the output file

int16_t buffer;

while(fread(&buffer,sizeof(buffer),input))
{
    buffer =(int16_t)(buffer*factor);
    fwrite(&buffer,output);
}

解决方法

如果特定的WAV文件仅包含一个标头,后跟代表声音数据的16位带符号值,则您的错误将出现在第一个while循环中。此循环继续从输入到输出复制sizeof(header[HEADER_SIZE])(实际上是标头中一个元素的大小为1)的块,直到到达文件末尾为止,第二个while循环不会被输入。>

只需复制一次标头,然后使用更合适的缩放算法即可解决其他一些问题。例如:

uint8_t header[HEADER_SIZE];
/* There is only one header,so parse it just once */
if (fread(&header[0],sizeof(header),1,input)) {
    fwrite(&header[0],output);
}

/* Assuming 16-bit signed integer PCM payload */
int16_t sample;
while(fread(&sample,sizeof(sample),input)) {
    /* Round value to nearest number */
    double scaledValue = floor((sample * factor) + 0.5);

    /* Clamp new value */
    if (scaledValue >= INT16_MAX) {
        sample = INT16_MAX;
    } else if (scaledValue <= INT16_MIN) {
        sample = INT16_MIN;
    } else {
        sample = (int16_t)scaledValue;
    }
    fwrite(&sample,output);
}

但是.wav文件格式不是那么简单,并且具有多种变体,但是16位带符号PCM值只是其中之一。标头中也提供了示例数据的大小和格式,您将需要仔细分析标头并采取相应的措施。有关.wav文件格式的更多信息,我认为这是一个不错的起点: