TORCS  1.3.10
The Open Racing Car Simulator
Loading...
Searching...
No Matches
SoundInterface.h
Go to the documentation of this file.
1// -*- Mode: c++ -*-
2/***************************************************************************
3 file : SoundInterface.h
4 created : Tue Apr 5 19:57:35 CEST 2005
5 copyright : (C) 2005-2024 Christos Dimitrakakis, Bernhard Wymann
6 email : berniw@bluewin.ch
7
8***************************************************************************/
9
10/***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18
19#ifndef SOUND_INTERFACE_H
20#define SOUND_INTERFACE_H
21
22#define USE_OPENAL 1
23
24#undef SOUND_LOG
25
26
27#ifdef SOUND_LOG
28#define logmsg printf ("# "); printf
29#else
30#define logmsg empty_log
31static void empty_log(const char* s, ...)
32{
33}
34#endif
35
36
37
38#include <plib/sl.h>
39#include <plib/sg.h>
40#include <raceman.h>
41#include <vector>
42
43#include "TorcsSound.h"
44//#include "grsound.h"
45#include "QSoundChar.h"
46
47
48#define VOLUME_CUTOFF 0.001f
49
50
51class CarSoundData;
52
69
74
76typedef struct SoundPri_ {
77 float a;
78 int id;
80
83 protected:
102
103 std::vector<TorcsSound*> sound_list;
105
115
118 QueueSoundMap* smap,
119 int n_cars);
120
125 QueueSoundMap* smap);
126
127 public:
130
132 virtual ~SoundInterface() {}
133
135 virtual void setNCars(int n_cars) = 0;
136
138 virtual TorcsSound* addSample (const char* filename,
139 int flags = (ACTIVE_VOLUME|ACTIVE_PITCH),
140 bool loop = false, bool static_pool = true) = 0;
141
143 virtual void initSharedSourcePool() {}
144
145 void setSkidSound (const char* sound_name)
146 {
147 for (int i=0; i<4; i++) {
148 TorcsSound* sound = addSample (sound_name, ACTIVE_VOLUME|ACTIVE_PITCH, true);
149 skid_sound[i] = sound;
150 }
151
152 }
153 void setRoadRideSound (const char* sound_name)
154 {
155 TorcsSound* sound = addSample (sound_name, ACTIVE_VOLUME|ACTIVE_PITCH, true);
156 road_ride_sound = sound;
157 }
158 void setGrassRideSound (const char* sound_name)
159 {
160 TorcsSound* sound = addSample (sound_name, ACTIVE_VOLUME|ACTIVE_PITCH, true);
161 grass_ride_sound = sound;
162 }
163 void setCurbRideSound (const char* sound_name)
164 {
165 TorcsSound* sound = addSample (sound_name, ACTIVE_VOLUME|ACTIVE_PITCH, true);
166 curb_ride_sound = sound;
167 }
168 void setGrassSkidSound (const char* sound_name)
169 {
170 TorcsSound* sound = addSample (sound_name, ACTIVE_VOLUME|ACTIVE_PITCH, true);
171 grass_skid_sound = sound;
172 }
173 void setMetalSkidSound (const char* sound_name)
174 {
175 TorcsSound* sound = addSample (sound_name, ACTIVE_VOLUME|ACTIVE_PITCH, true);
176 metal_skid_sound = sound;
177 }
178 void setAxleSound (const char* sound_name)
179 {
180 TorcsSound* sound = addSample (sound_name, ACTIVE_VOLUME|ACTIVE_PITCH, true);
181 axle_sound = sound;
182 }
183 void setTurboSound (const char* sound_name)
184 {
185 TorcsSound* sound = addSample (sound_name, ACTIVE_VOLUME|ACTIVE_PITCH, true);
186 turbo_sound = sound;
187 }
188 void setBackfireLoopSound (const char* sound_name)
189 {
190 TorcsSound* sound = addSample (sound_name, ACTIVE_VOLUME|ACTIVE_PITCH, true);
191 backfire_loop_sound = sound;
192 }
193 void setCrashSound (const char* sound_name, int index)
194 {
195 TorcsSound* sound = addSample (sound_name, 0, false);
196 assert (index>=0 && index<NB_CRASH_SOUND);
197 crash_sound[index] = sound;
198 }
199
200 void setBangSound (const char* sound_name)
201 {
202 TorcsSound* sound = addSample (sound_name, 0, false);
203 bang_sound = sound;
204 }
205
206 void setBottomCrashSound (const char* sound_name)
207 {
208 TorcsSound* sound = addSample (sound_name, 0, false);
209 bottom_crash_sound = sound;
210 }
211
212 void setBackfireSound (const char* sound_name)
213 {
214 TorcsSound* sound = addSample (sound_name, 0, false);
215 backfire_sound = sound;
216 }
217
218 void setGearChangeSound (const char* sound_name)
219 {
220 TorcsSound* sound = addSample (sound_name, 0, false);
221 gear_change_sound = sound;
222 }
223
225 int n_cars, sgVec3 p_obs, sgVec3 u_obs,
226 sgVec3 c_obs = NULL, sgVec3 a_obs = NULL)
227 {
228 // do nothing
229 }
230
231 virtual void muteForMenu() {}
232 virtual float getGlobalGain() {return 1.0f;}
233 virtual void setGlobalGain(float g)
234 {
235 fprintf (stderr, "Warning, gain setting not supported\n");
236 }
237
238};
239
240
241
244 typedef struct SoundChar_ {
245 float f; //frequency modulation
246 float a; //amplitude modulation
248 protected:
249 slScheduler* sched;
250 std::vector<TorcsSound*> sound_list;
254 void DopplerShift (SoundChar* sound, float* p_src, float* u_src, float* p, float* u);
257 public:
259 virtual ~PlibSoundInterface();
260 virtual void setNCars(int n_cars);
261 virtual slScheduler* getScheduler();
262 virtual TorcsSound* addSample (const char* filename, int flags = (ACTIVE_VOLUME|ACTIVE_PITCH), bool loop = false, bool static_pool = true);
263 virtual void update(CarSoundData** car_sound_data, int n_cars, sgVec3 p_obs, sgVec3 u_obs, sgVec3 c_obs = NULL, sgVec3 a_obs = NULL);
264 virtual float getGlobalGain() {return global_gain;}
265 virtual void setGlobalGain(float g)
266 {
267 global_gain = 0.5f*g;
268 logmsg ("Setting gain to %f\n", global_gain);
269 }
270
271};
272
273
274
276
277class SharedSourcePool;
278
280 typedef struct SoundChar_ {
281 float f; //frequency modulation
282 float a; //amplitude modulation
284 protected:
287 ALCcontext* cc;
288 ALCdevice* dev;
295 static const int OSI_MIN_DYNAMIC_SOURCES;
296
297 void DopplerShift (SoundChar* sound, float* p_src, float* u_src, float* p, float* u);
299
300 public:
302 virtual ~OpenalSoundInterface();
303 virtual void setNCars(int n_cars);
304 virtual TorcsSound* addSample (const char* filename,
305 int flags = (ACTIVE_VOLUME|ACTIVE_PITCH),
306 bool loop = false, bool static_pool = true);
307 virtual void update(CarSoundData** car_sound_data, int n_cars, sgVec3 p_obs, sgVec3 u_obs, sgVec3 c_obs, sgVec3 a_obs);
308 virtual void muteForMenu();
309 virtual float getGlobalGain() { return global_gain; }
310 virtual void initSharedSourcePool();
311 virtual void setGlobalGain(float g)
312 {
313 global_gain = 0.5f*g;
314 logmsg ("Setting gain to %f\n", global_gain);
315 }
316 virtual bool getStaticSource(ALuint *source);
317
318 virtual SharedSourcePool* getSourcePool(void) { return sourcepool; }
319
320
321};
322
323
324int sortSndPriority(const void* a, const void* b);
325
326
332
333
335 public:
338 int i;
339 for (i = 0; i < nbsources; i++) {
340 pool[i].currentOwner = NULL;
341 pool[i].in_use = false;
342 alGenSources(1, &(pool[i].source));
343 int error = alGetError();
344 if (error != AL_NO_ERROR) {
345 printf("OpenAL error, allocating dynamic source index %d\n", i);
346 this->nbsources = i;
347 break;
348 }
349 }
350 printf(" Dynamic Sources: requested: %d, created: %d\n", nbsources, this->nbsources);
351 }
352
354 int i;
355 for (i = 0; i < nbsources; i++) {
356 alDeleteSources(1, &(pool[i].source));
357 alGetError();
358 }
359 delete [] pool;
360 }
361
362 bool getSource(TorcsSound* sound, ALuint* source, bool* needs_init, int* index) {
363 if (*index >= 0 && *index < nbsources) {
364 if (sound == pool[*index].currentOwner) {
365 // Resurrect source from pool.
366 *source = pool[*index].source;
367 *needs_init = false;
368 pool[*index].in_use = true;
369 return true;
370 }
371 }
372
373 // TODO: Implement free list with ring buffer or whatever data structure
374 // to go from O(n) to O(1). If the ordering is done well it will automatically
375 // result in LRU (least recently used).
376 int i, firstfree = -1;
377 for (i = 0; i < nbsources; i++) {
378 if (pool[i].in_use == false && firstfree < 0) {
379 firstfree = i;
380 break;
381 }
382 }
383
384 if (firstfree < 0) {
385 // No free source.
386 return false;
387 }
388
389 pool[firstfree].currentOwner = sound;
390 pool[firstfree].in_use = true;
391 *source = pool[firstfree].source;
392 *needs_init = true;
393 *index = firstfree;
394 return true;
395 }
396
397 bool releaseSource(TorcsSound* sound, int* index) {
398 if (*index >= 0 && *index < nbsources) {
399 if (sound == pool[*index].currentOwner) {
400 pool[*index].in_use = false;
401 return true;
402 }
403 }
404 return false;
405 }
406
407 bool isSourceActive(TorcsSound* sound, int* index) {
408 if (*index >= 0 && *index < nbsources &&
409 sound == pool[*index].currentOwner &&
410 true == pool[*index].in_use)
411 {
412 return true;
413 } else {
414 return false;
415 }
416 }
417
418 int getNbSources(void) { return nbsources; }
419
420 protected:
423};
424
425
426
427#endif /* SOUND_INTERFACE_H */
static Point p[4]
Definition Convex.cpp:54
struct QSoundChar_ QSoundChar
struct QueueSoundMap_ QueueSoundMap
A queue containing mappings between sounds and sound sources.
int sortSndPriority(const void *a, const void *b)
SoundPriState
Current state of sound.
@ Stopped
@ Playing
@ Paused
@ None
@ Cleared
@ Loaded
struct SoundPri_ SoundPri
Sound priority, used to sort cars according to amplitude attenuation.
static void empty_log(const char *s,...)
#define logmsg
Manages the source sound of each individual car.
virtual void setGlobalGain(float g)
SoundSource tyre_src[4]
virtual TorcsSound * addSample(const char *filename, int flags=(ACTIVE_VOLUME|ACTIVE_PITCH), bool loop=false, bool static_pool=true)
virtual void setNCars(int n_cars)
void DopplerShift(SoundChar *sound, float *p_src, float *u_src, float *p, float *u)
struct OpenalSoundInterface::SoundChar_ SoundChar
static const int OSI_MIN_DYNAMIC_SOURCES
Define this to use the OpenAL Doppler.
virtual float getGlobalGain()
OpenalSoundInterface(float sampling_rate, int n_channels)
virtual SharedSourcePool * getSourcePool(void)
virtual void SetMaxSoundCar(CarSoundData **car_sound_data, QueueSoundMap *smap)
virtual bool getStaticSource(ALuint *source)
SharedSourcePool * sourcepool
virtual void update(CarSoundData **car_sound_data, int n_cars, sgVec3 p_obs, sgVec3 u_obs, sgVec3 c_obs, sgVec3 a_obs)
virtual TorcsSound * addSample(const char *filename, int flags=(ACTIVE_VOLUME|ACTIVE_PITCH), bool loop=false, bool static_pool=true)
virtual void setGlobalGain(float g)
virtual slScheduler * getScheduler()
void SetMaxSoundCar(CarSoundData **car_sound_data, QueueSoundMap *smap)
slScheduler * sched
PlibSoundInterface(float sampling_rate, int n_channels)
void DopplerShift(SoundChar *sound, float *p_src, float *u_src, float *p, float *u)
SoundSource * car_src
virtual void setNCars(int n_cars)
std::vector< TorcsSound * > sound_list
virtual void update(CarSoundData **car_sound_data, int n_cars, sgVec3 p_obs, sgVec3 u_obs, sgVec3 c_obs=NULL, sgVec3 a_obs=NULL)
struct PlibSoundInterface::SoundChar_ SoundChar
virtual float getGlobalGain()
SoundSource tyre_src[4]
bool releaseSource(TorcsSound *sound, int *index)
sharedSource * pool
SharedSourcePool(int nbsources)
bool getSource(TorcsSound *sound, ALuint *source, bool *needs_init, int *index)
bool isSourceActive(TorcsSound *sound, int *index)
virtual ~SharedSourcePool()
SoundInterface(float sampling_rate, int n_channels)
Make a new sound interface.
TorcsSound * turbo_sound
turbo spinning sound
virtual void setNCars(int n_cars)=0
Set the number of cars - must be defined in children classes.
void setGrassRideSound(const char *sound_name)
void setBangSound(const char *sound_name)
void setBottomCrashSound(const char *sound_name)
QueueSoundMap turbo
QueueSoundMap backfire_loop
void SortSingleQueue(CarSoundData **car_sound_data, QueueSoundMap *smap, int n_cars)
Find the max amplitude sound in car_sound_data and put it in smap.
void setCrashSound(const char *sound_name, int index)
TorcsSound * metal_skid_sound
metal skidding on metal
TorcsSound * backfire_loop_sound
exhaust backfire sound
void setCurbRideSound(const char *sound_name)
void setSkidSound(const char *sound_name)
TorcsSound * grass_skid_sound
skidding on dirt/grass
TorcsSound * axle_sound
axle/gear spinning sound
TorcsSound * skid_sound[4]
set of skid sounds, one per tyre
void SetMaxSoundCar(CarSoundData **car_sound_data, QueueSoundMap *smap)
Using the smap->id, get the appropriate entry in car_sound_data and call apprioriate methods for smap...
void setGearChangeSound(const char *sound_name)
QueueSoundMap metal_skid
TorcsSound * grass_ride_sound
rolling on dirt/grass
virtual void muteForMenu()
TorcsSound * backfire_sound
one-off backfire sound
QueueSoundMap road
The following are mappings for sound prioritisation.
virtual void setGlobalGain(float g)
void setTurboSound(const char *sound_name)
QueueSoundMap axle
TorcsSound * curb_ride_sound
rolling on curb
QueueSoundMap grass
virtual void update(CarSoundData **car_sound_data, int n_cars, sgVec3 p_obs, sgVec3 u_obs, sgVec3 c_obs=NULL, sgVec3 a_obs=NULL)
Update sound for a given observer.
float sampling_rate
sampling rate
virtual void initSharedSourcePool()
initialised the pool of shared sources
TorcsSound * crash_sound[NB_CRASH_SOUND]
list of crash sounds
TorcsSound * road_ride_sound
rolling on normal road
int n_channels
number of channels
void setGrassSkidSound(const char *sound_name)
void setAxleSound(const char *sound_name)
std::vector< TorcsSound * > sound_list
keeps track of sounds used
virtual TorcsSound * addSample(const char *filename, int flags=(ACTIVE_VOLUME|ACTIVE_PITCH), bool loop=false, bool static_pool=true)=0
Add a new sample - must be defined in children classes.
void setBackfireSound(const char *sound_name)
TorcsSound * gear_change_sound
sound when changing gears
void setMetalSkidSound(const char *sound_name)
virtual float getGlobalGain()
TorcsSound * bottom_crash_sound
bang when crashing from a great height
QueueSoundMap grass_skid
int n_engine_sounds
number of simultaneous engines
QueueSoundMap curb
void setBackfireLoopSound(const char *sound_name)
virtual ~SoundInterface()
Destructor - does nothing.
void setRoadRideSound(const char *sound_name)
int curCrashSnd
holds current crash sound used - the sound cycles
SoundPri * engpri
the engine priority, used for sorting
TorcsSound * bang_sound
sounds when suspension fully compressed
Sound source management.
Definition TorcsSound.h:141
A generic TORCS sound.
Definition TorcsSound.h:53
static CarSoundData ** car_sound_data
Definition grsound.cpp:38
#define ACTIVE_PITCH
#define NB_CRASH_SOUND
#define ACTIVE_VOLUME
A queue containing mappings between sounds and sound sources.
float max_vol
Max.
int id
The id of the car producing the sound, used for retrieving doppler effects etc.
QSoundChar CarSoundData::* schar
The calculated sound characteristic.
TorcsSound * snd
The raw sound.
Sound priority, used to sort cars according to amplitude attenuation.
int id
car ID.
float a
amplitude
TorcsSound * currentOwner