sdl 打开耳机_SDL 开发实战(七): 使用 SDL 实现 PCM播放器
在上文,我们做了YUV播放器,这样我们就入门了SDL播放视频。下面我们来做一个PCM播放,即使用SDL播放PCM数据。
下面说明一下使用SDL播放PCM音频的基本流程,主要分为两大部分:初始化SDL、循环播放数据。
1. 初始化SDL
1). 初始化SDL
执行的方法为SDL_Init(SDL_INIT_AUDIO)
2). 打开音频设备
使用SDL_OpenAudio()打开音频设备。该函数需要传入一个SDL_AudioSpec的结构体。
这里SDL_OpenAudio() 函数的原型为:
int SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained);
它的参数是两个SDL_AudioSpec结构体,它们的含义:
desired:期望的参数。
obtained:实际音频设备的参数,一般情况下设置为NULL即可。
其中SDL_AudioSpec结构体如下:
typedef structSDL_AudioSpec {int freq; /**< DSP frequency -- samples per second*/SDL_AudioFormat format;/**< Audio data format*/Uint8 channels;/**< Number of channels: 1 mono, 2 stereo*/Uint8 silence;/**< Audio buffer silence value (calculated)*/Uint16 samples;/**< Audio buffer size in samples (power of 2)*/Uint16 padding;/**< Necessary for some compile environments*/Uint32 size;/**< Audio buffer size in bytes (calculated)*/SDL_AudioCallback callback;void *userdata;
} SDL_AudioSpec;
其中包含了关于音频各种参数:
freq:音频数据的采样率。常用的有48000,44100等。
format:音频数据的格式。举例几种格式:
AUDIO_U16SYS:Unsigned 16-bit samples
AUDIO_S16SYS:Signed 16-bit samples
AUDIO_S32SYS:32-bit integer samples
AUDIO_F32SYS:32-bit floating point samples
channels:声道数。例如单声道取值为1,立体声取值为2。
silence:设置静音的值。
samples:音频缓冲区中的采样个数,要求必须是2的n次方。
padding:考虑到兼容性的一个参数。
size:音频缓冲区的大小,以字节为单位。
callback:填充音频缓冲区的回调函数。
userdata:用户自定义的数据。
在这里说明一下填充音频缓冲区的回调函数的作用。当音频设备需要更多数据的时候会调用该回调函数。
回调函数的格式要求如下:
void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 * stream, int len);
回调函数的参数含义如下:
userdata:SDL_AudioSpec结构中的用户自定义数据,一般情况下可以不用。
stream:该指针指向需要填充的音频缓冲区。
len:音频缓冲区的大小(以字节为单位)。
在回调函数中可以使用SDL_MixAudio()完成混音等工作。注意:SDL2中必须首先使用SDL_memset()将stream中的数据设置为0。
2. 循环播放数据
1) 播放音频数据。
使用SDL_PauseAudio()可以播放音频数据。SDL_PauseAudio() 函数的原型如下:
void SDLCALL SDL_PauseAudio(int pause_on)
当pause_on设置为0的时候即可开始播放音频数据。设置为1的时候,将会播放静音的值。
2) 延时等待播放完成。
使用像SDL_Delay()这样的延时函数即可。
实战
//SDL.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。//#include"pch.h"#include
extern "C"{
#include"SDL.h"}/**
*
* 使用SDL2播放PCM音频采样数据。SDL实际上是对底层绘图API(Direct3D,OpenGL)的封装,使用起来明显简单于直接调用底层API。
*
* 函数调用步骤如下:
*
* [初始化]
* SDL_Init(): 初始化SDL。
* SDL_OpenAudio(): 根据参数(存储于SDL_AudioSpec)打开音频设备。
* SDL_PauseAudio(): 播放音频数据。
*
* [循环播放数据]
* SDL_Delay(): 延时等待播放完成。
*
* [播放音频的基本原则]
* 声卡向你要数据而不是你主动推给声卡
* 数据的多少是由音频参数决定的*/
//Buffer://|-----------|-------------|//chunk-------pos---len-----|
static Uint8 *audio_chunk;staticUint32 audio_len;static Uint8 *audio_pos;void fill_audio(void *udata, Uint8 *stream, intlen) {//SDL 2.0
SDL_memset(stream, 0, len);if (audio_len == 0)return;
len= (len > audio_len ?audio_len : len);
SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);
audio_pos+=len;
audio_len-=len;
}int main(int argc, char*argv[])
{//Init
if (SDL_Init(SDL_INIT_AUDIO |SDL_INIT_TIMER)) {
printf("Could not initialize SDL - %s\n", SDL_GetError());return -1;
}//SDL_AudioSpec
SDL_AudioSpec wanted_spec;
wanted_spec.freq= 48000;
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;
}int pcm_buffer_size = 4096;char *pcm_buffer = (char *)malloc(pcm_buffer_size);int data_count = 0;//Play
SDL_PauseAudio(0);while (1) {if (fread(pcm_buffer, 1, pcm_buffer_size, fp) !=pcm_buffer_size) {//Loop
fseek(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 length
audio_len =pcm_buffer_size;
audio_pos=audio_chunk;while (audio_len > 0)//Wait until finish
SDL_Delay(1);
}free(pcm_buffer);
SDL_Quit();return 0;
}
sdl 打开耳机_SDL 开发实战(七): 使用 SDL 实现 PCM播放器相关推荐
- sdl 打开耳机_SDL使用
简介 Simple DirectMedia Layer, 简称SDL,是一个自由的跨平台的多媒体开发包,主要通过OpenGL和2D视频帧缓冲(framebuffer)提供对音频.键盘.鼠标.游戏操纵杆 ...
- [嵌入式Linux项目实战开发]基于QT4.7.4的音乐播放器实现与设计【2018年给力项目】
[嵌入式Linux项目实战开发]基于QT4.7.4的音乐播放器实现与设计[2018年给力项目]是[创科之龙]团队aiku嵌入式视频教程系列制作的现有的音乐播放器. 主要功能实现: 1.新建工程,基类选 ...
- 稳扎稳打Silverlight(18) - 2.0视频之详解MediaElement, 开发一个简易版的全功能播放器...
[索引页] [×××] 稳扎稳打Silverlight(18) - 2.0视频之详解MediaElement, 开发一个简易版的全功能播放器 作者:webabcd 介绍 Silverlight 2.0 ...
- Android 音乐播放器的开发教程(三) 小卷毛播放器的主界面开发 ---- 小达
Android 音乐播放器的开发教程(三) 小卷毛播放器的主界面开发 拿好素材之后,打开你们的开发工具,小达这里用的是android studio1.0, 新建一个项目,打开activity_main ...
- python 播放本地音乐_实战项目—python实现本地音乐播放器
随着网络的发展,我们已经很少将音乐下载到本地,而是直接在线听歌,方便而又直接.也许你用的音乐播放器是这个 也许是这个 这都不是重点,今天我们要用python自己打造一款音乐播放器. 具体思路 使用py ...
- iOS开发拓展篇—音频处理(音乐播放器3)
iOS开发拓展篇-音频处理(音乐播放器3) 说明:这篇文章主要介绍音频工具类和播放工具类的封装. 一.控制器间数据传递 1.两个控制器之间数据的传递 第一种方法:self.parentViewCont ...
- 【开源推荐】进阶实战,从一款音乐播放器开始
0.前言 前面有同学问我,想要做一个Android 实战项目,问我有没有好的开源项目可以参考和练习? 想想自己以前也是,当项目没有什么新任务的时候,想着自己写一个实战项目来来练练手,那拿什么项目来练手 ...
- esp32录音功能开发_自制基于ESP32的音频播放器
自制一台音乐播放器会很有趣,因此,在本篇文章中,我们将使用ESP32微控制器制作一个有趣的音频播放器,只需将一个扬声器连接到ESP32即可获得音效.本文中,我们将使用LM386.扬声器和ESP32来播 ...
- Android音视频开发(2)常用的系统播放器MediaPlayer
1.状态图及生命周期 MediaPlayer是一个多媒体播放类,通过它控制音视频流或本地音视频资源的播放过程. 它分为很多状态,如下图所示: 图中的单箭头弧代表同步函数调用,双箭头弧代表异步函数调用. ...
最新文章
- java synchronized 参数_个人对synchronized锁的参数理解,如果有误望指出
- 与数据相关的运算符和伪指令 offset align ptr type lengthof sizeof label 间接寻址 间接操作数 数组 变址操作数 指针 jmp, loop
- vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响)
- How is XSRF token retrieved from backend
- Halcon图像滤波方法与原理概述
- datax 导入数据中文乱码_DataX在有赞大数据平台的实践
- 1、Flutter Widget(IOS Style) - CupertinoApp;
- MYSQL函数应用----替换函数replace()用法
- JDK API 1.6.0中文版零C币纯分享,直接下载即可。
- Pytorch优化器全总结(二)Adadelta、RMSprop、Adam、Adamax、AdamW、NAdam、SparseAdam(重置版)
- vm8.0下安装mac
- 计算机主板电源接口8pin,菜鸟老鸟都要知道 电源接口图文全教程
- HbuilderX配置微信开发者工具
- Vue-Layout(可视化布局)
- 直线绘制算法-中点画线法
- Windows10 下同一局域网两台电脑互传文件及其取消
- c++单精度和双精度的运算例子(计算机占位存储)
- MOOG穆格伺服阀D661-4444C G60JOAA6VSX2HA
- 遥感—以常用夜光遥感卫星介绍为主
- VMP (VMProtect)脱壳
热门文章
- php保留两位小数的函数,php保留两位小数的几种方法介绍
- [附源码]计算机毕业设计Python葡萄酒销售管理系统论文(程序+源码+LW文档)
- python读取大智慧数据_大智慧数据读取器day.dat
- dijstra + 链式前向星 一个人的旅行 HDU - 2066
- backlog配置_tcp-backlog配置
- 笔记-项目立项管理与招投标管理-复习要点
- 全局安装nuxt_Nuxt爬坑
- 基于随机森林的植物环状RNA识别软件
- 【简历】项目管理讲师个人简历(系统集成)
- 对80后玩家影响深远的12款单机游戏