SDL播放PCM

最近在学习ffmpeg,想开发一个基于ffmpeg的播放器。后来发现ffmpeg只能进行解封装、解码操作,最终的sink需要借助SDL2来实现,所以先学习一下SDL2,用SDL2实现播放pcm的功能。

标题SDL简介

Simple DirectMedia Layer是一个跨平台开发库,旨在通过OpenGL和Direct3D提供对音频、键盘、鼠标、操纵杆和图形硬件的底层访问,SDL提供了数种控制图像、声音、输出入的函数,大大降低了音视频的开发难度,我们只需要将解码后的音视频数据交给SDL渲染,不必关心底层的实现方式。SDL支持的平台包括Windows、Mac OS X、Linux、iOS和Android。SDL是用C编写的,并且还有可以使用C++、C#和Python开发。

SDL播放PCM

SDL播放pcm数据的代码比较简单,代码参考了一个大神的博客,博客地址
audio.cpp

#include <iostream>
#ifdef __cplusplus
extern "C"
{
#endif
#include <SDL2/SDL.h>
#include <SDL2/SDL_video.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_rect.h>
#ifdef __cplusplus
};
#endif


static Uint8 *audio_chunk;
static Uint32 audio_len;
static Uint8 *audio_pos;
int pcm_buffer_size = 4096;

//回调函数,音频设备需要更多数据的时候会调用该回调函数
void read_audio_data(void *udata, Uint8 *stream, int len) {
    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[]) {

    if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
        printf("Could not initialize SDL - %s\n", SDL_GetError());
        return -1;
    }
  
    SDL_AudioSpec spec;
    spec.freq = 44100;//根据你录制的PCM采样率决定
    spec.format = AUDIO_S16SYS;
    spec.channels = 1; //单声道
    spec.silence = 0;
    spec.samples = 1024;
    spec.callback = read_audio_data;
    spec.userdata = NULL;

    if (SDL_OpenAudio(&spec, NULL) < 0) {
        printf("can't open audio.\n");
        return -1;
    }

    FILE *fp = fopen("./audio.pcm", "rb+");
    if (fp == NULL) {
        printf("cannot open this file\n");
        return -1;
    }
    char *pcm_buffer = (char *) malloc(pcm_buffer_size);

    //播放
    SDL_PauseAudio(0);

    while (1) {
        if (fread(pcm_buffer, 1, pcm_buffer_size, fp) != pcm_buffer_size) { //从文件中读取数据,剩下的就交给音频设备去完成了,它播放完一段数据后会执行回调函数,获取等多的数据
            break;
        }

        audio_chunk = (Uint8 *) pcm_buffer;
        audio_len = pcm_buffer_size; //长度为读出数据长度,在read_audio_data中做减法
        audio_pos = audio_chunk;

        while (audio_len > 0) //判断是否播放完毕
            SDL_Delay(1);
    }
    free(pcm_buffer);
    SDL_Quit();

    return 0;
}

pcm数据可是使用ffmpeg命令行的方式mp3格式的音频转换为pcm,转换命令为:

ffmpeg -i audio1.mp3 -f s16le audio.pcm

cmake文件

cmake_minimum_required(VERSION 3.10)
project(pcmPlayer) # 指定的项目名称
set(CMAKE_CXX_STANDARD 11)

set(MY_LIBRARY_DIR /usr/local)
#需要设置为自己的SDL2安装路径
set(SDL_DIR /usr/include/SDL)
find_package(Threads REQUIRED)

include_directories(${SDL_DIR}/include/) # 头文件搜索路径
link_directories(${SDL_DIR}/lib/) # 动态链接库或静态链接库的搜索路径

add_executable(pcmPlayer audio.cpp)

# 添加链接库
target_link_libraries(
        pcmPlayer
        SDL2
)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值