[SimplePlayer] 5. 向音频设备输出音频
两种SDL音频输出方式
我们这里采用SDL来进行音频输出。SDL提供两种音频输出的方式:
- 如果在SDL_OpenAudio时不指定callback,那么可以调用SDL_QueueAudio主动地向音频输出设备输送音频。这种方式的实现中,SDL维护一个音频队列,并从该队列中提取音频数据输出到音频设备,用户只需要源源不断地向队列添加音频即可。如果用户无法提供所需的音频,那么音频设备会输出静音。
- 如果在SDL_OpenAudio时指定了callback,那么就是通过该callback函数向音频输出设备输送音频。这种方式的实现中,SDL会维护一个固定大小的缓冲区,并创建一个轮询调用callback函数的线程(SDL_RunAudio),该实现要求callback函数每次向该缓冲区输送固定长度的音频数据,然后将该缓冲区的音频数据输出到音频设备。如果用户无法提供所需数据,则应该通过callback提供静音数据(填充0)。
我们这里采用的是SDL传统的音频输出方式,即指定callback函数。
初始化
首先需要初始化SDL的音频子系统
SDL_Init(SDL_INIT_AUDIO);
设置音频输出的采样率、样本格式、声道、一帧的有多少个样本(每次输出一帧)、以及回调函数。
SDL_AudioSpec wanted, obtained;
memset(&wanted, 0, sizeof(wanted));
wanted.freq = DEF_SAMPLERATE;
wanted.format = AUDIO_S16SYS;
wanted.channels = DEF_CHANNELS;
wanted.samples = DEF_SAMPLES;
wanted.silence = 0;
wanted.callback = SimpleCallback;
if(0>SDL_OpenAudio(&wanted, &obtained)){
fprintf(stderr, "SDL Open Audio failed, reason:%s\n", SDL_GetError());
return -1;
}
fprintf(stdout, "wanted freq:%d, format:%d, channels:%d, samples:%d\n", wanted.freq, wanted.format, wanted.channels, wanted.samples);
fprintf(stdout, "obtained freq:%d, format:%d, channels:%d, samples:%d\n", obtained.freq, obtained.format, obtained.channels, obtained.samples);
不过由于系统(声卡)的限制,系统所能接受的参数不一定就是我们设置的参数。
音频输出
如前面所述,我们需要在callback函数中填充一块固定大小的buffer,该buffer的大小为SDL_OpenAudio时设定的音频帧大小,buffer中的音频数据会被输出到音频输出设备。

