【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.rhkb.cn/news/500840.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

黑马Java面试教程_P10_设计模式

系列博客目录 文章目录 系列博客目录前言1. 工厂方法模式1.1 概述1.2 简单工厂模式1.2.1 结构1.2.2 实现1.2.3 优缺点 1.3 工厂方法模式1.3.1 概念1.3.2 结构1.3.3 实现1.3.4 优缺点 1.4 抽象工厂模式1.4.1 概念1.4.2 结构1.4.3 实现1.4.4 优缺点1.4.5 使用场景 总结&#xff0…

开源架构的容器化部署优化版

上三篇文章推荐&#xff1a; 开源架构的微服务架构实践优化版&#xff08;New&#xff09; 开源架构中的数据库选择优化版&#xff08;New&#xff09; 开源架构学习指南&#xff1a;文档与资源的智慧锦囊&#xff08;New&#xff09; 我管理的社区推荐&#xff1a;【青云交社区…

SpringCloudAlibaba实战入门之Sentinel服务降级和服务熔断(十五)

一、Sentinel概述 1、Sentinel是什么 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 一句话概括:sentinel即Hystrix的替代品,官网: https://sentinelguard.io/zh…

【每日学点鸿蒙知识】导入cardEmulation、自定义装饰器、CallState状态码顺序、kv配置、签名文件配置

1、HarmonyOS 无法导入cardEmulation&#xff1f; 在工程entry mudule里的index.ets文件里导入cardEmulation失败 可以按照下面方式添加SystemCapability&#xff1b;在src/main/syscap.json(此文件需要手动创建&#xff09;中添加如下内容 {"devices": {"gen…

Datawhale AI冬令营(第二期)动手学AI Agent--Task3:学Agent工作流搭建,创作进阶Agent

目录 一、工作流&#xff1a;制作复杂Agent的福音&#xff01; 二、支付宝百宝箱中工作流介绍 三、设计工作流 3.1 准备功能模块 3.2组合工作流 3.3 模块测试需要注意什么 3.4迭代优化 四、高中学习小助手工作流设计 4.1 选题调研 4.2 功能模块设计 4.3 组合完整工作…

Postman[8] 断言

1.常见的断言类型 status code: code is 200 //检查返回的状态码是否为200 Response body&#xff1a; contain string //检查响应中包含指定字符串包含指定的值 response body:json value check/ /检查响应中其中json的值 Response body&#xff1a; is equal to string …

python openyxl 用法 教程

Python自动化办公&#xff1a;openpyxl教程(基础)-CSDN博客 https://zhuanlan.zhihu.com/p/342422919 https://openpyxl-chinese-docs.readthedocs.io/zh-cn/latest/tutorial.html 列标题&#xff0c;是这一列 对应的单元格的格式&#xff0c;默认是常规&#xff0c;设置之后…

深入解析 Wireshark 的 TLS 设置:应用场景与实操技巧

简述 在网络数据分析中&#xff0c;传输层安全&#xff08;TLS&#xff09;协议的流量解密和分析是一项重要的技能。Wireshark 提供了专门的设置选项&#xff0c;帮助用户处理 TLS 流量&#xff0c;例如解密会话、重组分片等。本文将详细解析上图所示的 Wireshark TLS 设置功能…

每天五分钟机器学习:凸集

本文重点 在SVM中,目标函数是一个凸函数,约束集合是一个凸集。因此,SVM问题可以转化为一个凸规划问题来求解。这使得SVM在实际应用中具有较高的计算效率和准确性。 凸集的定义 凸集是指一个集合中的任意两点之间的线段都完全包含在这个集合中。换句话说,给定集合C中的两…

stm32 智能语音电梯系统

做了个stm32智能语音控制的电梯模型&#xff0c;总结一下功能&#xff0c;源码用ST的HAL库写的&#xff0c;整体流程分明。 实物图 这个是整个板子的图片&#xff0c;逻辑其实并不复杂&#xff0c;只是功能比较多&#xff0c;在我看来都是一些冗余的功能&#xff0c;但也可能是…

