Skip to main content
gamedev.net
🔒 Locked

OpenAL+Ogg work-in-progress

Started by MindCode May 16, 2003 at 4:47 PM 5 replies 1k views
Original Post
MindCode
MindCode
I''m at work right now (and bored stiff) so I can''t really do any coding. But I have had this in my head all day so I thought I''d work it out in notepad. I''m simply trying to figure out how to play Ogg files with OpenAL using the queue mechanism. I''m really new at Ogg Vorbis, and although I''m an avid OpenAL supporter, I really haven''t delved into the queue feature yet. Here''s what I''ve written so far. Let me know what you think. (I know I haven''t intialized OpenAL here but it''s just an experimiental "work-it-out-by-writting" type of thing). I''ve put this together from the little I know of Ogg streaming and the OpenAL queue. Let me know of what you think, or any bugs, mistakes, that sort of thing.
#include <al/al.h>
#include <al/alc.h>

#include <vorbis/codec.h>
#include <vorbis/vorbisfile.h>


#define CHUNK_SIZE 4096

OggVorbis_File OggVorbis;
vorbis_info*   VorbisInfo;
ALubyte        PCMdata[CHUNK_SIZE];




int main(int argc, char **argv) {

	int    section;
	int    result;
	ALuint buffer;
	ALuint source;


	ov_open(stdin, &OggVorbis, NULL, 0);

	VorbisInfo = ov_info(&OggVorbis, -1);

	alGenSources(1 &source);

	while(1) {

		result = ov_read(&OggVorbis, PCMdata, CHUNK_SIZE, 0, 2, 1, &section);

		if(result > 0) {

			alGenBuffers(1, &buffer);

			alBufferData(buffer, AL_STEREO16, PCMdata, result, VorbisInfo->rate);

			alSourceQueueBuffers(source, 1, buffer);
		}

		if(result < 0) {
			return -1; // error in stream.
		}
	}

	ov_clear(&OggVorbis);

	return 0;
};
 
That's just my understanding; I could be wrong.
Null and Void
Null and Void
I haven''t looked at it really hard, but here are two things I notice immediately: you never free/recycle buffers on the queue that are done being played from and you don''t handle ov_read returning 0, which means you''re at the end of the stream.

BTW: You did see my last reply as an AP in your last thread about how to use istream''s to feed Vorbisfile, right?

MindCode
MindCode
Well, I''ve added some error detection, and detection for hitting the end of the file. How would I handle unqueue? I''ve read the section from the Creative sdk but it''s greek to me.


#include <al/al.h>
#include <al/alc.h>

#include <vorbis/codec.h>
#include <vorbis/vorbisfile.h>


#define CHUNK_SIZE 4096

OggVorbis_File OggVorbis;
vorbis_info* VorbisInfo;
ALubyte PCMdata[CHUNK_SIZE];




int main(int argc, char **argv) {

int result;
int section;
ALuint buffer;
ALuint source;


result = ov_open(stdin, &OggVorbis, NULL, 0);

if(result < 0) {
return -1;
}

VorbisInfo = ov_info(&OggVorbis, -1);

alGenSources(1, &source);

result = 1;

while(result) {

result = ov_read(&OggVorbis, PCMdata, CHUNK_SIZE, 0, 2, 1, &section);

if(result > 0) {

alGenBuffers(1, &buffer);

alBufferData(buffer, AL_FORMAT_STEREO16, PCMdata, result, VorbisInfo->rate);

alSourceQueueBuffers(source, 1, buffer);
}

if(result < 0) {

return -1; // error in stream.
}
}

ov_clear(&OggVorbis);

return 0;
};
That's just my understanding; I could be wrong.
Null and Void
Null and Void
To completely unqueue finished buffers from a source and delete them (deleting them is optional, if you want to reuse them or whatever):

  
ALuint *Buffers, Count;

alGetSourceiv(SourceID,AL_BUFFERS_PROCESSED,(int *)&Count);

if(Count > 0) {
/* This is a good spot to use a stack-allocation function like
"alloca", actually; but I''ll stick to standard code here */
Buffers = malloc(sizeof(unsigned int) * Count);

if(Buffer == NULL)
/* Error */;

alSourceUnqueueBuffers(SourceID, Count, Buffers);

/* Delete them */

alDeleteBuffers(Count,Buffers);

free(Buffers);
}


MindCode
MindCode
Could I not load the whole file into buffers and queue them? Is this a bad idea? Some audio files get pretty big.

When on queue, will the buffers play in the order that I set them? (I know this sounds like a silly question if the answer is yes, but I would just like some clarifiation on how the queue works.)
That's just my understanding; I could be wrong.
Null and Void
Null and Void
quote:
Original post by MindCode
Could I not load the whole file into buffers and queue them? Is this a bad idea? Some audio files get pretty big.

Sure, you could do that, but as you said: it''s a bad idea. Why bother to ''stream'' the file at all if you''re going to do that? For small files: load them all at once into a single buffer. For large files: have a thread load more data and append it to the queue as needed. What your definition of large file is depends on your situation, but remember to base the size on PCM data size rather than whatever compressed format you''re decoding from.

quote:
Original post by MindCode
When on queue, will the buffers play in the order that I set them? (I know this sounds like a silly question if the answer is yes, but I would just like some clarifiation on how the queue works.)

It''s a normal queue: first in first out (FIFO).

Crispy
Crispy
I wrote a tutorial on buffered playback with OpenAL that''s posted under the articles->sound section. It loads a whole file into memory and plays it using 10 short buffers. If you add another thread that loads data from disk on queue, you can add buffered streming from the hard drive.

Never do anything that is a waste of time and be prepared to wage long tedious wars over this principle - Michael O''Connor

"Literally, it means that Bob is everything you can think of, but not dead; i.e., Bob is a purple-spotted, yellow-striped bumblebee/dragon/pterodactyl hybrid with a voracious addiction to Twix candy bars, but not dead."- kSquared

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.