学会C语言解码PCM到AAC,轻松掌握音频转换技巧

2026-08-01 0 阅读

1. PCM与AAC简介

1.1 PCM

PCM(Pulse-Code Modulation,脉冲编码调制)是最基本的数字音频格式之一。它将模拟音频信号转换为数字信号,通过采样、量化等步骤实现音频的数字化。PCM格式的音频保留了原始音频的采样频率、采样大小和通道数,因此在音频处理和回放时能够保持较高的音质。

1.2 AAC

AAC(Advanced Audio Coding,高级音频编码)是一种高效的音频压缩格式,由国际电信联盟(ITU)制定。相比于PCM格式,AAC在相同的音质下,能够以更低的比特率传输音频数据,从而减小文件大小,提高传输效率。

2. C语言解码PCM到AAC

2.1 环境准备

在开始解码PCM到AAC之前,我们需要准备以下环境:

  • C语言编译器(如GCC)
  • 音频处理库(如libswresample、libavcodec)

2.2 代码实现

以下是一个简单的C语言代码示例,用于解码PCM到AAC:

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswresample/swresample.h>

int main(int argc, char **argv) {
    AVFormatContext *format_ctx = NULL;
    AVCodecContext *codec_ctx = NULL;
    SwrContext *swr_ctx = NULL;
    AVPacket packet;
    AVFrame *frame = NULL;
    FILE *input_file = fopen(argv[1], "rb");
    FILE *output_file = fopen(argv[2], "wb");

    // 打开输入文件
    if (avformat_open_input(&format_ctx, argv[1], NULL, NULL) < 0) {
        fprintf(stderr, "Failed to open input file.\n");
        return -1;
    }

    // 查找并打开解码器
    if (avformat_find_stream_info(format_ctx, NULL) < 0) {
        fprintf(stderr, "Failed to find stream information.\n");
        return -1;
    }

    // 找到音频流
    int audio_stream_index = -1;
    for (unsigned int i = 0; i < format_ctx->nb_streams; i++) {
        if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
            audio_stream_index = i;
            break;
        }
    }
    if (audio_stream_index == -1) {
        fprintf(stderr, "No audio stream found.\n");
        return -1;
    }

    // 打开解码器
    codec_ctx = avcodec_alloc_context3(NULL);
    if (codec_ctx == NULL) {
        fprintf(stderr, "Failed to allocate audio codec context.\n");
        return -1;
    }

    avcodec_parameters_to_context(codec_ctx, format_ctx->streams[audio_stream_index]->codecpar);
    if (avcodec_open2(codec_ctx, avcodec_find_decoder(codec_ctx->codec_id), NULL) < 0) {
        fprintf(stderr, "Failed to open audio decoder.\n");
        return -1;
    }

    // 配置转换器
    swr_ctx = swr_alloc_set_opts(NULL,
                                 av_get_default_channel_layout(codec_ctx->channels),
                                 AV_CH_LAYOUT_STEREO,
                                 codec_ctx->sample_rate,
                                 av_get_default_channel_layout(codec_ctx->channels),
                                 codec_ctx->sample_fmt,
                                 codec_ctx->sample_rate,
                                 0, NULL);
    if (swr_init(swr_ctx) < 0) {
        fprintf(stderr, "Failed to initialize resampler.\n");
        return -1;
    }

    // 解码并转换PCM到AAC
    while (av_read_frame(format_ctx, &packet) >= 0) {
        if (packet.stream_index == audio_stream_index) {
            frame = av_frame_alloc();
            if (avcodec_send_packet(codec_ctx, &packet) == 0) {
                while (avcodec_receive_frame(codec_ctx, frame) == 0) {
                    // 转换PCM到AAC
                    uint8_t *outbuf[2];
                    int out_samples = av_samples_alloc_array_and_samples(&outbuf[0], NULL,
                                                                          codec_ctx->channels,
                                                                          frame->nb_samples,
                                                                          codec_ctx->sample_fmt,
                                                                          0);
                    swr_convert(swr_ctx, outbuf, frame->nb_samples,
                                (const uint8_t **)frame->data, frame->nb_samples);

                    // 写入输出文件
                    fwrite(outbuf[0], 1, out_samples * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16), output_file);
                }
            }
        }
        av_packet_unref(&packet);
    }

    // 清理资源
    av_frame_free(&frame);
    swr_free(&swr_ctx);
    avcodec_close(codec_ctx);
    avcodec_free_context(&codec_ctx);
    avformat_close_input(&format_ctx);
    fclose(input_file);
    fclose(output_file);

    return 0;
}

2.3 运行代码

编译并运行上述代码,传入输入文件和输出文件的路径即可:

gcc -o pcm2aac pcm2aac.c -lavformat -lavcodec -lasound
./pcm2aac input.pcm output.aac

3. 总结

通过以上步骤,我们可以使用C语言将PCM音频解码为AAC格式。在实际应用中,您可以根据需要进行功能扩展和优化。例如,添加音频处理功能、支持不同编码器、优化性能等。希望本文能帮助您轻松掌握音频转换技巧!

分享到: