如何更改 .wav 文件的音量?
How to change the volume of a .wav file?
我的代码只是复制 header 但不会在第二个循环中更改音量。
// 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,sizeof(header[HEADER_SIZE]),1,output);
}
// TODO: Read samples from the input file and write updated data to the output file
int16_t buffer;
while(fread(&buffer,sizeof(buffer),1,input))
{
buffer =(int16_t)(buffer*factor);
fwrite(&buffer,sizeof(buffer),1,output);
}
如果一个特定的 WAV 文件仅包含 header 后跟代表声音数据的 16 位带符号值,则您的错误将出现在第一个 while 循环中。此循环继续从输入到输出复制 sizeof(header[HEADER_SIZE])
(实际上是 header 中一个元素的大小为 1)个块,直到文件末尾为止,第二个 while 循环将不会已进入。
只需复制一次header,并使用更合适的缩放算法来修复其他一些问题。例如:
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], sizeof(header), 1, output);
}
/* Assuming 16-bit signed integer PCM payload */
int16_t sample;
while(fread(&sample, sizeof(sample), 1, 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, sizeof(sample), 1, output);
}
然而 .wav 文件格式并没有那么简单并且有多种变体,16 位带符号 PCM 值只是其中之一。 header 中还给出了示例数据的大小和格式,您需要仔细解析 header 并采取相应的行动。有关 .wav 文件格式的更多信息,我想这些是一个很好的起点:
我的代码只是复制 header 但不会在第二个循环中更改音量。
// 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,sizeof(header[HEADER_SIZE]),1,output);
}
// TODO: Read samples from the input file and write updated data to the output file
int16_t buffer;
while(fread(&buffer,sizeof(buffer),1,input))
{
buffer =(int16_t)(buffer*factor);
fwrite(&buffer,sizeof(buffer),1,output);
}
如果一个特定的 WAV 文件仅包含 header 后跟代表声音数据的 16 位带符号值,则您的错误将出现在第一个 while 循环中。此循环继续从输入到输出复制 sizeof(header[HEADER_SIZE])
(实际上是 header 中一个元素的大小为 1)个块,直到文件末尾为止,第二个 while 循环将不会已进入。
只需复制一次header,并使用更合适的缩放算法来修复其他一些问题。例如:
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], sizeof(header), 1, output);
}
/* Assuming 16-bit signed integer PCM payload */
int16_t sample;
while(fread(&sample, sizeof(sample), 1, 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, sizeof(sample), 1, output);
}
然而 .wav 文件格式并没有那么简单并且有多种变体,16 位带符号 PCM 值只是其中之一。 header 中还给出了示例数据的大小和格式,您需要仔细解析 header 并采取相应的行动。有关 .wav 文件格式的更多信息,我想这些是一个很好的起点: