root/trunk/orca/gl/audio.c

Revision 144, 7.7 kB (checked in by krobillard, 3 years ago)

Native arguments are now kept on the stack until after the call and the
result is now always put into a1.

Line 
1//============================================================================
2//
3// ORCA OpenAL Module
4// Copyright (C) 2005-2006  Karl Robillard
5//
6//  This library is free software; you can redistribute it and/or
7//  modify it under the terms of the GNU Lesser General Public
8//  License as published by the Free Software Foundation; either
9//  version 2.1 of the License, or (at your option) any later version.
10//
11//  This library is distributed in the hope that it will be useful,
12//  but WITHOUT ANY WARRANTY; without even the implied warranty of
13//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14//  Lesser General Public License for more details.
15//
16//  You should have received a copy of the GNU Lesser General Public
17//  License along with this library; if not, write to the Free Software
18//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19//
20//============================================================================
21
22
23#include <stdio.h>
24#include <stdlib.h>
25#ifdef __APPLE__
26#include <OpenAL/al.h>
27#include <OpenAL/alc.h>
28#include <OpenAL/alut.h>
29#elif defined(_WIN32)
30#include <al.h>
31#include <alc.h>
32#include <alut.h>
33#else
34#include <AL/al.h>
35#include <AL/alc.h>
36#include <AL/alut.h>
37#include <AL/alext.h>
38#endif
39#include "os.h"
40#include "ovalue.h"
41#include "audio.h"
42
43
44void audioStopMusic();
45
46
47#define SAMPLE_ID(sd)   (sd->index)
48
49// Counts must be a power of 2.
50#define FX_COUNT        8
51#define AMBIENT_COUNT   2
52
53#define SOURCE_COUNT    FX_COUNT + AMBIENT_COUNT
54
55
56static int _audioUp = 0;
57static ALCdevice*  _adevice  = 0;
58static ALCcontext* _acontext = 0;
59static ALuint _asource[ SOURCE_COUNT ];
60
61
62#define MUSIC_BUFFERS       1
63static int     _hasVorbis = 0;
64static ALuint  _musicSource = 0;
65static ALfloat _musicGain = 1.0f;
66static ALuint  _musicBuffers[ MUSIC_BUFFERS ];
67
68
69/**
70  Called once at program startup.
71  Returns 0 on a fatal error.
72*/
73int audioStartup()
74{
75#if 1
76    _adevice = alcOpenDevice( 0 );
77    if( ! _adevice )
78        return 0;
79    _acontext = alcCreateContext( _adevice, 0 );
80    alcMakeContextCurrent( _acontext );
81#else
82    alutInit( 0, 0 );
83#endif
84
85    alGenSources( SOURCE_COUNT, _asource );
86    alGenBuffers( MUSIC_BUFFERS, _musicBuffers );
87
88    _audioUp = 1;
89
90    if( alIsExtensionPresent( (ALubyte*) "AL_EXT_vorbis" ) )
91        _hasVorbis = 1;
92    else
93        dprint( "OpenAL AL_EXT_vorbis not present - music disabled\n" );
94
95    return 1;
96}
97
98
99/**
100  Called once when program exits.
101  It is safe to call this even if audioStartup() was not called.
102*/
103void audioShutdown()
104{
105    if( _audioUp )
106    {
107        audioStopMusic();
108
109        alDeleteSources( SOURCE_COUNT, _asource );
110        alDeleteBuffers( MUSIC_BUFFERS, _musicBuffers );
111
112#if 1
113        // Cannot use alutExit() on my box (FC3/Shuttle XPC) since
114        // alcMakeContextCurrent(0) -> _alLockMixerPause() will hangup.
115        alcDestroyContext( _acontext );
116        alcCloseDevice( _adevice );
117#else
118        alutExit();
119#endif
120    }
121}
122
123
124#if 0
125/**
126  Called periodically (once per frame) to drive sound engine.
127*/
128void audioUpdate()
129{
130}
131#endif
132
133
134static int wav_sig( uint8_t* sig, int sigLen )
135{
136    if( sigLen < 4 )
137        return 0;
138    return( sig[0]=='R' && sig[1]=='I' && sig[2]=='F' && sig[3]=='F');
139}
140
141
142int wav_loader( char* filename, uint8_t* sig, int sigLen )
143{
144    if( wav_sig( sig, sigLen ) )
145    {
146        ALenum format;
147        ALsizei size;
148        ALvoid* data;
149        ALsizei freq;
150        ALboolean loop;
151
152        alutLoadWAVFile( (ALbyte*) filename, &format,&data,&size,&freq,&loop );
153
154        if( data )
155        {
156            ALuint buffer;
157            alGenBuffers( 1, &buffer );
158            alBufferData( buffer, format, data, size, freq );
159            {
160            OValue* a1 = orTOS;
161            orResult( OT_SOUND, buffer );
162            }
163        }
164        else
165        {
166            orError( "alutLoadWAVFile() failed" );
167        }
168
169        alutUnloadWAV( format, data, size, freq );
170
171        return 1;
172    }
173    return 0;
174}
175
176
177#if 0
178bool osLoadSample( OS_SAMPLE* sp, BSample* bs )
179{
180    if( _audioUp )
181    {
182        ALenum format;
183
184        switch( bs->format )
185        {
186            case BSAMPLE_MONO8:    format = AL_FORMAT_MONO8;    break;
187            case BSAMPLE_MONO16:   format = AL_FORMAT_MONO16;   break;
188            case BSAMPLE_STEREO8:  format = AL_FORMAT_STEREO8;  break;
189            case BSAMPLE_STEREO16: format = AL_FORMAT_STEREO16; break;
190        }
191
192        alGenBuffers( 1, &sp->uh );
193        alBufferData( sp->uh, format, bs->pcm(), bs->size, bs->freq );
194    }
195    else
196    {
197        sp->uh = 0;
198    }
199
200    return 1;
201}
202
203
204void osInitSample( OS_SAMPLE* sp )
205{
206    sp->uh = 0;
207}
208
209
210void osFreeSample( OS_SAMPLE* sp )
211{
212    if( sp->uh )
213    {
214        alDeleteBuffers( 1, &sp->uh );
215        sp->uh = 0;
216    }
217}
218#endif
219
220
221int audioPlaySound( OValue* sound )
222{
223    static int n = 0;
224    if( sound && _audioUp )
225    {
226        ALuint src = _asource[ n ];
227
228        alSourcei( src, AL_BUFFER, SAMPLE_ID( sound ) );
229        alSourcePlay( src );
230
231        ++n;
232        n &= FX_COUNT - 1;          // Requires FX_COUNT to be a power of 2.
233        return src;
234    }
235    return 0;
236}
237
238
239#if 0
240int osPlayAmbientLoop( SoundData* sd )
241{
242    static int n = 0;
243    if( sd && _audioUp )
244    {
245        ALuint src = _asource[ n + FX_COUNT ];
246
247        alSourcei( src, AL_BUFFER, SAMPLE_ID( sd ) );
248        alSourcei( src, AL_LOOPING, AL_TRUE );
249        alSourcePlay( src );
250
251        ++n;
252        n &= AMBIENT_COUNT - 1;     // Requires count to be a power of 2.
253        return src;
254    }
255    return 0;
256}
257
258
259void osStopSound( int id )
260{
261    if( _audioUp )
262        alSourceStop( id );
263}
264#endif
265
266
267void audioPlayMusic( const char* file )
268{
269#ifdef AL_FORMAT_VORBIS_EXT
270    if( _audioUp && _hasVorbis )
271    {
272        int   size;
273        void* fileBuf = 0;
274        int   ok = 0;
275
276        //dprint( "osPlayMusic( %s )", file );
277
278        audioStopMusic();
279
280        size = orFileSize( file );
281        if( size > 0 )
282        {
283            fileBuf = memAlloc( size );
284            if( fileBuf )
285            {
286                FileHandle fp = fileOpen( file, FILE_READ_BINARY );
287                if( fp )
288                {
289                    if( fileRead( fp, fileBuf, size ) == (size_t) size )
290                        ok = 1;
291                    fileClose( fp );
292                }
293            }
294        }
295
296        if( ok )
297        {
298            alGenSources( 1, &_musicSource );
299
300            alSourcei ( _musicSource, AL_LOOPING, AL_FALSE );
301            alSourcei ( _musicSource, AL_SOURCE_RELATIVE, AL_TRUE );
302            alSource3f( _musicSource, AL_POSITION,  0.0f, 0.0f, 0.0f );
303            alSource3f( _musicSource, AL_VELOCITY,  0.0f, 0.0f, 0.0f );
304            alSource3f( _musicSource, AL_DIRECTION, 0.0f, 0.0f, 0.0f );
305            alSourcef ( _musicSource, AL_ROLLOFF_FACTOR, 0.0f );
306            alSourcef ( _musicSource, AL_GAIN, _musicGain );
307
308            alBufferData( _musicBuffers[0], AL_FORMAT_VORBIS_EXT, fileBuf,
309                          size, 44100 );
310            alSourcei( _musicSource, AL_BUFFER, _musicBuffers[0] );
311
312            alSourcePlay( _musicSource );
313        }
314        else
315        {
316            dprint( "audioPlayMusic - could not open %s\n", file );
317        }
318
319        if( fileBuf )
320            memFree( fileBuf );
321    }
322#endif
323}
324
325
326void audioStopMusic()
327{
328    if( _audioUp )
329    {
330        if( _musicSource )
331        {
332            alSourceStop( _musicSource );
333            alDeleteSources( 1, &_musicSource );
334            _musicSource = 0;
335        }
336    }
337}
338
339
340void audioSetSoundVolume( int v )
341{
342    alListenerf( AL_GAIN, ((ALfloat) v) / 256.0f );
343}
344
345
346void audioSetMusicVolume( int v )
347{
348    //ALfloat gain;
349    //alGetListenerfv( AL_GAIN, &gain );
350    _musicGain = ((ALfloat) v) / 256.0f;
351    if( _musicSource )
352        alSourcef( _musicSource, AL_GAIN, _musicGain );
353}
354
355
356//EOF
Note: See TracBrowser for help on using the browser.