Sign in to follow this  
CTPAX

OpenAL in windows

Recommended Posts

CTPAX    122
Can anyone help me with writting smallest possible code for playing wavs with OpenAL in windows... I've found out a couple of codes, but they are all written for console program, so when I implement them in a win program it just freezes image until the file is played...

Share this post


Link to post
Share on other sites
CTPAX    122
Something else: if anyone knows where I can find alut.h please send a link to me. And does anyone know why did they idea collapse?

Share this post


Link to post
Share on other sites
j-locke    945
Afraid I haven't used OpenAL enough to start throwing around code to answer your first question, but as for the 2nd... this link is to the OpenAL site to download alut for various platforms:
http://connect.creativelabs.com/openal/Downloads/Forms/AllItems.aspx?RootFolder=%2fopenal%2fDownloads%2fALUT&FolderCTID=&View=%7b6A9700C6%2d7248%2d4CD2%2d83F5%2d268F2C176072%7d

Share this post


Link to post
Share on other sites
Gorax    202
It seems quite a few people are struggling without ALUT, which is a little strange considering Open AL's documentation tells you how to initialise everything and read (and play) a wave file. In any case, here's some (very) basic code that'll allow you to play a wave:


#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <AL/al.h>
#include <AL/alc.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/*
WARNING: THIS IS ONLY A *VERY* BASIC WAVE HEADER
RIFF files (avis, waves, etc.) can have multiple headers and chunks of data,
including 'JUNK' headers which can basically be used to store messages.
Google some documentation on RIFF formats if you want to read every possible
wave file, but trust me when I say it takes a fair bit more code than this to
get something decent working.
*/

typedef struct {
char riff[4];//'RIFF'
unsigned int riffSize;
char wave[4];//'WAVE'
char fmt[4];//'fmt '
unsigned int fmtSize;
unsigned short format;
unsigned short channels;
unsigned int samplesPerSec;
unsigned int bytesPerSec;
unsigned short blockAlign;
unsigned short bitsPerSample;
char data[4];//'data'
unsigned int dataSize;
}BasicWAVEHeader;

int initOpenAL(ALCdevice** device,ALCcontext** context){
printf("Initialising Open AL...\n");
*device = alcOpenDevice(0);
if (*device){
*context = alcCreateContext(*device,0);
if (*context){
alcMakeContextCurrent(*context);
return 1;
}
alcCloseDevice(*device);
}
return 0;
}

//WARNING: This Doesn't Check To See If These Pointers Are Valid
void deinitOpenAL(ALCdevice* device,ALCcontext* context){
alcMakeContextCurrent(0);
alcDestroyContext(context);
alcCloseDevice(device);
}

//WARNING: This Doesn't Check To See If These Pointers Are Valid
char* readWAVE(char* filename,BasicWAVEHeader* header){
printf("Reading File...\n");
char* buffer = 0;
FILE* file = fopen(filename,"rb");
if (!file) return 0;

if (fread(header,sizeof(BasicWAVEHeader),1,file)){
if (!(//these things *must* be valid with this basic header
memcmp("RIFF",header->riff,4) ||
memcmp("WAVE",header->wave,4) ||
memcmp("fmt ",header->fmt,4) ||
memcmp("data",header->data,4)
)){
buffer = (char*)malloc(header->dataSize);
if (buffer){
if (fread(buffer,header->dataSize,1,file)){
fclose(file);
return buffer;
}
free(buffer);
}
}
}
fclose(file);
return 0;
}

ALuint createBufferFromWave(char* data,BasicWAVEHeader header){
printf("Creating Buffer...\n");
ALuint buffer = 0;

ALuint format = 0;
switch (header.bitsPerSample){
case 8:
format = (header.channels == 1) ? AL_FORMAT_MONO8 : AL_FORMAT_STEREO8;
break;
case 16:
format = (header.channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
break;
default:
//last time I checked, Open AL didn't support anything else
return 0;
}

alGenBuffers(1,&buffer);
alBufferData(buffer,format,data,header.dataSize,header.samplesPerSec);
return buffer;
}

int main(){
ALCdevice* device = 0;
ALCcontext* context = 0;
if (!initOpenAL(&device,&context)){
printf("FAILED TO INIT OPEN AL\n");
return 0;
}

BasicWAVEHeader header;
char* data = readWAVE("MyWave.wav",&header);
if (data){
//Now We've Got A Wave In Memory, Time To Turn It Into A Usable Buffer
ALuint buffer = createBufferFromWave(data,header);
if (buffer){
//You can usually free the data here, but in this example, it's done later

//Time to create a source to play the wave
ALuint source;
alGenSources(1,&source);
//and now we queue the buffer
alSourceQueueBuffers(source,1,&buffer);
//and play
printf("PLAYING...\n");
alSourcePlay(source);
//now we do nothing for 10 seconds but let it play
time_t t = time(0) + 10;
while (time(0) < t){
Sleep(100);
}
//now we stop it (assuming it's still playing...)
printf("STOPPING...\n");
alSourceStop(source);
//unqueue the buffer
alSourceUnqueueBuffers(source,1,&buffer);
//clean up
alDeleteSources(1,&source);
alDeleteBuffers(1,&buffer);
printf("ALL DONE!\n");
}else printf("FAILED TO CREATE BUFFER!\n");
free(data);
}else printf("FAILED TO READ FILE!\n");
deinitOpenAL(device,context);

return 1;
}




[EDIT]
This code is extremely basic (and subsequently crap, but I wrote it in a whole 30 minutes after finding bits and pieces of code I wrote ages ago, so it's not that bad...). The actual code I use to read waves (and ogg vorbis files) these days has been reduced to a single line. That's what happens when you write reusable code though.

I suggest you don't do anything more than see how this works, then write the code on your own, because this code really is that horrible. Check out Open AL's documentation, because as I said before, it does show you how to do it, and the code's actually explained, and looks far better than this.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this