SDL2.0学习笔记6--用SDL播放音频wave文件

#include "SDL.h"

struct {
    Uint8   *sound;     // pointer to wave data
    Uint32  soundlen;   // length of wave data
    int     soundpos;   // current play position
}wave;

int done;

static void quit(int rc)
{
    SDL_Quit();
    exit(rc);
}

void SDLCALL fill_audio(void *unused, Uint8 *stream, int len)
{
    Uint8   *waveptr;
    int     waveleft;
    int     copylen;

    SDL_memset(stream, 0, len);

    if (wave.soundpos == wave.soundlen)
    {
        done = 1;
        return;
    }

    waveptr  = wave.sound + wave.soundpos;
    waveleft = wave.soundlen - wave.soundpos;

    waveleft <= len ? (copylen = waveleft) : (copylen = len);

    SDL_memcpy(stream, waveptr, copylen);
    wave.soundpos += copylen;

    SDL_Log("len: %d, copylen:%d\n", len, copylen);
}

/*
    SDL播放音频wave文件测试
*/
int audio_test()
{
    SDL_AudioSpec spec;
    const char * audio_file = "sample.wav";

    done = 0;

    // 1. init
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

    if (SDL_Init(SDL_INIT_AUDIO) < 0)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL:%s\n", SDL_GetError());
        return (1);
    }

    // 2. open audio wave file
    if (SDL_LoadWAV(audio_file, &spec, &wave.sound, &wave.soundlen) == NULL)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", audio_file, SDL_GetError());
        quit(1);
    }
    spec.callback = fill_audio;

    // 3. open audio
    if (SDL_OpenAudio(&spec, NULL) < 0)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError());
        SDL_FreeWAV(wave.sound);
        quit(2);
    }

    SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());

    // 4. play
    SDL_PauseAudio(0);

    /*
        5. fill audio data, it's be done by fill_audio
    */

    // 6. waiting for play end
    while (0 == done)
    {
        SDL_Delay(1);
    }

    // 7. close
    SDL_CloseAudio();
    SDL_FreeWAV(wave.sound);
    SDL_Quit();

    return 0;
}

以上代码参考自SDL的test文件夹下的loopwave.c函数。

由上,用SDL播放音频wave文件包含如下流程:

1、 调用SDL_Init(SDL_INIT_AUDIO)初始化音频子系统;

2、 调用SDL_LoadWAW()打开音频wave文件,获取对应的spec、波形数据及波形数据长度等信息;

3、 调用SDL_OpenAudio()打开音频设备(在这之前还需要设置spec的callback成员),这函数实际上是启动了SDL_RunAudio线程,用于实际的音频播放;

4、 调用SDL_PauseAudio(0)播放音频;

5、 调用spec.callback()函数,填充音频数据(这一步由SDL_RunAudio线程完成);

6、 待播放完成后,关闭音频音频设备(SDL_CloseAudio()),释放波形数据buffer(SDL_FreeWAV()),然后退出。



你可能感兴趣的:(SDL2.0学习笔记6--用SDL播放音频wave文件)