两种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. 向音频设备输出音频的更多相关文章

  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. Java中的会话Cookie&&Session

    会话技术 会话: 一次会话中包含多次请求和响应. 一次会话:浏览器第一次给服务器资源发送请,会话建立,直到有一方断开为止 功能:在一次会话的范围内的多次请求之间共享数据 方式: 客户端会话技术:coo ...

  2. 从.Net到Java学习第九篇——SpringBoot下Thymeleaf

    从.Net到Java学习系列目录 Thymeleaf概述 Thymeleaf 是一个流行的模板引擎,该模板引擎采用java语言开发.模板引擎是一个技术名称,是跨领域平台的概念,在java语言体系下有模 ...

  3. 一个MySQL视图的优化过程

    1.需要优化的sql 最近做一个基于.net mvc和MySQL的仓储系统的优化工作,遇到了一个执行特别慢的SQL语句,经过一番折腾,终于搞定啦,分享一下过程.问题就是下面这个家伙: create o ...

  4. 怎么打开iPhone的开发者模式

    1.需要连接Xcode 2.打开一个app就有了

  5. Linux查杀stopped进程

      在Linux系统下面,top命令可以查看查看stopped进程.但是不能查看stopped进程的详细信息.那么如何查看stopped 进程,并且杀掉这些stopped进程呢? ps -e j | ...

  6. 【Eclipse】springMVC介绍与配置

    SpringMCV介绍: Spring MVC是一种基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动的,也就是使用 ...

  7. Python面试笔记三

    1. 类继承 有如下的一段代码: python对象 如何调用类A的show方法了,方法如下: python对象 __class__方法指向了类对象,只用给他赋值类型A,然后调用方法show,但是用完了 ...

  8. LeetCode算法题-Base 7(Java实现)

    这是悦乐书的第247次更新,第260篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第114题(顺位题号是504).给定一个整数,返回其基数为7的字符串表示.例如: 输入: ...

  9. Docker: Harbor一些小知识

    镜像文件上传到私有仓库harbor后,镜像的物理存储位置在哪里? 这些信息记录在docker-compose.yml里,通过观察发现 镜像存储在了宿主机的 volumes: - /data/regis ...

  10. Linux Collection:网络配置

    PAS 缺少ifconfig 安装相应软件[不推荐],尽量使用 ip 命令 sudo apt install gnome-nettool 补充,显示IP地址: ip show address PAS ...