两种SDL音频输出方式

我们这里采用SDL来进行音频输出。SDL提供两种音频输出的方式:

  • 如果在SDL_OpenAudio时不指定callback,那么可以调用SDL_QueueAudio主动地向音频输出设备输送音频。这种方式的实现中,SDL维护一个音频队列,并从该队列中提取音频数据输出到音频设备,用户只需要源源不断地向队列添加音频即可。如果用户无法提供所需的音频,那么音频设备会输出静音。
  • 如果在SDL_OpenAudio时指定了callback,那么就是通过该callback函数向音频输出设备输送音频。这种方式的实现中,SDL会维护一个固定大小的缓冲区,并创建一个轮询调用callback函数的线程(SDL_RunAudio),该实现要求callback函数每次向该缓冲区输送固定长度的音频数据,然后将该缓冲区的音频数据输出到音频设备。如果用户无法提供所需数据,则应该通过callback提供静音数据(填充0)。

我们这里采用的是SDL传统的音频输出方式,即指定callback函数。

初始化

首先需要初始化SDL的音频子系统

  1. SDL_Init(SDL_INIT_AUDIO);

设置音频输出的采样率、样本格式、声道、一帧的有多少个样本(每次输出一帧)、以及回调函数。

  1. SDL_AudioSpec wanted, obtained;
  2.  
  3. memset(&wanted, 0, sizeof(wanted));
  4. wanted.freq = DEF_SAMPLERATE;
  5. wanted.format = AUDIO_S16SYS;
  6. wanted.channels = DEF_CHANNELS;
  7. wanted.samples = DEF_SAMPLES;
  8. wanted.silence = 0;
  9. wanted.callback = SimpleCallback;
  10.  
  11. if(0>SDL_OpenAudio(&wanted, &obtained)){
  12. fprintf(stderr, "SDL Open Audio failed, reason:%s\n", SDL_GetError());
  13. return -1;
  14. }
  15. fprintf(stdout, "wanted freq:%d, format:%d, channels:%d, samples:%d\n", wanted.freq, wanted.format, wanted.channels, wanted.samples);
  16. 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中的音频数据会被输出到音频输出设备。

  1. void SimpleCallback(void* userdata, Uint8 *stream, int queryLen){
  2. unsigned char *buf, *itr;
  3. int readsize = 0, len, bufsize, lengthOfRead;
  4.  
  5. len = queryLen;
  6. buf = (unsigned char *)malloc(len);
  7. memset(buf, 0, len);
  8.  
  9. itr = buf;
  10. while(len > 0){
  11. readsize = fread(itr, 1, len, pFile);
  12. if(!readsize)
  13. len = 0;
  14. len = len - readsize;
  15. itr = itr + readsize;
  16. }
  17.  
  18. memcpy(stream, buf, queryLen);
  19. free(buf);
  20. }

