在上文,我们做了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播放器相关推荐

  1. sdl 打开耳机_SDL使用

    简介 Simple DirectMedia Layer, 简称SDL,是一个自由的跨平台的多媒体开发包,主要通过OpenGL和2D视频帧缓冲(framebuffer)提供对音频.键盘.鼠标.游戏操纵杆 ...

  2. [嵌入式Linux项目实战开发]基于QT4.7.4的音乐播放器实现与设计【2018年给力项目】

    [嵌入式Linux项目实战开发]基于QT4.7.4的音乐播放器实现与设计[2018年给力项目]是[创科之龙]团队aiku嵌入式视频教程系列制作的现有的音乐播放器. 主要功能实现: 1.新建工程,基类选 ...

  3. 稳扎稳打Silverlight(18) - 2.0视频之详解MediaElement, 开发一个简易版的全功能播放器...

    [索引页] [×××] 稳扎稳打Silverlight(18) - 2.0视频之详解MediaElement, 开发一个简易版的全功能播放器 作者:webabcd 介绍 Silverlight 2.0 ...

  4. Android 音乐播放器的开发教程(三) 小卷毛播放器的主界面开发 ---- 小达

    Android 音乐播放器的开发教程(三) 小卷毛播放器的主界面开发 拿好素材之后,打开你们的开发工具,小达这里用的是android studio1.0, 新建一个项目,打开activity_main ...

  5. python 播放本地音乐_实战项目—python实现本地音乐播放器

    随着网络的发展,我们已经很少将音乐下载到本地,而是直接在线听歌,方便而又直接.也许你用的音乐播放器是这个 也许是这个 这都不是重点,今天我们要用python自己打造一款音乐播放器. 具体思路 使用py ...

  6. iOS开发拓展篇—音频处理(音乐播放器3)

    iOS开发拓展篇-音频处理(音乐播放器3) 说明:这篇文章主要介绍音频工具类和播放工具类的封装. 一.控制器间数据传递 1.两个控制器之间数据的传递 第一种方法:self.parentViewCont ...

  7. 【开源推荐】进阶实战,从一款音乐播放器开始

    0.前言 前面有同学问我,想要做一个Android 实战项目,问我有没有好的开源项目可以参考和练习? 想想自己以前也是,当项目没有什么新任务的时候,想着自己写一个实战项目来来练练手,那拿什么项目来练手 ...

  8. esp32录音功能开发_自制基于ESP32的音频播放器

    自制一台音乐播放器会很有趣,因此,在本篇文章中,我们将使用ESP32微控制器制作一个有趣的音频播放器,只需将一个扬声器连接到ESP32即可获得音效.本文中,我们将使用LM386.扬声器和ESP32来播 ...

  9. Android音视频开发(2)常用的系统播放器MediaPlayer

    1.状态图及生命周期 MediaPlayer是一个多媒体播放类,通过它控制音视频流或本地音视频资源的播放过程. 它分为很多状态,如下图所示: 图中的单箭头弧代表同步函数调用,双箭头弧代表异步函数调用. ...

最新文章

  1. java synchronized 参数_个人对synchronized锁的参数理解,如果有误望指出
  2. 与数据相关的运算符和伪指令 offset align ptr type lengthof sizeof label 间接寻址 间接操作数 数组 变址操作数 指针 jmp, loop
  3. vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响)
  4. How is XSRF token retrieved from backend
  5. Halcon图像滤波方法与原理概述
  6. datax 导入数据中文乱码_DataX在有赞大数据平台的实践
  7. 1、Flutter Widget(IOS Style) - CupertinoApp;
  8. MYSQL函数应用----替换函数replace()用法
  9. JDK API 1.6.0中文版零C币纯分享,直接下载即可。
  10. Pytorch优化器全总结(二)Adadelta、RMSprop、Adam、Adamax、AdamW、NAdam、SparseAdam(重置版)
  11. vm8.0下安装mac
  12. 计算机主板电源接口8pin,菜鸟老鸟都要知道 电源接口图文全教程
  13. HbuilderX配置微信开发者工具
  14. Vue-Layout(可视化布局)
  15. 直线绘制算法-中点画线法
  16. Windows10 下同一局域网两台电脑互传文件及其取消
  17. c++单精度和双精度的运算例子(计算机占位存储)
  18. MOOG穆格伺服阀D661-4444C G60JOAA6VSX2HA
  19. 遥感—以常用夜光遥感卫星介绍为主
  20. VMP (VMProtect)脱壳

热门文章

  1. php保留两位小数的函数,php保留两位小数的几种方法介绍
  2. [附源码]计算机毕业设计Python葡萄酒销售管理系统论文(程序+源码+LW文档)
  3. python读取大智慧数据_大智慧数据读取器day.dat
  4. dijstra + 链式前向星 一个人的旅行 HDU - 2066
  5. backlog配置_tcp-backlog配置
  6. 笔记-项目立项管理与招投标管理-复习要点
  7. 全局安装nuxt_Nuxt爬坑
  8. 基于随机森林的植物环状RNA识别软件
  9. 【简历】项目管理讲师个人简历(系统集成)
  10. 对80后玩家影响深远的12款单机游戏