void SimpleCallback(void* userdata, Uint8 *stream, int queryLen){
unsigned char *buf, *itr;
int readsize = 0, len, bufsize, lengthOfRead;
len = queryLen;
buf = (unsigned char *)malloc(len);
memset(buf, 0, len);
itr = buf;
while(len > 0){
readsize = fread(itr, 1, len, pFile);
if(!readsize)
len = 0;
len = len - readsize;
itr = itr + readsize;
}
memcpy(stream, buf, queryLen);
free(buf);
}
[SimplePlayer] 5. 向音频设备输出音频的更多相关文章
- Keil MDK STM32系列(八) STM32F4基于HAL的PWM和定时器输出音频
Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...
- stm32 DAC输出音频
#define DAC_DHR8R1_Address 0x40007410 // Init Structure definition DAC_InitTypeDef DAC_InitStructure ...
- mac obs直播软件 无法输出音频解决办法
搜索大量的网页,确没有一个实用的设置教程,也正是speechless. 直接做个教程,方便大家的使用 1.安装 boom 2 到app store 上搜索boom 我安装的是正版的,需要128元. 你 ...
- Linux下音频编程-输出音频文件
程序实现了在Linux下播放Ok.wav的功能.程序首先调用fstat函数获得文件相关信息(主要是文件大小信息).通过malloc函数分配指定的内存空间,并将online.wav读入内存:然后,打开声 ...
- [SimplePlayer] 实现一个简单的播放器
简单的播放器需要实现一个最基本的功能:播放视频文件. 实现这个功能需要包含以下几个步骤: 从视频文件中提取视频图像 在屏幕上显示视频图像 视频帧的同步,也就是保证视频图像在合适的时间在屏幕上显示 从视 ...
- FFmpeg学习3:播放音频
参考dranger tutorial,本文将介绍如何使用FFmpeg解码音频数据,并使用SDL将解码后的数据输出. 本文主要包含以下几方面的内容: 关于播放音频的需要的一些基础知识介绍 使用SDL2播 ...
- DirectShow音频采集声音不连续问题分析与解决办法经验总结
最近广州大雨不断,并且多数无前兆,突然就来场大雨,给同学们降降温,说来本也是好事,但有时候下的真不是时候,最近这段时间都是即将下班了,大雨就来了,昨晚快下班前又出现了大雨,北方人总爱忘带雨伞,这不就被 ...
- Android音频系统之AudioFlinger(二)
1.1.1 音频设备的管理 虽然AudioFlinger实体已经成功创建并初始化,但到目前为止它还是一块静态的内存空间,没有涉及到具体的工作. 从职能分布上来讲,AudioPolicyService是 ...
- Android音频系统之AudioPolicyService
地址:http://blog.csdn.net/edmond999/article/details/18599327 1.1 AudioPolicy Service 在AudioFlinger小节,我 ...
随机推荐
- 跨域iframe如何实现高度自适应?
经常有项目会要求实现iframe高度自适应,如果是同域的还好说,如果是跨域的,父页面没有办法操作子页面,想要正确获取子页面高度的话,可以采用以下办法: 方法一:使用HTML5 postMessage ...
- Arcgis瓦片--数据获取
Arcgis的二维地图瓦片有两种获取方式 1.在Arcmap中对配置好的地图进行切图,生成对应瓦片 2.使用第三方的地图下载器,直接下载,导出成arcgis瓦片格式即可使用. 备注:这里主要介绍第二种 ...
- CentOS6.9升级autoconf版本,解决”Autoconf version 2.64 or higher is required“错误
安装软件时提示说需要Autoconf 2.64或更高的版本: # autoconf configure.ac:: error: Autoconf version 2.64 or higher is r ...
- Vue CLI 3.0脚手架如何在本地配置mock数据
前后端分离的开发模式已经是目前前端的主流模式,至于为什么会前后端分离的开发我们就不做过多的阐述,既然是前后端分离的模式开发肯定是离不开前端的数据模拟阶段. 我们在开发的过程中,由于后台接口的没有完成或 ...
- 使用cmd查看电脑连接过的wifi密码(二)
上次写了一个查看wifi的bat文件(https://www.cnblogs.com/feiquan/p/9823402.html),发现有个问题就没法保存到记事本,而且还要处理不同的系统语言,这次重 ...
- 解决vs启动出现“cannot find one or more components .Please reinstall the application”
参考下文: https://blog.csdn.net/novice_growth/article/details/71627395
- MFC打印
映射模式是MFC甚至SDK界面编程第1个难点.打印则是第2个难点.这2个都是历史遗留的设计缺陷.这些缺陷还不至于到bug程度,但却很难用,不易理解. MFC提供2个类来实现打印(预览),具体有CPri ...
- man -f/-k [keyword]在fedora 29 中报错nothing appropriate
我们在使用 man 手册的时候,可以使用man -f [keyword]去查询keyword的在线文档,但是这时候会报错:(图来源自网络) 这是因为我们还没有建立 man 手册的索引缓存: 我们可以使 ...
- Extjs 解决grid分页bug问题
//从后端获取数据加载到grid中var mainStore = new HeJsonStore({ url:'xxx', autoLoad:true, pageSize:20 }) //此方法最好放 ...
- mysql的分组
以下是根据老师的视屏写的总结,要自己实际操作以下. 首先老师一顿操作猛如虎,得到以下的表. 然后进行以下的操作: 发现筛选时报错了,老师的解释实说,分组是因为mysql不知道选择谁而出现报错,因为pa ...