SDL播放wav格式的音乐

#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;
}

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章