SDL2 播放音频数据(PCM)

1.简介

这里以常用的视频原始数据PCM数据为例,展示音频的播放。

SDL播放音频的流程如下:

  • 初始化音频子系统:SDL_Init()。
  • 设置音频参数:SDL_AudioSpec。
  • 设置回调函数:SDL_AudioCallback。
  • 打开音频设备:SDL_OpenAudio()。
  • 打开pcm文件,读取数据。
  • 开始播放:SDL_PauseAudio()。

2.使用的数据结构以及方法介绍

SDL_AudioSpec:

typedef struct SDL_AudioSpec {int freq; // 音频采样率SDL_AudioFormat format; // 音频数据格式Uint8 channels; // 声道数: 1 单声道, 2 立体声Uint8 silence; // 设置静音的值,因为声音采样是有符号的,所以0当然就是这个值Uint16 samples; // 音频缓冲区中的采样个数,要求必须是2的n次,这个决定了回调len的长度,len=samples*chn*位宽(单位是字节)Uint16 padding; // 考虑到兼容性的一个参数Uint32 size; // 音频缓冲区的大小,以字节为单位SDL_AudioCallback callback; // 填充音频缓冲区的回调函数void *userdata; // 用户自定义的数据
} SDL_AudioSpec;

SDL_AudioCallback回调:

  • userdata:SDL_AudioSpec结构中的用户自定义数据,一般情况下可以不用。
  • stream:该指针指向需要填充的音频缓冲区。
  • len:音频缓冲区的大小(以字节为单位)。
typedef void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 * stream,int len);

播放音频数据:

// 当pause_on设置为0的时候即可开始播放音频数据。设置为1的时候,将会播放静音的值。
void SDLCALL SDL_PauseAudio(int pause_on)

混音函数:

  • dst:目标数据,这里传入音频缓冲区指针 stream;
  • src:音频数据,这里传入我们读出的 PCM 数据;
  • len:音频数据长度,这里传入音频缓冲区大小 len;
  • volume:音量,范围 0~128,这里我们传入 SDL_MIX_MAXVOLUME,注意此参数并不会修改硬件音量;
extern DECLSPEC void SDLCALL SDL_MixAudio(Uint8 * dst, const Uint8 * src,Uint32 len, int volume);

3.代码示例

#include <stdio.h>
#include <SDL.h>static  Uint8  *audio_chunk;
static  Uint32  audio_len;
static  Uint8  *audio_pos;void  fill_audio(void *udata, Uint8 *stream, int len)
{//SDL 2.0SDL_memset(stream, 0, len);if (audio_len == 0)		/*  Only  play  if  we  have  data  left  */return;len = (len > audio_len ? audio_len : len);	/*  Mix  as  much  data  as  possible  */SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);audio_pos += len;audio_len -= len;
}#undef main
int main(int argc, char* argv[])
{//Initif (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER)){printf("Could not initialize SDL - %s\n", SDL_GetError());return -1;}//SDL_AudioSpecSDL_AudioSpec wanted_spec;wanted_spec.freq = 44100;wanted_spec.format = AUDIO_S16SYS;wanted_spec.channels = 2;wanted_spec.silence = 0;wanted_spec.samples = 1024;wanted_spec.callback = fill_audio;//打开音频设备if (SDL_OpenAudio(&wanted_spec, NULL) < 0){printf("can't open audio.\n");return -1;}FILE *fp = fopen("./test.pcm", "rb+");if (fp == NULL){printf("cannot open this file\n");return -1;}//For YUV420Pint pcm_buffer_size = 4096;char *pcm_buffer = (char *)malloc(pcm_buffer_size);int data_count = 0;while (1){if (fread(pcm_buffer, 1, pcm_buffer_size, fp) != pcm_buffer_size){// Loopfseek(fp, 0, SEEK_SET);fread(pcm_buffer, 1, pcm_buffer_size, fp);data_count = 0;}printf("Now Playing %10d Bytes data.\n", data_count);data_count += pcm_buffer_size;//Set audio buffer (PCM data)audio_chunk = (Uint8 *)pcm_buffer;//Audio buffer lengthaudio_len = pcm_buffer_size;audio_pos = audio_chunk;//PlaySDL_PauseAudio(0);while (audio_len > 0)//Wait until finishSDL_Delay(1);}fclose(fp);SDL_CloseAudio();SDL_Quit();return 0;
}

