source: abuse/trunk/src/sdlport/sound.cpp @ 124

Last change on this file since 124 was 124, checked in by Sam Hocevar, 15 years ago
  • Get rid of ugly tabs and trailing spaces everywhere.
File size: 8.0 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 2001 Anthony Kruize <trandor@labyrinth.net.au>
4 *
5 *  This program is free software; you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation; either version 2 of the License, or
8 *  (at your option) any later version.
9 *
10 *  This program is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with this program; if not, write to the Free Software Foundation,
17 *  Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
18 */
19
20#include "config.h"
21
22#include <SDL.h>
23
24#include "sound.hpp"
25#include "jmalloc.hpp"
26#include "readwav.hpp"
27#include "specs.hpp"
28#include "setup.h"
29
30class effect_handle
31{
32public:
33    effect_handle    *prev;        // Handle to the previous effect
34    effect_handle    *next;        // Handle to the next effect
35    Uint8            *data;        // Audio data
36    Uint8            *pos;        // current playing position in the data
37    Uint32            length;        // Length of the data
38    Uint32            volume;        // Volume for this effect.
39
40    effect_handle( effect_handle *Next )
41    {
42        next = Next;
43        if( next )
44        {
45            next->prev = this;
46        }
47        prev = NULL;
48        data = NULL;
49        pos = NULL;
50    }
51
52    ~effect_handle()
53    {
54        if( next )
55        {
56            next->prev = prev;
57        }
58        if( prev )
59        {
60            prev->next = next;
61        }
62    }
63};
64
65static effect_handle * fx_list = NULL;
66extern flags_struct flags;
67static int sound_enabled = 0;
68static SDL_AudioSpec audioObtained;
69
70//
71// mix_audio
72//
73// Do the actual playing of the audio by looping through our effects list
74// and mixing each sample.
75//
76void mix_audio(void *udata, Uint8 *stream, int len)
77{
78    effect_handle *handle = fx_list;
79
80    while( handle )
81    {
82        if( handle->length > 0 && handle->pos )
83        {
84            len = ( len > (int)handle->length ? handle->length : len );
85            SDL_MixAudio( stream, handle->pos, len, handle->volume );
86            handle->pos += len;
87            handle->length -= len;
88            handle = handle->next;
89        }
90        else
91        {
92            // update the list pointer if we're deleting the first node
93            if( fx_list == handle )
94            {
95                fx_list = handle->next;
96            }
97            effect_handle *tmp = handle->next;
98            if( !flags.mono )
99            {
100                // delete the audio buffer
101                free( handle->data );
102            }
103            delete handle;
104            handle = tmp;
105        }
106    }
107}
108
109//
110// sound_init()
111// Initialise audio
112//
113int sound_init( int argc, char **argv )
114{
115    SDL_AudioSpec audioWanted;
116    char *sfxdir, *datadir;
117    FILE *fd = NULL;
118
119    // Disable sound if requested.
120    if( flags.nosound )
121    {
122        // User requested that sound be disabled
123        printf( "Sound : Disabled (-nosound)\n" );
124        return 0;
125    }
126
127    // Check for the sfx directory, disable sound if we can't find it.
128    datadir = get_filename_prefix();
129    sfxdir = (char *)jmalloc( strlen( datadir ) + 5 + 1, "sfxdir" );
130    sprintf( sfxdir, "%s/sfx/", datadir );
131    if( (fd = fopen( sfxdir,"r" )) == NULL )
132    {
133        // Didn't find the directory, so disable sound.
134        printf( "Sound : Disabled (couldn't find the sfx directory)\n" );
135        return 0;
136    }
137    jfree( sfxdir );
138
139    audioWanted.freq = 11025;
140    audioWanted.format = AUDIO_U8;
141    audioWanted.channels = 2 - flags.mono;
142    audioWanted.samples = 128;
143    audioWanted.callback = mix_audio;
144    audioWanted.userdata = NULL;
145
146    // Now open the audio device
147    if( SDL_OpenAudio( &audioWanted, &audioObtained ) < 0 )
148    {
149        printf( "Sound : Unable to open audio - %s\nSound : Disabled (error)\n", SDL_GetError() );
150        return 0;
151    }
152
153    sound_enabled = 1;
154    printf( "Sound : Enabled\n" );
155
156    SDL_PauseAudio( 0 );
157
158    // It's all good
159    return sound_enabled;
160}
161
162//
163// sound_uninit
164//
165// Shutdown audio and release any memory left over.
166//
167void sound_uninit()
168{
169    if( sound_enabled )
170    {
171        SDL_PauseAudio( 1 );
172        while( fx_list )
173        {
174            effect_handle *last = fx_list;
175            fx_list = fx_list->next;
176            jfree( last );
177        }
178        SDL_CloseAudio();
179    }
180}
181
182//
183// sound_effect constructor
184//
185// Read in the requested .wav file.
186//
187sound_effect::sound_effect( char * filename )
188{
189    if( sound_enabled )
190    {
191        long sample_speed;
192        data = (void *)read_wav( filename, sample_speed, size );
193    }
194}
195
196//
197// sound_effect destructor
198//
199// Release the audio data.
200//
201sound_effect::~sound_effect()
202{
203    if( sound_enabled )
204    {
205        if( data )
206        {
207            jfree( data );
208        }
209    }
210}
211
212//
213// sound_effect::play
214//
215// Insert a new effect_handle into the list and modify the audio
216// if we're doing stereo.
217// panpot defines the pan position for the sound effect.
218//   0   - Completely to the right.
219//   128 - Centered.
220//   255 - Completely to the left.
221//
222void sound_effect::play( int volume, int pitch, int panpot )
223{
224    if( sound_enabled )
225    {
226        SDL_LockAudio();
227
228        fx_list = new effect_handle( fx_list );
229        if( fx_list == NULL )
230        {
231            printf( "Sound : ERROR - Failed to create new effect.\n" );
232            SDL_UnlockAudio();
233            return;
234        }
235
236        if( !flags.mono )
237        {
238            unsigned int i;
239            Uint32 cvtBufferSize;
240            SDL_AudioCVT audiocvt;
241
242            // Do some audio conversion
243            SDL_BuildAudioCVT( &audiocvt, AUDIO_U8, 1, 11025, audioObtained.format, audioObtained.channels, audioObtained.freq );
244            audiocvt.buf = (Uint8 *)malloc( size * audiocvt.len_mult );
245            audiocvt.len = size;
246            memcpy( audiocvt.buf, data, size );
247            SDL_ConvertAudio( &audiocvt );
248            cvtBufferSize = (Uint32)((double)size * audiocvt.len_ratio);
249
250            // Adjust for requested pan position
251            if( panpot != 128 )
252            {
253                if( panpot > 128 )
254                {
255                    // Pan to the left
256                    panpot = (panpot - 255) * -1;
257                    for( i = 1 ; i <= cvtBufferSize; i += 2 )
258                    {
259                        audiocvt.buf[i] = (((audiocvt.buf[i] - 128) * panpot) / 128) + 128;
260                    }
261                }
262                else
263                {
264                    // Pan to the right
265                    for( i = 0 ; i < cvtBufferSize; i += 2 )
266                    {
267                        audiocvt.buf[i] = (((audiocvt.buf[i] - 128) * panpot) / 128) + 128;
268                    }
269                }
270            }
271
272            fx_list->data = audiocvt.buf;
273            fx_list->pos = audiocvt.buf;
274            fx_list->length = cvtBufferSize;
275            fx_list->volume = volume;
276        }
277        else
278        {
279            // Only doing mono so don't mess with the audio data.
280            fx_list->data = (Uint8 *)data;
281            fx_list->pos = (Uint8 *)data;
282            fx_list->length = size;
283            fx_list->volume = volume;
284        }
285        SDL_UnlockAudio();
286    }
287}
288
289
290//
291// We don't handle songs.  These are just stubs to basically do nothing.
292// I tried using SDL_mixer to do this, but with no success.
293//
294
295song::song( char const * filename )
296{
297    data = NULL;
298    Name = strcpy((char *)jmalloc( strlen( filename ) + 1, "song name" ), filename );
299    song_id = 0;
300}
301
302song::~song()
303{
304    if( playing() )
305    {
306        stop();
307    }
308    if( data )
309    {
310        jfree( data );
311    }
312    jfree( Name );
313}
314
315void song::play( unsigned char volume )
316{
317    song_id = 1;
318}
319
320void song::stop( long fadeout_time )
321{
322    song_id = 0;
323}
324
325int song::playing()
326{
327    return song_id;
328}
329
330void song::set_volume( int volume )
331{
332//    do nothing...
333}
Note: See TracBrowser for help on using the repository browser.