.ogg再生(OpenAL)

OpenAL で .ogg を再生します。

#pragma comment ( lib, "libogg_static.lib" )
#pragma comment ( lib, "libvorbis_static.lib" )
#pragma comment ( lib, "libvorbisfile_static.lib" )
#pragma comment ( lib, "OpenAL32.lib" )
#include "vorbis/vorbisfile.h"
#include <windows.h>

#include <al.h>
#include <alc.h>
#include <stdio.h>
#define NUM_BUFFERS 32
#define BUFFER_SIZE 4096
void main()
{
    ALCdevice *device;
    ALCcontext *context;
    ALuint source, buffer;
    ALint state, num;
    device = alcOpenDevice(NULL);
    context = alcCreateContext(device, NULL);
    alcMakeContextCurrent(context);
    alGenSources(1, &source);
    FILE *fp;
 fopen_s(&fp,"sample.ogg", "rb");
    OggVorbis_File vf;
    int current = 0;
    ov_open(fp, &vf, NULL, 0);
    while(1) {
  char data[BUFFER_SIZE];
        long size = ov_read(&vf, data, sizeof(data), 0, 2, 1, &current);
        vorbis_info *info = ov_info(&vf, -1);
        ALenum format = info->channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
        if (size <= 0) {
            break;
        }
        alGetSourcei(source, AL_BUFFERS_QUEUED, &num);
        if (num < NUM_BUFFERS) {
            alGenBuffers(1, &buffer);
        } else {
            alGetSourcei(source, AL_SOURCE_STATE, &state);
            if (state != AL_PLAYING) {
                alSourcePlay(source);
            }
            while (alGetSourcei(source, AL_BUFFERS_PROCESSED, &num), num == 0) {
                Sleep(100);
            }
            alSourceUnqueueBuffers(source, 1, &buffer);
        }
        alBufferData(buffer, format, data, size, info->rate);
        alSourceQueueBuffers(source, 1, &buffer);
    }
    ov_clear(&vf);
    alGetSourcei(source, AL_SOURCE_STATE, &state);
    if (state != AL_PLAYING) {
        alSourcePlay(source);
    }
    while (alGetSourcei(source, AL_SOURCE_STATE, &state), state == AL_PLAYING) {
        Sleep(100);
    }
    while (alGetSourcei(source, AL_BUFFERS_PROCESSED, &num), num > 0) {
        alSourceUnqueueBuffers(source, 1, &buffer);
        alDeleteBuffers(1, &buffer);
    }
    alDeleteSources(1, &source);
    alcMakeContextCurrent(NULL);
    alcDestroyContext(context);
    alcCloseDevice(device);
    return;
}

 

最終更新:2012年12月18日 15:44