4.相关推荐

[总结]FFMPEG视音频编解码零基础学习方法_零基础ffmpeg 雷霄骅-CSDN博客

FFmpeg 音频解码(秒懂)-CSDN博客

SDL2 播放视频文件(MP4)-CSDN博客

SDL2 播放音频(MP4)-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/149431.shtml

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

相关文章

ML-Net:通过深度学习彻底改变多标签分类

一、说明 多标签分类是一项具有挑战性的机器学习任务&#xff0c;其中输入可以同时属于多个类。传统的多标签分类方法通常依赖于将问题转化为一系列二元分类任务或使用集成方法。然而&#xff0c;深度学习的出现开创了多标签分类的新时代&#xff0c;ML-Net 等模型突破了该领域…

02-1解析xpath

我是在edge浏览器中安装的xpath&#xff0c;需要安装的朋友可以参考下面这篇博客最新版edge浏览器中安装xpath插件 一、xpathd的使用 安装lxml pip install lxml ‐i https://pypi.douban.com/simple导入lxml.etree from lxml import etreeetree.parse() 解析本地文件 htm…

SpringBoot和Spring的区别是什么?

目录 Spring SpringBoot 区别&#xff1a; 1、自动配置: 2、内嵌Web服务器: 3、约定大于配置: Spring Spring是一个非常强大的企业级Java开发框架&#xff0c;Spring 框架为开发 Java 应用程序提供了全面的基础架构支持。它包含一些很好的功能&#xff0c;如依赖注入和开…

vscode的git 工具使用

vscode的git 工具使用 目录概述需求&#xff1a; 设计思路实现思路分析1.git 工具的使用2.提交代码3.查看历史提交代码 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a be…

使用webhook发送企业微信消息

文章目录 使用webhook发送企业微信消息企业微信群机器人思路实现总结 使用webhook发送企业微信消息 企业微信群机器人思路实现 1&#xff0c;在企业微信中新建一个群 2&#xff0c;在设置里面添加机器人 3&#xff0c;拿到webhook地址 在终端某个群组添加机器人之后&#xf…

Servlet API 详解

文章目录 前言什么是ServletHttpServletHttpServletRequest1. form表单构造POST请求2. JSON形式表示body部分 HttpServletResponse 前言 前面为大家介绍了如何使用 servlet 写一个简单的网站&#xff0c;前面只是大概了解了如何使用简单的 servlet&#xff0c;而平时网站的逻辑…

Hive Lateral View explode列为空时导致数据异常丢失

一、问题描述 日常工作中我们经常会遇到一些非结构化数据&#xff0c;因此常常会将Lateral View 结合explode使用&#xff0c;达到将非结构化数据转化成结构化数据的目的&#xff0c;但是该方法对应explode的内容是有非null限制的&#xff0c;否则就有可能造成数据缺失。 SE…

一体多面:哪有什么DO、BO、DTO,只不过是司空见惯的日常

欢迎大家关注公众号「JAVA前线」查看更多精彩分享文章&#xff0c;主要包括源码分析、实际应用、架构思维、职场分享、产品思考等等&#xff0c;同时欢迎大家加我微信「java_front」一起交流学习 1 分层疑问 无论DDD还是MVC模式构建项目&#xff0c;势必涉及到工程结构的分层&…

typora整理markdown笔记

效果 符号 快捷键 斜体 * * ctrlB(代表同时按) 加粗 ** ** ctrlI 竖线 > 超链接 清除样式 ctrl\ 图片 ![图片描述][图片绝对路径/相对路径] 如何在Typora中插入图像&#xff1f; ➊ 使用Markdown语法 &#xff08;不推荐&#xff0c;太慢&#xff09; ➋ 直接拷贝图…

Theory behind GAN

假如要生成一些人脸图&#xff0c;实际上就是想要找到一个分布&#xff0c;从这个分布内sample出来的图片像是人脸&#xff0c;分布之外生成的就不像人脸。而GAN要做的就是找到这个distribution。 在GAN之前用的是Maximum Likelihood Estimation。 Maximum Likelihood Estimat…

