当前位置: 首页 > article >正文

【C语言】如何插入并播放音频文件

在 C 语言中处理音频文件可以是一个有趣且挑战性的任务,尤其是在嵌入式开发或多媒体程序开发中。尽管 C 语言本身并不直接支持音频处理,但可以通过集成第三方库来处理音频文件的解码和播放。本篇博客将介绍如何在 C 语言中插入并播放音频文件,具体使用 SDL2 库来播放音频,同时用 minimp3 库解码 MP3 文件。

前提要求

  • C 语言基础:你需要了解基本的 C 语言语法和文件操作。
  • SDL2:SDL2 是一个跨平台的多媒体库,可以用来处理音频、视频和图形渲染。在这里,我们将用它来播放音频。
  • minimp3:minimp3 是一个小巧的 MP3 解码库,它可以将 MP3 文件解码为 PCM 数据,供其他音频播放系统使用。

环境设置

在使用 SDL2 和 minimp3 前,你需要确保它们已安装在系统中。以下是在不同平台上安装 SDL2 和 minimp3 的方法:

1. 安装 SDL2

Linux

在 Linux 系统中,可以通过包管理工具安装 SDL2:

sudo apt-get install libsdl2-dev
Windows

在 Windows 上,你需要手动下载 SDL2 的开发包。可以从 SDL 官网 下载。

  1. 解压下载的文件,并将 include 和 lib 文件夹添加到你的项目中。
  2. 在编译时,确保链接 SDL2.lib
macOS

在 macOS 上,可以使用 Homebrew 安装 SDL2:

brew install sdl2

2. 安装 minimp3

minimp3 是一个轻量级的 MP3 解码库,你可以从 minimp3 GitHub 下载源代码。

minimp3.cminimp3.h 文件添加到你的项目中。这个库不依赖其他外部库,非常适合用于小型项目。

步骤详解:用 C 语言播放音频

1. 配置环境

假设你已经安装了 SDL2 和 minimp3,并将它们正确地集成到你的开发环境中。

接下来,我们将编写一个 C 语言程序,利用 SDL2 来播放音频文件,并使用 minimp3 来解码 MP3 文件。

2. 示例代码

#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include "minimp3.h"
#include "minimp3_ex.h"

#define SAMPLE_RATE 44100
#define CHANNELS 2
#define BITS_PER_SAMPLE 16
#define BUFFER_SIZE 8192

// 播放音频
void playMP3(const char *filename) {
    // 打开 MP3 文件
    FILE *mp3File = fopen(filename, "rb");
    if (!mp3File) {
        printf("无法打开文件 %s\n", filename);
        return;
    }

    // 初始化 MP3 解码器
    mp3_decoder_t decoder;
    mp3_info_t mp3info;
    minimp3_decode_init(&decoder);
    minimp3_info(&decoder, &mp3info);

    Uint8 audioBuffer[BUFFER_SIZE];
    mp3_frame_info_t frameInfo;

    // 初始化 SDL2 音频系统
    if (SDL_Init(SDL_INIT_AUDIO) < 0) {
        printf("SDL_Init failed: %s\n", SDL_GetError());
        fclose(mp3File);
        return;
    }

    // 设置 SDL 音频设备参数
    SDL_AudioSpec audioSpec;
    audioSpec.freq = SAMPLE_RATE;
    audioSpec.format = AUDIO_S16SYS;
    audioSpec.channels = CHANNELS;
    audioSpec.samples = 4096;
    audioSpec.callback = NULL;

    // 打开音频设备
    if (SDL_OpenAudio(&audioSpec, NULL) < 0) {
        printf("SDL_OpenAudio failed: %s\n", SDL_GetError());
        fclose(mp3File);
        SDL_Quit();
        return;
    }

    // 启动音频播放
    SDL_PauseAudio(0);

    // 读取并解码 MP3 数据
    while (1) {
        // 从 MP3 文件中读取数据
        int bytesRead = fread(audioBuffer, 1, sizeof(audioBuffer), mp3File);
        if (bytesRead == 0) {
            break; // 文件读取完毕
        }

        // 解码 MP3 数据并获取 PCM 数据
        int decoded = minimp3_decode_frame(&decoder, audioBuffer, bytesRead, audioBuffer, sizeof(audioBuffer), &frameInfo);
        if (decoded > 0) {
            // 将 PCM 数据添加到 SDL 播放队列
            SDL_QueueAudio(1, audioBuffer, decoded);
        }
    }

    // 等待音频播放完成
    SDL_Delay(5000);

    // 清理资源
    SDL_CloseAudio();
    SDL_Quit();
    fclose(mp3File);
}

