You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调整音频文件音量的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 01:30:56