[SimplePlayer] 5. 向音频设备输出音频的更多相关文章

  1. Keil MDK STM32系列(八) STM32F4基于HAL的PWM和定时器输出音频

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  2. stm32 DAC输出音频

    #define DAC_DHR8R1_Address 0x40007410 // Init Structure definition DAC_InitTypeDef DAC_InitStructure ...

  3. mac obs直播软件 无法输出音频解决办法

    搜索大量的网页,确没有一个实用的设置教程,也正是speechless. 直接做个教程,方便大家的使用 1.安装 boom 2 到app store 上搜索boom 我安装的是正版的,需要128元. 你 ...

  4. Linux下音频编程-输出音频文件

    程序实现了在Linux下播放Ok.wav的功能.程序首先调用fstat函数获得文件相关信息(主要是文件大小信息).通过malloc函数分配指定的内存空间,并将online.wav读入内存:然后,打开声 ...

  5. [SimplePlayer] 实现一个简单的播放器

    简单的播放器需要实现一个最基本的功能:播放视频文件. 实现这个功能需要包含以下几个步骤: 从视频文件中提取视频图像 在屏幕上显示视频图像 视频帧的同步,也就是保证视频图像在合适的时间在屏幕上显示 从视 ...

  6. FFmpeg学习3:播放音频

    参考dranger tutorial,本文将介绍如何使用FFmpeg解码音频数据,并使用SDL将解码后的数据输出. 本文主要包含以下几方面的内容: 关于播放音频的需要的一些基础知识介绍 使用SDL2播 ...

  7. DirectShow音频采集声音不连续问题分析与解决办法经验总结

    最近广州大雨不断,并且多数无前兆,突然就来场大雨,给同学们降降温,说来本也是好事,但有时候下的真不是时候,最近这段时间都是即将下班了,大雨就来了,昨晚快下班前又出现了大雨,北方人总爱忘带雨伞,这不就被 ...

  8. Android音频系统之AudioFlinger(二)

    1.1.1 音频设备的管理 虽然AudioFlinger实体已经成功创建并初始化,但到目前为止它还是一块静态的内存空间,没有涉及到具体的工作. 从职能分布上来讲,AudioPolicyService是 ...

  9. Android音频系统之AudioPolicyService

    地址:http://blog.csdn.net/edmond999/article/details/18599327 1.1 AudioPolicy Service 在AudioFlinger小节,我 ...

随机推荐

  1. Makedown

    目录 Makedown 介绍 Markdown的语法 Makedown 介绍 Makedown的创建者是John Gruber Q:什么是markdown呢? markdown和html类似是mark ...

  2. 流程控制之 if 判断

    语法一:if 条件: 代码1 代码2 代码3 gender='female'age=18is_beautiful=True if gender == 'female' and age > 16 ...

  3. vue+vuecli+webapck2实现多页面应用

    准备工作 在本地用vue-cli新建一个项目,首先安装vue-cil,命令: npm install -g vue-cli 新建一个vue项目,创建一个基于"webpack"的项目 ...

  4. 2018 AI产业界大盘点

    2018  AI产业界大盘点 大事件盘点 “ 1.24——Facebook人工智能部门负责人Yann LeCun宣布卸任 Facebook人工智能研究部门(FAIR)的负责人Yann LeCun宣布卸 ...

  5. 在AndroidStudio上使用AddressSanitizer

    在AndroidStudio上使用AddressSanitizer AddressSanitizer是Google主导的一个开源内存问题检测工具.现在也开始支持Android平台,且受Google推荐 ...

  6. ASP.NET Core 入门教程 5、ASP.NET Core MVC 视图传值入门

    一.前言 1.本教程主要内容 ASP.NET Core MVC 视图引擎(Razor)简介 ASP.NET Core MVC 视图(Razor)ViewData使用示例 ASP.NET Core MV ...

  7. ORACLE中关于表的一些特殊查询语句

    1: 如何判断字段的值里面:那些数据包含小写字母或大小字母 判断字段NAME的值里面有小写字母的记录 方式1: SELECT NAME FROM TEST WHERE regexp_like(NAME ...

  8. c/c++ linux 进程间通信系列6,使用消息队列(message queue)

    linux 进程间通信系列6,使用消息队列(message queue) 概念:消息排队,先进先出(FIFO),消息一旦出队,就从队列里消失了. 1,创建消息队列(message queue) 2,写 ...

  9. 英语词性系列-B02-动词

    诗Poem 要求:背诵这首诗,翻译现代文,根据现代文用简单的英文翻译. 动词直观体会 动词 动词 动词 动词 动词 sell卖 buy买 beat击打 look看 dance跳舞 sing唱歌 spe ...

  10. 如何在Asp.Net中使用JQueryEasyUI

    JQueryEasyUI的基本信息: 官方下载 官方演示 官方文档 一.jQuery easyUI下载后解压的文件目录如下图: demo:JQueryEasyUI的一些示例页面,在项目使用可以将该目录 ...