int main() {
    // 调用播放 MP3 文件的函数
    playMP3("audio.mp3");
    return 0;
}

3. 代码解释

  • 文件操作:我们使用 fopen 函数打开 MP3 文件,并在读取过程中检查是否成功。

  • 音频解码:使用 minimp3 库解码 MP3 文件。minimp3_decode_frame 会将 MP3 文件的音频数据解码为 PCM 数据,以便传递给音频播放系统。

  • SDL2 设置音频设备:我们使用 SDL2 来配置和管理音频设备。通过 SDL_OpenAudio 打开音频设备,设置音频参数(如采样率、位深度和通道数),并通过 SDL_QueueAudio 将解码后的音频数据放入播放队列。

  • 音频播放SDL_PauseAudio(0) 启动音频播放,SDL_Delay 用于确保播放完成。

4. 编译代码

在 Linux 系统上,你可以使用以下命令来编译代码:

gcc -o mp3_player mp3_player.c -lSDL2 -lm

如果你在 Windows 或 macOS 上,确保链接了 SDL2 库。

5. 运行程序

编译成功后,你可以运行程序并提供一个 MP3 文件作为参数,程序将会播放该文件。

./mp3_player

6. 输出结果

如果一切设置正确,程序将会播放指定的 MP3 文件。你可以在终端或命令行窗口中看到播放状态的输出信息,并听到音频文件播放的声音。

总结

在这篇博客中,我们通过将 minimp3SDL2 库结合使用,成功地在 C 语言中实现了音频的插入和播放。通过这种方法,你可以在 C 程序中方便地集成音频播放功能,并且能够支持 MP3 文件的解码和播放。

这只是一个基础的音频播放示例,你还可以根据实际需求,扩展更多的功能,比如支持不同音频格式(例如 WAV、FLAC 等)、实现音量控制、支持多通道音频等。


http://www.kler.cn/a/464106.html

相关文章:

  • Unity3D仿星露谷物语开发16之角色拾取道具
  • UE5 Debug的一些心得
  • 每日一学——监控工具(Grafana)
  • golang 编程规范 - 项目目录结构
  • Pytorch使用手册-DCGAN 指南(专题十四)
  • 慧集通iPaaS集成平台低代码培训-基础篇
  • 高级架构五 设计模式
  • python中序列化之json文件的使用
  • Redis 发布订阅(Pub/Sub)机制详解
  • Switch组件的用法
  • 《我在技术交流群算命》(二):QGraphicsItem怎么写自定义信号啊(QObject多继承顺序问题)
  • 深入解析 JVM vs JDK vs JRE:三者区别与联系详解
  • python opencv的orb特征检测(Oriented FAST and Rotated BRIEF)
  • LevelDB 源码阅读:利用 Clang 的静态线程安全分析
  • 彻底解决 Selenium ChromeDriver 不匹配问题:Selenium ChromeDriver 最新版本下载安装教程
  • 概率论与数理统计
  • 需求上线,为什么要刷缓存?
  • LeetCode算法题——长度最小的子数组
  • 大模型的prompt的应用一
  • 数据挖掘——集成学习
  • Java-写一个计数器
  • mac下载Homebrew安装nvm
  • 微服务间通信的端口开放性探究:从单机到多机的转变
  • <<零基础学C++,类和对象(上)--类的定义,访问限定符,类域,实例化>>
  • 第11章 汇编语言--- 内存模型概述
  • 文件本地和OSS上传