同创永益联合红帽打造一站式数字韧性解决方案

随着AI技术的快速兴起&#xff0c;IT技术已成为推动业务持续增长的重要驱动力&#xff0c;这要求企业不断尝试新事物&#xff0c;改变固有流程&#xff0c;加强IT技术与业务的合作&#xff0c;同时提升数字韧性能力&#xff0c;以实现业务目标。10月26日&#xff0c;红帽2023中…

Bert学习笔记(简单入门版)

目 录 一、基础架构 二、输入部分 三、预训练&#xff1a;MLMNSP 3.1 MLM&#xff1a;掩码语言模型 3.1.1 mask模型缺点 3.1.2 mask的概率问题 3.1.3 mask代码实践 3.2 NSP 四、如何微调Bert 五、如何提升BERT下游任务表现 5.1 一般做法 5.2 如何在相同领域数据中进…

学习UI第一天

在工作闲暇之余&#xff0c;自己画的原型图&#xff0c;再次做一次记录&#xff0c;哈哈哈 萌宠领养UI设计原型图 https://modao.cc/proto/lq2KqIVBs48xwylNZlA7OP/sharing?view_moderead_only #萌宠领养-分享 可以点击此链接&#xff0c;进行查看O(∩_∩)O哈哈~

基于uni-app的汽车租赁app的设计与实现

1.项目背景及意义 项目背景&#xff1a; 随着人们生活水平的提高&#xff0c;汽车租赁服务在城市中变得越来越普及。传统的租车方式存在一些问题&#xff0c;比如租车流程繁琐、费用不透明、选择有限等。因此&#xff0c;开发一款基于uni-app的汽车租赁app成为了满足用户需求…

基于RFID的自动化仓储设备研发项目可行性研究报告

一、项目概况 基于RFID的自动化仓储设备研发项目&#xff0c;是深圳市飞鸟国际供应链股份有限公司在公司有色金属供应链一站式服务的基础上&#xff0c;针对有色金属供应链的仓储环节进行的研发。 多年来&#xff0c;公司一直坚持以“科技金融”为核心的未来发展战略&#xf…

二进制部署k8s集群-过程中的问题总结(接上篇的部署)

1、kube-apiserver部署过程中的问题 kube-apiserver.conf配置文件更改 2、calico的下载地址 curl https://docs.projectcalico.org/v3.20/manifests/calico.yaml -O 这里如果kubernetes的节点服务器为多网卡配置会产生报错 修改calino.yaml配置文件 解决方法&#xff1a; 调…

连接服务器上mysql数据库

1. 首先在服务器的安全组上设置开放3306端口&#xff08;默认是这个&#xff0c;有自定义可以酌情更改&#xff09; 2. 更改服务器上的数据库配置文件vi /etc/mysql/my.cnf 增加下面bind- address配置 [mysqld] bind-address0.0.0.0 3. 授予本地IP地址的主机连接权限 - 创建…

论文阅读——DiffusionDet

在目标检测上使用扩散模型 前向过程&#xff1a;真实框-->随机框 后向过程&#xff1a;随机框-->真实框 前向过程&#xff1a; 一般一张图片真实框的数目不同&#xff0c;填补到同一的N个框&#xff0c;填补方法可以是重复真实框&#xff0c;填补和图片大小一样的框&a…

Redis 学习

Redis 集群共3种集群模式&#xff1a; 1. 主从模式 &#xff08;主写从读&#xff09;&#xff0c;写请求分配到主库&#xff0c;完后数据同步到从库&#xff0c;从库主要负责读请求 同步过程&#xff1a; 从库启动向主库发送同步请求&#xff0c;数据传输的形式是RDB文件&am…

C++算法入门练习——树的带权路径长度

现有一棵n个结点的树&#xff08;结点编号为从0到n-1&#xff0c;根结点为0号结点&#xff09;&#xff0c;每个结点有各自的权值w。 结点的路径长度是指&#xff0c;从根结点到该结点的边数&#xff1b;结点的带权路径长度是指&#xff0c;结点权值乘以结点的路径长度&#x…