Skip to content

Instantly share code, notes, and snippets.

@progschj
Created October 13, 2012 19:54
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save progschj/3885932 to your computer and use it in GitHub Desktop.
A Simple Ogg Vorbis Player using libvorbisplay and OpenAL
#include <stdlib.h>
#include <stdio.h>
#include <AL/alut.h>
#include <vorbis/codec.h>
#include <vorbis/vorbisfile.h>
char pcmout[16*1024];
void check_error()
{
ALenum error = alGetError();
switch(error)
{
case AL_INVALID_NAME: fprintf(stderr,"invalid name\n"); return;
case AL_INVALID_ENUM: fprintf(stderr,"invalid enum\n"); return;
case AL_INVALID_VALUE: fprintf(stderr,"invalid value\n"); return;
case AL_INVALID_OPERATION: fprintf(stderr,"invalid operation\n"); return;
case AL_OUT_OF_MEMORY: fprintf(stderr,"out of memory\n"); return;
default: return;
}
}
int main (int argc, char **argv)
{
OggVorbis_File vf;
int current_section;
int eof = 0;
FILE *fp = fopen(argv[1], "rb");
if(fp == NULL)
{
fprintf(stderr, "could not open file %s", argv[1]);
exit(1);
}
if(ov_open_callbacks(fp, &vf, NULL, 0, OV_CALLBACKS_DEFAULT)<0)
{
fprintf(stderr, "input does not appear to be in an ogg bitstream");
exit(1);
}
vorbis_info *vi = ov_info(&vf, -1);
printf("rate %d channels: %d\n",vi->rate, vi->channels);
ALuint source;
alutInit (&argc, argv);
ALuint buffers[16];
alGenBuffers(16, buffers);
alGenSources (1, &source);
for(int i = 0;i<16;++i)
{
long pos = 0;
while(pos < sizeof(pcmout))
{
long ret = ov_read(&vf, pcmout+pos, sizeof(pcmout)-pos, 0, 2, 1, &current_section);
pos+=ret;
if(ret == 0)
{
eof = 1;
break;
}
}
alBufferData(buffers[i], AL_FORMAT_STEREO16, pcmout, pos, vi->rate);
}
alSourceQueueBuffers(source, 16, buffers);
alSourcePlay(source);
check_error();
while(!eof)
{
ALuint released[16];
ALint count;
alGetSourcei(source, AL_BUFFERS_PROCESSED, &count);
alSourceUnqueueBuffers(source, count, released);
for(int i = 0;i<count;++i)
{
long pos = 0;
while(pos < sizeof(pcmout))
{
long ret = ov_read(&vf, pcmout+pos, sizeof(pcmout)-pos, 0, 2, 1, &current_section);
pos+=ret;
if(ret == 0)
{
eof = 1;
break;
}
}
alBufferData(released[i], AL_FORMAT_STEREO16, pcmout, pos, vi->rate);
}
alSourceQueueBuffers(source, count, released);
alutSleep(1/20.);
}
alutExit ();
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment