SDL 播放pcm数据

 代码来自慕课网李超视频,我只是添加了注释

#include <stdio.h>
#include <SDL.h>

#define BLOCK_SIZE 4096000

static Uint8 *audio_buf = NULL;
static Uint8 *audio_pos = NULL;
static size_t buffer_len = 0;
//声卡是主动向你要数据,即通过回调函数的方式发送数据;
//数据的多少由音频参数决定的;
//callback function for audio devcie
void read_audio_data(void *udata, Uint8 *stream, int len){
/*
	udata : 用户数据
	stream : 音频数据缓冲区
	len : 需要的音频数据大小

*/
    if(buffer_len == 0){
        return;
    }

    SDL_memset(stream, 0, len);

    len = (len < buffer_len) ? len : buffer_len;
	//拷贝数据到音频
    SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);

    audio_pos += len;
    buffer_len -= len;
}


int main(int argc, char *argv[])
{
    int ret = -1;

    FILE *audio_fd = NULL;

    SDL_AudioSpec spec;

    char *path = "./test.pcm";

    //SDL initialize
    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)){
        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
        return ret;
    }

    //open pcm file
    audio_fd = fopen(path, "r");
    if(!audio_fd){
        fprintf(stderr, "Failed to open pcm file!\n");
        goto __FAIL;
    }

    //alloc memory for audio
    audio_buf = (Uint8*)malloc(BLOCK_SIZE);
    if(!audio_buf){
        goto __FAIL;
    }

    //SDL_AudioSpec 设置参数
    spec.freq = 44100;;//采样率
    spec.format = AUDIO_S16SYS; //数据位数
    spec.channels = 2;//通道数
    spec.silence = 0;
    spec.samples = 2048;;
    spec.callback = read_audio_data;;
    spec.userdata = NULL;

    //open audio devcie打开音频数据
    if(SDL_OpenAudio(&spec, NULL)){
        fprintf(stderr, "Failed to open audio device, %s\n", SDL_GetError());
        goto __FAIL;
    }

    //play audio开始暂停播放
    SDL_PauseAudio(0);
	//SDL_MixAudio//混合音频
    do{
        //read data from pcm file
        buffer_len = fread(audio_buf, 1, BLOCK_SIZE, audio_fd);
        fprintf(stderr, "block size is %zu\n", buffer_len);

        audio_pos = audio_buf;

        //the main thread wait for a moment 每次读取一块(BLOCK_SIZE)数据
        while(audio_pos < (audio_buf + buffer_len)) {
            SDL_Delay(1);
        }

    }while(buffer_len !=0);

    //close audio device关闭音频设备
    SDL_CloseAudio();

    ret = 0;

__FAIL:
    //release some resources
    if(audio_buf){
        free(audio_buf);
    }

    if(audio_fd){
        fclose(audio_fd);
    }

    //quit SDL
    SDL_Quit();

    return ret;
}


发布了136 篇原创文章 · 获赞 22 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/u010261063/article/details/103731406
SDL