调整音频文件音量的C程序出现Segmentation Fault问题求助
问题分析与修复方案
你的代码存在多个关键错误,直接导致了段错误和功能异常,以下是逐个问题的解决方法:
1. 未正确处理WAV文件头
WAV文件前44字节是格式头信息,不能参与音量调整,必须完整复制到输出文件后,再处理后续的音频样本。你的代码直接跳过这一步,开始修改头数据,既破坏了输出文件格式,也会引发后续读取错误。
2. 内存分配与样本类型错误
BYTE *buffer = malloc(sizeof(buffer));中,sizeof(buffer)计算的是指针变量的大小(如64位系统为8字节),而非音频样本的实际大小。- 标准WAV的音频样本是16位有符号整数(int16_t),用单字节的
BYTE处理会丢失数据精度,甚至触发内存访问错误。
3. fread/fwrite参数错误
fread(&buffer, sizeof(buffer), 1, input) 里:
- 第一个参数应该是缓冲区起始地址
buffer,而非&buffer(指针的地址,类型不匹配); - 第二个参数应该是单个样本的大小(如
sizeof(int16_t)),而非指针的大小。
4. 循环条件错误
fread的返回值是成功读取的元素个数,判断循环结束应该用!= 0,而非!= EOF——EOF是字符读取专用宏,二进制文件读取用元素个数判断更准确。
修复后的完整代码
// 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; typedef uint8_t BYTE; typedef int16_t SAMPLE; // 标准WAV音频样本为16位有符号整数 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"); fclose(input); // 打开失败时及时关闭已打开的输入文件,避免资源泄漏 return 1; } float factor = atof(argv[3]); // 复制WAV文件头到输出文件 BYTE header[HEADER_SIZE]; fread(header, sizeof(BYTE), HEADER_SIZE, input); fwrite(header, sizeof(BYTE), HEADER_SIZE, output); // 分配单个音频样本的缓冲区 SAMPLE *sample = malloc(sizeof(SAMPLE)); if (sample == NULL) { printf("Memory allocation failed.\n"); fclose(input); fclose(output); return 1; } // 读取音频样本,调整音量后写入输出文件 while (fread(sample, sizeof(SAMPLE), 1, input) == 1) { // 调整音量,添加边界检查避免样本值溢出int16_t范围 *sample = (SAMPLE)(*sample * factor); if (*sample > 32767) *sample = 32767; if (*sample < -32768) *sample = -32768; fwrite(sample, sizeof(SAMPLE), 1, output); } // 释放内存并关闭文件 free(sample); fclose(input); fclose(output); return 0; }
额外注意事项
- 若你的WAV文件是其他位深(如24位),需对应修改样本类型(如
int32_t); - 音量调整时的边界检查可避免音频出现破音(Clipping)问题。
内容的提问来源于stack exchange,提问作者theonerishi
相关产品推荐
相关产品推荐

