我尝试使用两种稍微不同的方式复制wav样本。第一种方式给我正确的输出文件声音,第二种方式-失真的声音:
- 写大小写:*
int16_t samp;
while (fread(&samp, sizeof(int16_t), 1, input))
{
samp *= factor;
fwrite(&samp, sizeof(int16_t), 1, output);
}
- fputc大小写:*
int16_t samp;
while ((samp = fgetc(input)) != EOF)
{
samp *= factor;
fputc(samp, output);
}
我已经知道,这正是因为第二种情况下的samp *= factor;
。当我使用不带小数点的数字时,音量会正常变化,而当我使用浮点数时,声音会失真。
所以我的问题是:* 为什么它在fwrite
的情况下工作,而在fputc
的情况下不工作?* 它们都是 int 乘以 float。它在第一种情况下是如何工作的?
下面是一个完整的程序供参考:
// Modifies the volume of an audio file
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
// Number of bytes in .wav header
const int HEADER_SIZE = 44;
int main(int argc, char *argv[])
{
// Check command-line arguments
if (argc != 4)
{
printf("Usage: ./volume input.wav output.wav factor\n");
return 1;
}
// Open files and determine scaling factor
FILE *input = fopen(argv[1], "r");
if (input == NULL)
{
printf("Could not open file.\n");
return 1;
}
FILE *output = fopen(argv[2], "w");
if (output == NULL)
{
printf("Could not open file.\n");
return 1;
}
float factor = atof(argv[3]);
// Copy header from input file to output file
uint8_t *hder = malloc(sizeof(uint8_t) * HEADER_SIZE);
fread(hder, sizeof(uint8_t), HEADER_SIZE, input);
fwrite(hder, sizeof(uint8_t), HEADER_SIZE, output);
free(hder);
// Read samples from input file and write updated data to output file
int16_t samp;
while (fread(&samp, sizeof(int16_t), 1, input))
{
samp *= factor;
fwrite(&samp, sizeof(int16_t), 1, output);
}
// while ((samp = fgetc(input)) != EOF)
// {
// samp *= factor;
// fputc(samp, output);
// }
// Close files
fclose(input);
fclose(output);
}
1条答案
按热度按时间wvt8vs2t1#
从
fputc
docs on cppreference.com:在内部,字符会在写入之前转换为unsigned char。
当你调用
fputc
时,你的16位samp
被转换为8位unsigned char
。使用fwrite
,两个字节都被写入输出文件。