00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "sound.h"
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 void SOUNDMANAGER::Init()
00420 {
00421 if (disabled)
00422 return;
00423
00424 if (!init)
00425 {
00426 alutInit(NULL, 0);
00427 alGetError();
00428
00429 alDopplerFactor (0.002);
00430 alDistanceModel (AL_INVERSE_DISTANCE);
00431
00432 VERTEX p;
00433 SetListenerPos(p);
00434 SetListenerVel(p);
00435 VERTEX u;
00436 u.y = 1;
00437 p.z = -1;
00438 SetListenerOrientation(p, u);
00439
00440 init = true;
00441 }
00442 }
00443
00444 void SOUNDMANAGER::Deinit()
00445 {
00446 if (disabled)
00447 return;
00448
00449 if (init)
00450 {
00451 Unload();
00452
00453
00454 mSoundContext = alcGetCurrentContext();
00455 mSoundDevice = alcGetContextsDevice( mSoundContext );
00456 alcDestroyContext( mSoundContext );
00457 if ( mSoundDevice)
00458 alcCloseDevice( mSoundDevice );
00459
00460 alutExit();
00461
00462 init = false;
00463 }
00464 }
00465
00466 void SOUNDMANAGER::Load()
00467 {
00468 if (disabled)
00469 return;
00470
00471 if (!loaded)
00472 {
00473 buffers.clear();
00474 sources.clear();
00475
00476
00477 string car_name;
00478 settings.Get( "game.selected_car", car_name );
00479 LoadSoundFile(settings.GetFullDataPath("sounds/tire_squeal.wav"));
00480 LoadSoundFile(settings.GetFullDataPath("cars/"+car_name+"/engine.wav"));
00481
00482 loaded = true;
00483 }
00484 }
00485
00486 void SOUNDMANAGER::Unload()
00487 {
00488 if (disabled)
00489 return;
00490
00491 if (loaded)
00492 {
00493 for (map <string, ALuint>::iterator i = buffers.begin(); i != buffers.end(); i++)
00494 {
00495 #ifdef SOUND_DEBUG
00496 cout << "Deleted sound " << i->first << " from buffer " << i->second << endl;
00497 #endif
00498 alDeleteBuffers(1, &(i->second));
00499 }
00500
00501 for (vector <ALuint>::iterator i = sources.begin(); i != sources.end(); i++)
00502 {
00503 alDeleteSources(1, &(*(i)));
00504 }
00505
00506 buffers.clear();
00507 sources.clear();
00508
00509 loaded = false;
00510 }
00511 }
00512
00513 void SOUNDMANAGER::Reload()
00514 {
00515 if (disabled)
00516 return;
00517
00518 Unload();
00519 Load();
00520 }
00521
00522 void SOUNDMANAGER::LoadSoundFile(string filename)
00523 {
00524 if (disabled)
00525 return;
00526
00527 if (buffers.find(filename) != buffers.end())
00528 {
00529 cout << "sound file already loaded: " << filename << endl;
00530 return;
00531 }
00532
00533 ALenum format;
00534 ALsizei size;
00535 ALvoid* data = 0;
00536 ALsizei freq;
00537 bool error = 0;
00538
00539 #ifdef __BIG_ENDIAN__
00540 alutLoadWAVFile((ALbyte*)(filename).c_str(), &format, &data, &size, &freq);
00541 #else
00542 ALboolean loop;
00543 error= LoadWave(filename.c_str(), &format, &data, &size, &freq, &loop);
00544 #endif
00545
00546 if (data && !error)
00547 {
00548 ALuint newbuf;
00549 alGenBuffers(1, &newbuf);
00550 #ifdef __BIG_ENDIAN__
00551 alBufferData(newbuf, format, data, size, freq);
00552 alutUnloadWAV(format, data, size, freq);
00553 #else
00554 alBufferData(newbuf, format, data, size, (int)freq);
00555 UnloadWave(data);
00556 #endif
00557 buffers[filename] = newbuf;
00558
00559 #ifdef SOUND_DEBUG
00560 cout << "Loaded sound " << filename << " into buffer " << newbuf << endl;
00561 #endif
00562 }
00563 else
00564 {
00565 cerr << "Error loading sound file: " << filename << "\n";
00566 if (!disabled)
00567 {
00568 cerr << "Disabling sound." << endl;
00569 disabled = true;
00570 }
00571 }
00572 }
00573
00574 void SOUNDMANAGER::SetPosVel(int sid, VERTEX coord, VERTEX tvel)
00575 {
00576 if (disabled)
00577 return;
00578
00579 SetPos(sid, coord);
00580 SetVel(sid, tvel);
00581 }
00582
00583 void SOUNDMANAGER::SetListener(VERTEX campos, VERTEX camvel, VERTEX at, VERTEX up)
00584 {
00585 if (disabled)
00586 return;
00587
00588 SetListenerPos(campos);
00589 SetListenerVel(camvel);
00590 SetListenerOrientation(at, up);
00591 }
00592
00593 void SOUNDMANAGER::SetPitch(int sid, float pitch)
00594 {
00595 if (disabled)
00596 return;
00597
00598
00599
00600 alSourcef (sources[sid], AL_PITCH, pitch);
00601 }
00602
00603 void SOUNDMANAGER::SetGain(int sid, float gain)
00604 {
00605 if (disabled)
00606 return;
00607
00608 if (!loaded)
00609 {
00610
00611 return;
00612 }
00613
00614 gain *= master_volume;
00615
00616 alSourcef (sources[sid], AL_MAX_GAIN, gain);
00617 alSourcef (sources[sid], AL_GAIN, gain);
00618 }
00619
00620 void SOUNDMANAGER::SetPos(int sid, VERTEX pos)
00621 {
00622 if (disabled)
00623 return;
00624
00625 pos.Scale(DISTANCE_FACTOR);
00626
00627 if (alIsSource(sources[sid]))
00628 {
00629 alSourcefv(sources[sid], AL_POSITION, pos.v3());
00630 }
00631 else
00632 {
00633 }
00634 }
00635
00636 void SOUNDMANAGER::SetVel(int sid, VERTEX vel)
00637 {
00638 if (disabled)
00639 return;
00640
00641 vel.Scale(VELOCITY_FACTOR);
00642 if (alIsSource(sources[sid]))
00643 alSourcefv(sources[sid], AL_VELOCITY, vel.v3());
00644 }
00645
00646 void SOUNDMANAGER::StopSource(int sid)
00647 {
00648 if (disabled || !loaded)
00649 return;
00650
00651 alSourceStop(sources[sid]);
00652 alDeleteSources(1, &sources[sid]);
00653 source_free[sid] = true;
00654 }
00655
00656 void SOUNDMANAGER::PlaySource(int idx)
00657 {
00658 if (disabled || !loaded)
00659 return;
00660
00661 alSourcePlay(sources[idx]);
00662 }
00663
00664 ALuint SOUNDMANAGER::NewSource(string buffername)
00665 {
00666 bool error;
00667 return NewSource(buffername, error);
00668 }
00669
00670 ALuint SOUNDMANAGER::NewSource(string buffername, bool & error)
00671 {
00672 if (disabled)
00673 return 0;
00674
00675 if (!loaded)
00676 {
00677
00678 error = true;
00679 return 0;
00680 }
00681
00682 if (sources.size() > MAX_SOURCES)
00683 {
00684 cout << "Out of sound sources, can't create new source for buffer " << buffername << " (" << sources.size() << ")" << endl;
00685 error = true;
00686 return 0;
00687 }
00688
00689 map <string, ALuint>::iterator sbuf = buffers.find(buffername);
00690 if (sbuf == buffers.end())
00691 {
00692 cout << "Can't find buffer " << buffername << endl;
00693 error = true;
00694 return 0;
00695 }
00696
00697 ALuint newsource;
00698 alGenSources(1, &newsource);
00699
00700 ALfloat SourcePos[] = { 0.0, 0.0, 0.0 };
00701 ALfloat SourceVel[] = { 0.0, 0.0, 0.0 };
00702
00703 alSourcei (newsource, AL_BUFFER, sbuf->second );
00704 alSourcef (newsource, AL_PITCH, 1.0 );
00705 alSourcef (newsource, AL_GAIN, 1.0 );
00706 alSourcefv(newsource, AL_POSITION, SourcePos);
00707 alSourcefv(newsource, AL_VELOCITY, SourceVel);
00708 alSourcei (newsource, AL_LOOPING, AL_TRUE );
00709
00710
00711 int i = sources.size();
00712 sources.push_back(newsource);
00713
00714 SetGain(i, 1.0);
00715
00716 PlaySource(i);
00717
00718 error = false;
00719
00720 return i;
00721 }
00722
00723 void SOUNDMANAGER::SetListenerVel(VERTEX vel)
00724 {
00725 if (disabled)
00726 return;
00727
00728 vel.Scale(VELOCITY_FACTOR);
00729 alListenerfv(AL_VELOCITY, vel.v3());
00730 }
00731
00732 void SOUNDMANAGER::SetListenerPos(VERTEX pos)
00733 {
00734 if (disabled)
00735 return;
00736
00737 pos.Scale(DISTANCE_FACTOR);
00738 alListenerfv(AL_POSITION, pos.v3());
00739 }
00740
00741 void SOUNDMANAGER::SetListenerOrientation(VERTEX at, VERTEX up)
00742 {
00743 if (disabled)
00744 return;
00745
00746 float f[6];
00747 f[0] = at.x;
00748 f[1] = at.y;
00749 f[2] = at.z;
00750 f[3] = up.x;
00751 f[4] = up.y;
00752 f[5] = up.z;
00753
00754 alListenerfv(AL_ORIENTATION, f);
00755 }
00756
00757 void SOUNDMANAGER::MuteAll()
00758 {
00759 if (disabled)
00760 return;
00761
00762 unsigned int i;
00763 for (i = 0; i < sources.size(); i++)
00764 {
00765 SetGain(i, 0.0f);
00766 }
00767 }
00768
00769 void SOUNDMANAGER::UnMuteAll()
00770 {
00771
00772 }
00773
00774 bool SOUNDMANAGER::LoadWave(string fname, ALenum *format, ALvoid **data, ALsizei *size,
00775 ALsizei *freq, ALboolean *loop)
00776 {
00777 FILE *fp;
00778
00779 bool err = false;
00780
00781 fp = fopen(fname.c_str(),"rb");
00782 if (fp)
00783 {
00784 ALbyte id[4], *sound_buffer;
00785
00786 ALint fsize;
00787
00788 ALshort format_tag;
00789 ALushort channels, block_align, bits_per_sample;
00790
00791 ALint format_length;
00792 ALuint sample_rate, avg_bytes_sec;
00793 ALint data_size;
00794 fsize = 0;
00795 fread(id, sizeof(ALbyte), 4, fp);
00796
00797 if (IDMatchesString((char*) id, "RIFF"))
00798 {
00799 fread(&fsize, sizeof(ALint), 1, fp);
00800 fread(id, sizeof(ALbyte), 4, fp);
00801
00802 if (IDMatchesString((char*)id,"WAVE"))
00803 {
00804 fread(id, sizeof(ALbyte), 4, fp);
00805 fread(&format_length, sizeof(ALint),1,fp);
00806 fread(&format_tag, sizeof(ALshort), 1, fp);
00807
00808 fread(&channels, sizeof(ALshort),1,fp);
00809 fread(&sample_rate, sizeof(ALint), 1, fp);
00810 fread(&avg_bytes_sec, sizeof(ALint), 1, fp);
00811 fread(&block_align, sizeof(ALshort), 1, fp);
00812 fread(&bits_per_sample, sizeof(ALshort), 1, fp);
00813
00814
00815 bool found_data_chunk = false;
00816 long filepos = format_length + 4 + 4 + 4 + 4 + 4;
00817 int chunknum = 0;
00818 while (!found_data_chunk && chunknum < 10)
00819 {
00820 #ifdef SOUND_DEBUG
00821 cout << "seeking to " << filepos << endl;
00822 #endif
00823 fseek(fp, filepos, SEEK_SET);
00824 fread(id, sizeof(ALbyte), 4, fp);
00825 fread(&data_size, sizeof(ALbyte), 4, fp);
00826 if (IDMatchesString((char*)id, "data"))
00827 {
00828 found_data_chunk = true;
00829 #ifdef SOUND_DEBUG
00830 cout << "Found data chunk at " << filepos << ", chunk " << chunknum << endl;
00831 #endif
00832 }
00833 else
00834 {
00835 #ifdef SOUND_DEBUG
00836 cout << "Chunk isn't data at " << filepos << ", chunk " << chunknum << endl;
00837 #endif
00838 filepos += data_size + 4 + 4;
00839 }
00840
00841 chunknum++;
00842 }
00843
00844 if (chunknum >= 10)
00845 {
00846 cerr << "Error: Wave file contains more than 10 chunks before the data chunk: " << fname << endl;
00847 *data = NULL;
00848 return false;
00849 }
00850
00851
00852 #ifdef SOUND_DEBUG
00853 cout << "Loading sound " << fname << ": filesize " << fsize << ", " << data_size << " samples" << endl;
00854 #endif
00855 sound_buffer = new ALbyte[data_size];
00856 fread(sound_buffer, sizeof(ALbyte), data_size, fp);
00857
00858 *data = sound_buffer;
00859 if (bits_per_sample == 16 && channels == 2)
00860 *format = AL_FORMAT_STEREO16;
00861 else if (bits_per_sample == 8 && channels == 2)
00862 *format = AL_FORMAT_STEREO8;
00863 else if (bits_per_sample == 16 && channels == 1)
00864 *format = AL_FORMAT_MONO16;
00865 else if (bits_per_sample == 8 && channels == 1)
00866 *format = AL_FORMAT_MONO8;
00867 else
00868 {
00869 cerr << "Error: unknown bits per sample and channels in file: " << fname << endl;
00870 cerr << channels << " channels" << endl;
00871 cerr << bits_per_sample << " bits per sample" << endl;
00872 }
00873
00874 *size = data_size;
00875 *freq = sample_rate;
00876 #ifdef SOUND_DEBUG
00877 cout << channels << " channels" << endl;
00878 cout << bits_per_sample << " bits per sample" << endl;
00879 cout << sample_rate << " Hz sample rate" << endl;
00880
00881 #endif
00882 }
00883 else
00884 {
00885 cerr << "Error: RIFF file but not a wave file: " << fname << endl;
00886 err = true;
00887 *data = NULL;
00888 }
00889 }
00890 else
00891 {
00892 cerr << "Error: not a RIFF file: " << fname << endl;
00893 err = true;
00894 *data = NULL;
00895 }
00896 }
00897 else
00898 {
00899 cerr << "Can't find sound file: " << fname << endl;
00900 err = true;
00901 *data = NULL;
00902 }
00903
00904 return err;
00905 }
00906
00907 void SOUNDMANAGER::UnloadWave(ALvoid* data)
00908 {
00909 delete [] (ALbyte*)data;
00910 }
00911
00912 bool SOUNDMANAGER::IDMatchesString(const char * id, const char * str)
00913 {
00914 bool match = true;
00915 for (unsigned int i = 0; i < strlen(str); i++)
00916 {
00917 if (id[i] != str[i])
00918 match = false;
00919 }
00920 return match;
00921 }