SDL播放wav格式的音乐

来源:互联网 发布:2015十大网络流行语 编辑:程序博客网 时间:2024/05/21 10:24
#include "stdafx.h"#include<stdlib.h>#include<stdio.h>#include<SDL.h>#include<SDL_config.h>
static SDL_AudioSpec spec;static Uint8 *sound = NULL;static Uint32 soundlen = 0;static int posindex = 0;static Uint32 positions[64];static void quit(int rc) {    SDL_Quit();    exit(rc);}/*_pos:userdata的数据stream:需要填充的流len:相应stream的大小简单来说就是将音频在内存中的地址复制给stream,SDL会播放stream中对应地址的数据*/void SDLCALL fillerup(void *_pos, Uint8 *stream, int len){    Uint32 pos = *((Uint32*)_pos);    Uint8 *waveptr;    int waveleft;    /*设置当前声音指针    声音指针+当前播放的位置    */    waveptr = sound + pos;    //剩余声音数据   声音数据长度-当前播放的位置       waveleft = soundlen - pos;    /* 如果剩余数据<需要的长度 */    while (waveleft <= len)    {        //拷贝剩余数据到音频缓冲区          SDL_memcpy(stream,waveptr,waveleft);        //音频缓冲区stream指针后移          stream += waveleft;        len -= waveleft;        //拷贝玩剩余数据          //waveptr指向 声音数据开头            waveptr = sound;        //长度等于len        waveleft = soundlen;        pos = 0;    }    SDL_memcpy(stream, waveptr, len);    pos += len;    *((Uint32*)_pos) = pos;}static int done = 0;void poked(int sig) {    done = 1;}static void iteration(){    SDL_Event e;    SDL_AudioDeviceID dev;    //获取当前等待的事件    while (SDL_PollEvent(&e))     {        if (e.type == SDL_QUIT)         {            done = 1;        }        else if (e.type==SDL_AUDIODEVICEADDED)//音频添加        {            const char *name = SDL_GetAudioDeviceName(e.adevice.which, 0);            SDL_Log("new %s audio device :%s\n",e.adevice.iscapture?"capture":"output",name);            if (!e.adevice.iscapture)            {                positions[posindex] = 0;                spec.userdata = &positions[posindex++];                spec.callback = fillerup;                dev = SDL_OpenAudioDevice(name, 0, &spec, NULL, 0);                if (!dev)                {                    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "can not open '%s':%s\n",name, SDL_GetError());                }                else                {                    SDL_Log("opened '%s' as %u \n", name, (unsigned int)dev);                    //循环播放音乐                    SDL_PauseAudioDevice(dev, 0);                    SDL_OpenAudio(&spec,NULL);                }            }            else if (e.type==SDL_AUDIODEVICEREMOVED)//音频移除            {                dev = (SDL_AudioDeviceID)e.adevice.which;                SDL_Log("%s device %u removed.\n", e.adevice.iscapture ? "capture" : "output", (unsigned int)dev);                //关闭音频设备                SDL_CloseAudioDevice(dev);            }        }    }}/**音频播放的步骤1.初始化SDL模块,这里是要播放音乐,所有初始化SDL_INIT_AUDIO和视频模块2.创建窗口3.加载音频4.播放音频5.视频音频6.退出SDL*/int main(int argc, char* argv[]){    int i;    char filename[4096];    //设置显示application 的log信息    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);    //设置sdl要初始化的模块    if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO)<0)     {        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,"couldn't initialize SDL:%s\n",SDL_GetError());        return 1;    }    //创建窗口    //SDL_MinimizeWindow(SDL_CreateWindow("test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0));    //获取文件名    if (argc > 1)    {        SDL_strlcpy(filename, argv[1], sizeof(filename));    }    else    {        SDL_strlcpy(filename, "sample.wav", sizeof(filename));        //SDL_strlcpy(filename, "Now.mp3", sizeof(filename));    }    /**     将音频文件加载到内存中     filename:文件名     spec:音频的规格     sound:音频的句柄     soundlen:音频文件的长度    */    if (SDL_LoadWAV(filename, &spec, &sound, &soundlen) == NULL)    {        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,"cound't load %s:%s \n",filename,SDL_GetError());        quit(1);    }    SDL_Log("available audio drivers");    //打印音频设备    for (i = 0; i < SDL_GetNumAudioDrivers(); i++)    {        SDL_Log("%i:%s", i, SDL_GetAudioDriver(i));    }    //查看当前使用的音频设备    SDL_Log("Using audio driver:%s\n", SDL_GetCurrentAudioDriver());    while (!done)    {        SDL_Delay(100);        iteration();    }    //释放音频内存    SDL_FreeWAV(sound);    //退出sdl    SDL_Quit();    system("pause");    return 0;}

我这里只是将官网给出的例子添加了注释,方便大家理解

0 0
原创粉丝点击