]> git.mxchange.org Git - simgear.git/blob - simgear/sound/soundmgr_openal.cxx
Add support for the MacOS variations of OpenAL.
[simgear.git] / simgear / sound / soundmgr_openal.cxx
1 // soundmgr.cxx -- Sound effect management class
2 //
3 // Sound manager initially written by David Findlay
4 // <david_j_findlay@yahoo.com.au> 2001
5 //
6 // C++-ified by Curtis Olson, started March 2001.
7 //
8 // Copyright (C) 2001  Curtis L. Olson - curt@flightgear.org
9 //
10 // This program is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU General Public License as
12 // published by the Free Software Foundation; either version 2 of the
13 // License, or (at your option) any later version.
14 //
15 // This program is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 // General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 //
24 // $Id$
25
26 #include <iostream>
27
28 #if defined(__APPLE__)
29 # include <OpenAL/al.h>
30 # include <OpenAL/alut.h>
31 # include <OpenAL/alc.h>
32 #else
33 # include <AL/al.h>
34 # include <AL/alut.h>
35 # include <AL/alc.h>
36 #endif
37
38 #include <simgear/debug/logstream.hxx>
39 #include <simgear/misc/sg_path.hxx>
40
41 #include "soundmgr_openal.hxx"
42
43
44 //
45 // Sound Manager
46 //
47
48 // constructor
49 SGSoundMgr::SGSoundMgr() {
50
51     SG_LOG( SG_GENERAL, SG_ALERT, "Initializing OpenAL sound manager" );
52
53     // initialize OpenAL
54     alutInit( 0, NULL );
55     alGetError();
56     if ( alGetError() == AL_NO_ERROR) {
57         working = true;
58     } else {
59         working = false;
60         SG_LOG( SG_GENERAL, SG_ALERT, "Audio initialization failed!" );
61     }
62
63     listener_pos[0] = 0.0;
64     listener_pos[1] = 0.0;
65     listener_pos[2] = 0.0;
66
67     listener_vel[0] = 0.0;
68     listener_vel[1] = 0.0;
69     listener_vel[2] = 0.0;
70     
71     listener_ori[0] = 0.0;
72     listener_ori[1] = 0.0;
73     listener_ori[2] = -1.0;
74     listener_ori[3] = 0.0;
75     listener_ori[4] = 1.0;
76     listener_ori[5] = 0.0;
77
78     alListenerfv( AL_POSITION, listener_pos );
79     alListenerfv( AL_VELOCITY, listener_vel );
80     alListenerfv( AL_ORIENTATION, listener_ori );
81     alGetError();
82     if ( alGetError() != AL_NO_ERROR) {
83         SG_LOG( SG_GENERAL, SG_ALERT,
84                 "Oops AL error after audio initialization!" );
85     }
86 }
87
88 // destructor
89
90 SGSoundMgr::~SGSoundMgr() {
91
92     //
93     // Remove the samples from the sample manager.
94     //
95     sample_map_iterator sample_current = samples.begin();
96     sample_map_iterator sample_end = samples.end();
97     for ( ; sample_current != sample_end; ++sample_current ) {
98         SGSoundSample *sample = sample_current->second;
99         delete sample;
100     }
101
102     alutExit();
103 }
104
105
106 // initialize the sound manager
107 void SGSoundMgr::init() {
108     //
109     // Remove the samples from the sample manager.
110     //
111     sample_map_iterator sample_current = samples.begin();
112     sample_map_iterator sample_end = samples.end();
113     for ( ; sample_current != sample_end; ++sample_current ) {
114         SGSoundSample *sample = sample_current->second;
115         delete sample;
116     }
117     samples.clear();
118 }
119
120
121 void SGSoundMgr::bind ()
122 {
123     // no properties
124 }
125
126
127 void SGSoundMgr::unbind ()
128 {
129     // no properties
130 }
131
132
133 // run the audio scheduler
134 void SGSoundMgr::update( double dt ) {
135 }
136
137
138 void
139 SGSoundMgr::pause ()
140 {
141     ALCcontext *pCurContext = alcGetCurrentContext();
142     alcSuspendContext( pCurContext );
143     if ( alGetError() != AL_NO_ERROR) {
144         SG_LOG( SG_GENERAL, SG_ALERT,
145                 "Oops AL error after soundmgr pause()!" );
146     }
147 }
148
149
150 void
151 SGSoundMgr::resume ()
152 {
153     ALCcontext *pCurContext = alcGetCurrentContext();
154     alcProcessContext( pCurContext );
155     if ( alGetError() != AL_NO_ERROR) {
156         SG_LOG( SG_GENERAL, SG_ALERT,
157                 "Oops AL error after soundmgr resume()!" );
158     }
159 }
160
161
162 // add a sound effect, return true if successful
163 bool SGSoundMgr::add( SGSoundSample *sound, const string& refname ) {
164
165     sample_map_iterator sample_it = samples.find( refname );
166     if ( sample_it != samples.end() ) {
167         // sound already exists
168         return false;
169     }
170
171     samples[refname] = sound;
172
173     return true;
174 }
175
176
177 // remove a sound effect, return true if successful
178 bool SGSoundMgr::remove( const string &refname ) {
179
180     sample_map_iterator sample_it = samples.find( refname );
181     if ( sample_it != samples.end() ) {
182         // first stop the sound from playing (so we don't bomb the
183         // audio scheduler)
184         SGSoundSample *sample = sample_it->second;
185         delete sample;
186         samples.erase( sample_it );
187
188         // cout << "sndmgr: removed -> " << refname << endl;
189         return true;
190     } else {
191         // cout << "sndmgr: failed remove -> " << refname << endl;
192         return false;
193     }
194 }
195
196
197 // return true of the specified sound exists in the sound manager system
198 bool SGSoundMgr::exists( const string &refname ) {
199     sample_map_iterator sample_it = samples.find( refname );
200     if ( sample_it != samples.end() ) {
201         return true;
202     } else {
203         return false;
204     }
205 }
206
207
208 // return a pointer to the SGSoundSample if the specified sound exists
209 // in the sound manager system, otherwise return NULL
210 SGSoundSample *SGSoundMgr::find( const string &refname ) {
211     sample_map_iterator sample_it = samples.find( refname );
212     if ( sample_it != samples.end() ) {
213         return sample_it->second;
214     } else {
215         return NULL;
216     }
217 }
218
219
220 // tell the scheduler to play the indexed sample in a continuous
221 // loop
222 bool SGSoundMgr::play_looped( const string &refname ) {
223     SGSoundSample *sample;
224
225     if ( (sample = find( refname )) == NULL ) {
226         return false;
227     } else {
228         sample->play( true );
229         return true;
230     }
231 }
232
233
234 // tell the scheduler to play the indexed sample once
235 bool SGSoundMgr::play_once( const string& refname ) {
236     SGSoundSample *sample;
237
238     if ( (sample = find( refname )) == NULL ) {
239         return false;
240     } else {
241         sample->play( false );
242         return true;
243     }
244 }
245
246
247 // return true of the specified sound is currently being played
248 bool SGSoundMgr::is_playing( const string& refname ) {
249     SGSoundSample *sample;
250
251     if ( (sample = find( refname )) == NULL ) {
252         return false;
253     } else {
254         return ( sample->is_playing() );
255     }
256 }
257
258
259 // immediate stop playing the sound
260 bool SGSoundMgr::stop( const string& refname ) {
261     SGSoundSample *sample;
262
263     if ( (sample = find( refname )) == NULL ) {
264         return false;
265     } else {
266         sample->stop();
267         return true;
268     }
269 }