AI 助力游戏开发中的常用算法实现

在当今的游戏开发领域&#xff0c;人工智能&#xff08;AI&#xff09;技术的应用已经成为推动行业发展的关键力量。AI不仅能够提升游戏的智能化水平&#xff0c;还能够增强玩家的沉浸感和游戏体验。随着技术的进步&#xff0c;AI在游戏设计、开发和测试中的应用越来越广泛&…

计算机的错误计算(一百九十九)

摘要 用大模型判断下面四个函数 有何关系&#xff1f;并计算它们在 x0.00024时的值&#xff0c;结果保留10位有效数字。两个大模型均认为它们是等价的。实际上&#xff0c;还有点瑕疵。关于计算函数值&#xff0c;大模型一只是纸上谈兵&#xff0c;没计算&#xff1b;大模型二…

HTML——57. type和name属性

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>type和name属性</title></head><body><!--1.input元素是最常用的表单控件--><!--2.input元素不仅可以在form标签内使用也可以在form标签外使用-…

基于SpringBoot和OAuth2,实现通过Github授权登录应用

基于SpringBoot和OAuth2&#xff0c;实现通过Github授权登录应用 文章目录 基于SpringBoot和OAuth2&#xff0c;实现通过Github授权登录应用0. 引言1. 创建Github应用2. 创建SpringBoot测试项目2.1 初始化项目2.2 设置配置文件信息2.3 创建Controller层2.4 创建Html页面 3. 启动…

LVGL 移植到 Arduino IDE(适用SP32 Arduino RP系列)

1.因为我们需要移植相关LVGL配置文件&#xff0c;否则IDE会报错&#xff0c;因此 先找到LVGL官方的GITHUB处&#xff0c;如下图所示&#xff1a; 2.值得注意的是&#xff0c;你需要知你的 Arduino IDE 用的是哪个版本的LVGL&#xff0c;要与我们在GITHUB处的版本号一致&#xf…

Ubuntu 24.04 LTS 解决网络连接问题

1. 问题描述 现象&#xff1a;ens33 网络接口无法获取 IPv4 地址&#xff0c;导致网络不可用。初步排查&#xff1a; 运行 ip a&#xff0c;发现 ens33 接口没有分配 IPv4 地址。运行 ping www.baidu.com&#xff0c;提示“网络不可达”。查看 NetworkManager 日志&#xff0c…

C语言----指针数组

目录 1. 定义&#xff1a; 2. 格式&#xff1a; 应用示例 1) 用于存放普通变量的地址 2) 用于存放二维数组的每一行第一个元素的地址&#xff08;列地址&#xff09; 3) 用于存放字符串 4) 命令行参数 补充&#xff1a;开辟堆区空间&#xff08;动态空间开辟&#xff0…

单区域OSPF配置实验

1、绘制拓扑图 2、配置ip地址 R0 Router(config)#interface FastEthernet0/0 Router(config-if)#ip address 192.168.1.1 255.255.255.0 Router(config-if)#no shutdown Router(config-if)#exit Router(config)#interface FastEthernet0/1 Router(config-if)#ip address 192.16…

【玩转OCR | 基于腾讯云智能结构化OCR的技术应用实践】

目录 背景与业务挑战 腾讯云智能结构化OCR的核心优势 1. 全面的行业覆盖能力 2. 高识别精度与版式适应性 3. 个性化模板定制 4. 便捷接入与资源优化 应用实践案例&#xff1a;物流行业的单据自动化处理 1. 应用背景 2. 引入腾讯云智能结构化OCR的解决方案 1) 定制化模…

2024 年发布的 Android AI 手机都有什么功能?

大家好&#xff0c;我是拭心。 2024 年是 AI 快速发展的一年&#xff0c;这一年 AI 再获诺贝尔奖&#xff0c;微软/苹果/谷歌等巨头纷纷拥抱 AI&#xff0c;多款强大的 AI 手机进入我们的生活。 今年全球 16% 的智能手机出货量为 AI 手机&#xff0c;到 2028 年&#xff0c;这…