src/engine/eSound.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 *************************************************************************
00004 
00005 ArmageTron -- Just another Tron Lightcycle Game in 3D.
00006 Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
00007 
00008 **************************************************************************
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00023   
00024 ***************************************************************************
00025 
00026 */
00027 
00028 #include "eSound.h"
00029 #include "config.h"
00030 #include "tMemManager.h"
00031 #include "tDirectories.h"
00032 #include "tRandom.h"
00033 #include "tError.h"
00034 #include <string>
00035 #include "tConfiguration.h"
00036 #include "uMenu.h"
00037 #include "eCamera.h"
00038 //#include "tList.h"
00039 #include <iostream>
00040 #include <stdlib.h>
00041 #include "eGrid.h"
00042 #include "tException.h"
00043 
00044 //eGrid* eSoundPlayer::S_Grid = NULL;
00045 
00046 #ifdef WIN32
00047 #define HAVE_LIBSDL_MIXER 1
00048 #endif
00049 
00050 #ifndef DEDICATED
00051 #ifdef  HAVE_LIBSDL_MIXER
00052 #include <SDL_mixer.h>
00053 static Mix_Music* music = NULL;
00054 #endif
00055 
00056 static SDL_AudioSpec audio;
00057 static bool sound_is_there=false;
00058 static bool uses_sdl_mixer=false;
00059 #endif
00060 
00061 // sound quality
00062 
00063 #define SOUND_OFF 0
00064 #define SOUND_LOW 1
00065 #define SOUND_MED 2
00066 #define SOUND_HIGH 3
00067 
00068 #ifdef WIN32
00069 static int buffer_shift=1;
00070 #else
00071 static int buffer_shift=0;
00072 #endif
00073 
00074 static tConfItem<int> bs("SOUND_BUFFER_SHIFT",buffer_shift);
00075 
00076 int sound_quality=SOUND_MED;
00077 static tConfItem<int> sq("SOUND_QUALITY",sound_quality);
00078 
00079 static int sound_sources=10;
00080 static tConfItem<int> ss("SOUND_SOURCES",sound_sources);
00081 static REAL loudness_thresh=0;
00082 static int real_sound_sources=0;
00083 
00084 static tList<eSoundPlayer> se_globalPlayers;
00085 
00086 
00087 void fill_audio(void *udata, Uint8 *stream, int len)
00088 {
00089 #ifndef DEDICATED
00090     real_sound_sources=0;
00091     int i;
00092     if (eGrid::CurrentGrid())
00093         for(i=eGrid::CurrentGrid()->Cameras().Len()-1;i>=0;i--)
00094             eGrid::CurrentGrid()->Cameras()(i)->SoundMix(stream,len);
00095 
00096     for(i=se_globalPlayers.Len()-1;i>=0;i--)
00097         se_globalPlayers(i)->Mix(stream,len,0,1,1);
00098 
00099     if (real_sound_sources>sound_sources+4)
00100         loudness_thresh+=.01;
00101     if (real_sound_sources>sound_sources+1)
00102         loudness_thresh+=.001;
00103     if (real_sound_sources<sound_sources-4)
00104         loudness_thresh-=.001;
00105     if (real_sound_sources<sound_sources-1)
00106         loudness_thresh-=.0001;
00107     if (loudness_thresh<0)
00108         loudness_thresh=0;
00109 #endif
00110 }
00111 
00112 #ifndef DEDICATED
00113 #ifdef DEFAULT_SDL_AUDIODRIVER
00114 
00115 // stringification, yep, two levels required
00116 #define XSTRING(s) #s
00117 #define STRING(s) XSTRING(s)
00118 
00119 // call once to initialize SDL sound subsystem
00120 static bool se_SoundInitPrepare()
00121 {
00122     // initialize audio subsystem with predefined, hopefully good, driver
00123     if ( ! getenv("SDL_AUDIODRIVER") ) {
00124         char * arg = "SDL_AUDIODRIVER=" STRING(DEFAULT_SDL_AUDIODRIVER);
00125         putenv(arg);
00126 
00127         if ( SDL_InitSubSystem(SDL_INIT_AUDIO) >= 0 )
00128             return true;
00129 
00130         putenv("SDL_AUDIODRIVER=");
00131     }
00132 
00133     // if that fails, try what the user wanted
00134     return ( SDL_InitSubSystem(SDL_INIT_AUDIO) >= 0 );
00135 }
00136 #endif
00137 #endif
00138 
00139 void se_SoundInit()
00140 {
00141 #ifndef DEDICATED
00142     // save configuration file with sound disabled on first use so we don't try again
00143     bool needSave = false;
00144     static bool firstRun = true;
00145     if ( st_FirstUse )
00146     {
00147         needSave = true;
00148         int sound_quality_back = sound_quality;
00149         sound_quality = SOUND_OFF;
00150         st_SaveConfig();
00151         if ( firstRun )
00152             con << tOutput("$sound_firstinit");
00153         sound_quality=sound_quality_back;
00154     }
00155 
00156     if ( sound_quality != SOUND_OFF )
00157     {
00158 #ifdef DEFAULT_SDL_AUDIODRIVER
00159         static bool init = se_SoundInitPrepare();
00160         if ( !init )
00161             return;
00162 #endif
00163         if ( firstRun && !SDL_WasInit( SDL_INIT_AUDIO ) )
00164             return;
00165         firstRun = false;
00166     }
00167 
00168     if (!sound_is_there && sound_quality!=SOUND_OFF)
00169     {
00170         SDL_AudioSpec desired;
00171 
00172         switch (sound_quality)
00173         {
00174         case SOUND_LOW:
00175             desired.freq=11025; break;
00176         case SOUND_MED:
00177             desired.freq=22050; break;
00178         case SOUND_HIGH:
00179             desired.freq=44100; break;
00180         default:
00181             desired.freq=22050;
00182         }
00183 
00184         desired.format=AUDIO_S16SYS;
00185         desired.samples=128;
00186         while (desired.samples <= desired.freq >> (6-buffer_shift))
00187             desired.samples <<= 1;
00188         desired.channels = 2;
00189         desired.callback = fill_audio;
00190         desired.userdata = NULL;
00191 
00192 #ifdef HAVE_LIBSDL_MIXER
00193         uses_sdl_mixer=true;
00194 
00195         // init using SDL_Mixer
00196         sound_is_there=(Mix_OpenAudio(desired.freq, desired.format, desired.channels, desired.samples)>=0);
00197 
00198         if ( sound_is_there )
00199         {
00200             // query actual sound info
00201             audio = desired;
00202             int channels;
00203             Mix_QuerySpec( &audio.freq, &audio.format, &channels );
00204             audio.channels = channels;
00205 
00206             // register callback
00207             Mix_SetPostMix( &fill_audio, NULL );
00208 
00209             const tPath& vpath = tDirectories::Data();
00210             tString musFile = vpath.GetReadPath( "music/fire.xm" );
00211 
00212             music = Mix_LoadMUS( musFile );
00213 
00214             if ( music )
00215                 Mix_FadeInMusic( music, -1, 2000 );
00216 
00217         }
00218 #else
00219         // just use SDL to init sound
00220         uses_sdl_mixer=false;
00221         sound_is_there=(SDL_OpenAudio(&desired,&audio)>=0);
00222 #endif
00223         if (sound_is_there && (audio.format!=AUDIO_S16SYS || audio.channels!=2))
00224         {
00225             uses_sdl_mixer=false;
00226             se_SoundExit();
00227             // force emulation of 16 bit stereo; sadly, this cannot use SDL_Mixer :-(
00228             audio.format=AUDIO_S16SYS;
00229             audio.channels=2;
00230             sound_is_there=(SDL_OpenAudio(&audio,NULL)>=0);
00231             con << tOutput("$sound_error_no16bit");
00232         }
00233         if (!sound_is_there)
00234             con << tOutput("$sound_error_initfailed");
00235         else
00236         {
00237             //for(int i=wavs.Len()-1;i>=0;i--)
00238             //wavs(i)->Init();
00239 #ifdef DEBUG
00240             tOutput o;
00241             o.SetTemplateParameter(1,audio.freq);
00242             o.SetTemplateParameter(2,audio.samples);
00243             o << "$sound_inited";
00244             con << o;
00245 #endif
00246         }
00247     }
00248 
00249     // save sound settings, they appear to work
00250     if ( needSave )
00251     {
00252         st_SaveConfig();
00253     }
00254 #endif
00255 }
00256 
00257 void se_SoundExit(){
00258 #ifndef DEDICATED
00259     se_SoundLock();
00260 
00261     eWavData::UnloadAll();
00262     se_SoundPause(true);
00263 
00264     se_SoundUnlock();
00265 
00266     if (sound_is_there){
00267 #ifdef DEBUG
00268         con << tOutput("$sound_disabling");
00269 #endif
00270         //              se_SoundPause(false);
00271         //    for(int i=wavs.Len()-1;i>=0;i--)
00272         //wavs(i)->Exit();
00273 
00274 #ifdef HAVE_LIBSDL_MIXER
00275         if ( music )
00276         {
00277             if( Mix_PlayingMusic() )
00278             {
00279                 Mix_FadeOutMusic(100);
00280                 SDL_Delay(100);
00281             }
00282             Mix_FreeMusic( music );
00283             music = NULL;
00284         }
00285 
00286         se_SoundPause(true);
00287 
00288         if ( uses_sdl_mixer )
00289             Mix_CloseAudio();
00290         else
00291 #endif
00292             SDL_CloseAudio();
00293 
00294 #ifdef DEBUG
00295         con << tOutput("$sound_disabling_done");
00296 #endif
00297     }
00298     sound_is_there=false;
00299 #endif
00300 }
00301 
00302 #ifndef DEDICATED
00303 static unsigned int locks;
00304 #endif
00305 
00306 void se_SoundLock(){
00307 #ifndef DEDICATED
00308     if (!locks)
00309         SDL_LockAudio();
00310     locks++;
00311 #endif
00312 }
00313 
00314 void se_SoundUnlock(){
00315 #ifndef DEDICATED
00316     locks--;
00317     if (!locks)
00318         SDL_UnlockAudio();
00319 #endif
00320 }
00321 
00322 void se_SoundPause(bool p){
00323 #ifndef DEDICATED
00324     SDL_PauseAudio(p);
00325 #endif
00326 }
00327 
00328 // ***********************************************************
00329 
00330 eWavData* eWavData::s_anchor = NULL;
00331 
00332 eWavData::eWavData(const char * fileName,const char *alternative)
00333         :tListItem<eWavData>(s_anchor),data(NULL),len(0),freeData(false){
00334     //wavs.Add(this,id);
00335     filename     = fileName;
00336     filename_alt = alternative;
00337 
00338 }
00339 
00340 void eWavData::Load(){
00341     //wavs.Add(this,id);
00342 
00343     if (data)
00344         return;
00345 
00346 #ifndef DEDICATED
00347 
00348     static char const * errorName = "Sound Error";
00349 
00350     freeData = false;
00351 
00352     alt=false;
00353 
00354     const tPath& path = tDirectories::Data();
00355 
00356     SDL_AudioSpec *result=SDL_LoadWAV( path.GetReadPath( filename ) ,&spec,&data,&len);
00357     if (result!=&spec || !data){
00358         if (filename_alt.Len()>1){
00359             result=SDL_LoadWAV( path.GetReadPath( filename_alt ),&spec,&data,&len);
00360             if (result!=&spec || !data)
00361             {
00362                 tOutput err;
00363                 err.SetTemplateParameter(1, filename);
00364                 err << "$sound_error_filenotfound";
00365                 throw tGenericException(err, errorName);
00366             }
00367             else
00368                 alt=true;
00369         }
00370         else{
00371             result=SDL_LoadWAV( path.GetReadPath( "sound/expl.wav" ) ,&spec,&data,&len);
00372             if (result!=&spec || !data)
00373             {
00374                 tOutput err;
00375                 err.SetTemplateParameter(1, "sound/expl.waw");
00376                 err << "$sound_error_filenotfount";
00377                 throw tGenericException(err, errorName);
00378             }
00379             else
00380                 len=0;
00381         }
00382         /*
00383           tERR_ERROR("Sound file " << fileName << " not found. Have you called "
00384           "Armagetron from the right directory?"); */
00385     }
00386 
00387     if (spec.format==AUDIO_S16SYS)
00388         samples=len>>1;
00389     //  else if(spec.format==AUDIO_U8)
00390     //          samples=len;
00391     else
00392     {
00393         // prepare error message
00394         tOutput err;
00395         err.SetTemplateParameter(1, filename);
00396         err << "$sound_error_unsupported";
00397 
00398         // convert to 16 bit system format
00399         SDL_AudioCVT cvt;
00400         if ( -1 == SDL_BuildAudioCVT( &cvt, spec.format, spec.channels, spec.freq, AUDIO_S16SYS, spec.channels, spec.freq ) )
00401         {
00402             throw tGenericException(err, errorName);
00403         }
00404 
00405         cvt.buf=reinterpret_cast<Uint8 *>( malloc( len * cvt.len_mult ) );
00406         cvt.len=len;
00407         memcpy(cvt.buf, data, len);
00408         freeData = true;
00409 
00410 
00411         if ( -1 == SDL_ConvertAudio( &cvt ) )
00412         {
00413             throw tGenericException(err, errorName);
00414         }
00415 
00416         SDL_FreeWAV( data );
00417         data = cvt.buf;
00418         spec.format = AUDIO_S16SYS;
00419         len    = len * cvt.len_mult;
00420 
00421         samples = len >> 1;
00422     }
00423 
00424     samples/=spec.channels;
00425 
00426 #ifdef DEBUG
00427 #ifdef LINUX
00428     con << "Sound file " << filename << " loaded: ";
00429     switch (spec.format){
00430     case AUDIO_S16SYS: con << "16 bit "; break;
00431     case AUDIO_U8: con << "8 bit "; break;
00432     default: con << "unknown "; break;
00433     }
00434     if (spec.channels==2)
00435         con << "stereo ";
00436     else
00437         con << "mono ";
00438 
00439     con << "at " << spec.freq << " Hz,\n";
00440 
00441     con << samples << " samples in " << len << " bytes.\n";
00442 #endif
00443 #endif
00444 #endif
00445 }
00446 
00447 void eWavData::Unload(){
00448 #ifndef DEDICATED
00449     //wavs.Add(this,id);
00450     if (data){
00451         se_SoundLock();
00452         if ( freeData )
00453         {
00454 
00455             free(data);
00456 
00457         }
00458 
00459         else
00460 
00461         {
00462 
00463             SDL_FreeWAV(data);
00464 
00465         }
00466 
00467 
00468 
00469         data=NULL;
00470         len=0;
00471         se_SoundUnlock();
00472     }
00473 #endif
00474 }
00475 
00476 void eWavData::UnloadAll(){
00477     //wavs.Add(this,id);
00478     eWavData* wav = s_anchor;
00479     while ( wav )
00480     {
00481         wav->Unload();
00482         wav = wav->Next();
00483     }
00484 
00485 }
00486 
00487 eWavData::~eWavData(){
00488 #ifndef DEDICATED
00489     Unload();
00490 #endif
00491 }
00492 
00493 bool eWavData::Mix(Uint8 *dest,Uint32 playlen,eAudioPos &pos,
00494                    REAL Rvol,REAL Lvol,REAL Speed,bool loop){
00495 #ifndef DEDICATED
00496     if ( !data )
00497     {
00498         return false;
00499     }
00500 
00501     playlen/=4;
00502 
00503     //  Rvol *= 4;
00504     //  Lvol *= 4;
00505 
00506     const REAL thresh = .25;
00507 
00508     if ( Rvol > thresh )
00509     {
00510         Rvol = thresh;
00511     }
00512 
00513     if ( Lvol > thresh )
00514     {
00515         Lvol = thresh;
00516     }
00517 
00518 #define SPEED_FRACTION (1<<20)
00519 
00520 #define VOL_SHIFT 16
00521 #define VOL_FRACTION (1<<VOL_SHIFT)
00522 
00523 #define MAX_VAL ((1<<16)-1)
00524 #define MIN_VAL -(1<<16)
00525 
00526     // first, split the speed into the part before and after the decimal:
00527     if (Speed<0) Speed=0;
00528 
00529     // adjust for different sample rates:
00530     Speed*=spec.freq;
00531     Speed/=audio.freq;
00532 
00533     int speed=int(floor(Speed));
00534     int speed_fraction=int(SPEED_FRACTION*(Speed-speed));
00535 
00536     // secondly, make integers out of the volumes:
00537     int rvol=int(Rvol*VOL_FRACTION);
00538     int lvol=int(Lvol*VOL_FRACTION);
00539 
00540 
00541     bool goon=true;
00542 
00543     while (goon){
00544         if (spec.channels==2){
00545             if (spec.format==AUDIO_U8)
00546                 while (playlen>0 && pos.pos<samples){
00547                     // fix endian problems for the Mac port, as well as support for other
00548                     // formats than  stereo...
00549                     int l=((short *)dest)[0];
00550                     int r=((short *)dest)[1];
00551                     r += (rvol*(data[(pos.pos<<1)  ]-128)) >> (VOL_SHIFT-8);
00552                     l += (lvol*(data[(pos.pos<<1)+1]-128)) >> (VOL_SHIFT-8);
00553                     if (r>MAX_VAL) r=MAX_VAL;
00554                     if (l>MAX_VAL) l=MAX_VAL;
00555                     if (r<MIN_VAL) r=MIN_VAL;
00556                     if (l<MIN_VAL) l=MIN_VAL;
00557 
00558                     ((short *)dest)[0]=l;
00559                     ((short *)dest)[1]=r;
00560 
00561                     dest+=4;
00562 
00563                     pos.pos+=speed;
00564 
00565                     pos.fraction+=speed_fraction;
00566                     while (pos.fraction>=SPEED_FRACTION){
00567                         pos.fraction-=SPEED_FRACTION;
00568                         pos.pos++;
00569                     }
00570 
00571                     playlen--;
00572                 }
00573             else{
00574                 while (playlen>0 && pos.pos<samples){
00575                     int l=((short *)dest)[0];
00576                     int r=((short *)dest)[1];
00577                     r += (rvol*(((short *)data)[(pos.pos<<1)  ])) >> VOL_SHIFT;
00578                     l += (lvol*(((short *)data)[(pos.pos<<1)+1])) >> VOL_SHIFT;
00579                     if (r>MAX_VAL) r=MAX_VAL;
00580                     if (l>MAX_VAL) l=MAX_VAL;
00581                     if (r<MIN_VAL) r=MIN_VAL;
00582                     if (l<MIN_VAL) l=MIN_VAL;
00583 
00584                     ((short *)dest)[0]=l;
00585                     ((short *)dest)[1]=r;
00586 
00587                     dest+=4;
00588 
00589                     pos.pos+=speed;
00590 
00591                     pos.fraction+=speed_fraction;
00592                     while (pos.fraction>=SPEED_FRACTION){
00593                         pos.fraction-=SPEED_FRACTION;
00594                         pos.pos++;
00595                     }
00596                     playlen--;
00597                 }
00598             }
00599         }
00600         else{
00601             if (spec.format==AUDIO_U8){
00602                 while (playlen>0 && pos.pos<samples){
00603                     // fix endian problems for the Mac port, as well as support for other
00604                     // formats than  stereo...
00605                     int l=((short *)dest)[0];
00606                     int r=((short *)dest)[1];
00607                     int d=data[pos.pos]-128;
00608                     l += (lvol*d) >> (VOL_SHIFT-8);
00609                     r += (rvol*d) >> (VOL_SHIFT-8);
00610                     if (r>MAX_VAL) r=MAX_VAL;
00611                     if (l>MAX_VAL) l=MAX_VAL;
00612                     if (r<MIN_VAL) r=MIN_VAL;
00613                     if (l<MIN_VAL) l=MIN_VAL;
00614 
00615                     ((short *)dest)[0]=l;
00616                     ((short *)dest)[1]=r;
00617 
00618                     dest+=4;
00619 
00620                     pos.pos+=speed;
00621 
00622                     pos.fraction+=speed_fraction;
00623                     while (pos.fraction>=SPEED_FRACTION){
00624                         pos.fraction-=SPEED_FRACTION;
00625                         pos.pos++;
00626                     }
00627 
00628                     playlen--;
00629                 }
00630             }
00631             else
00632                 while (playlen>0 && pos.pos<samples){
00633                     int l=((short *)dest)[0];
00634                     int r=((short *)dest)[1];
00635                     int d=((short *)data)[pos.pos];
00636                     l += (lvol*d) >> VOL_SHIFT;
00637                     r += (rvol*d) >> VOL_SHIFT;
00638                     if (r>MAX_VAL) r=MAX_VAL;
00639                     if (l>MAX_VAL) l=MAX_VAL;
00640                     if (r<MIN_VAL) r=MIN_VAL;
00641                     if (l<MIN_VAL) l=MIN_VAL;
00642 
00643                     ((short *)dest)[0]=l;
00644                     ((short *)dest)[1]=r;
00645 
00646                     dest+=4;
00647 
00648                     pos.pos+=speed;
00649 
00650                     pos.fraction+=speed_fraction;
00651                     while (pos.fraction>=SPEED_FRACTION){
00652                         pos.fraction-=SPEED_FRACTION;
00653                         pos.pos++;
00654                     }
00655                     playlen--;
00656                 }
00657         }
00658 
00659         if (loop && pos.pos>=samples)
00660             pos.pos-=samples;
00661         else
00662             goon=false;
00663     }
00664 #endif
00665     return (playlen>0);
00666 
00667 }
00668 
00669 void eWavData::Loop(){
00670 #ifndef DEDICATED
00671     Uint8 *buff2=tNEW(Uint8) [len];
00672 
00673     if (buff2){
00674         memcpy(buff2,data,len);
00675         Uint32 samples;
00676 
00677         if (spec.format==AUDIO_U8){
00678             samples=len;
00679             for(int i=samples-1;i>=0;i--){
00680                 Uint32 j=i+((len>>2)<<1);
00681                 if (j>=len) j-=len;
00682 
00683                 REAL a=fabs(100*(j/REAL(samples)-.5));
00684                 if (a>1) a=1;
00685                 REAL b=1-a;
00686 
00687                 data[i]=int(a*buff2[i]+b*buff2[j]);
00688             }
00689         }
00690         else if (spec.format==AUDIO_S16SYS){
00691             samples=len>>1;
00692             for(int i=samples-1;i>=0;i--){
00693 
00694                 /*
00695                   REAL a=2*i/REAL(samples);
00696                   if (a>1) a=2-a;
00697                   REAL b=1-a;
00698                 */
00699 
00700 
00701                 Uint32 j=i+((samples>>2)<<1);
00702                 while (j>=samples) j-=samples;
00703 
00704                 REAL a=fabs(100*(j/REAL(samples)-.5));
00705                 if (a>1) a=1;
00706                 REAL b=1-a;
00707 
00708 
00709                 ((short *)data)[i]=int(a*((short *)buff2)[i]+b*((short *)buff2)[j]);
00710             }
00711         }
00712         delete[] buff2;
00713     }
00714 
00715 #endif
00716 }
00717 
00718 
00719 // ******************************************************************
00720 
00721 void eAudioPos::Reset(int randomize){
00722 #ifndef DEDICATED
00723     if (randomize){
00724         tRandomizer & randomizer = tRandomizer::GetInstance();
00725         fraction = randomizer.Get( SPEED_FRACTION );
00726         // fraction=int(SPEED_FRACTION*(rand()/float(RAND_MAX)));
00727         pos=randomizer.Get( randomize );
00728         // pos=int(randomize*(rand()/float(RAND_MAX)));
00729     }
00730     else
00731         fraction=pos=0;
00732 #endif
00733 }
00734 
00735 
00736 
00737 eSoundPlayer::eSoundPlayer(eWavData &w,bool l)
00738         :id(-1),wav(&w),loop(l){
00739     if (l)
00740         wav->Load();
00741 
00742     for(int i=MAX_VIEWERS-1;i>=0;i--)
00743         goon[i]=true;
00744 }
00745 
00746 eSoundPlayer::~eSoundPlayer(){}
00747 
00748 bool eSoundPlayer::Mix(Uint8 *dest,
00749                        Uint32 len,
00750                        int viewer,
00751                        REAL rvol,
00752                        REAL lvol,
00753                        REAL speed){
00754 
00755     if (goon[viewer]){
00756         if (rvol+lvol>loudness_thresh){
00757             real_sound_sources++;
00758             return goon[viewer]=!wav->Mix(dest,len,pos[viewer],rvol,lvol,speed,loop);
00759         }
00760         else
00761             return true;
00762     }
00763     else
00764         return false;
00765 }
00766 
00767 void eSoundPlayer::Reset(int randomize){
00768     wav->Load();
00769 
00770     for(int i=MAX_VIEWERS-1;i>=0;i--){
00771         pos[i].Reset(randomize);
00772         goon[i]=true;
00773     }
00774 }
00775 
00776 void eSoundPlayer::End(){
00777     for(int i=MAX_VIEWERS-1;i>=0;i--){
00778         goon[i]=false;
00779     }
00780 }
00781 
00782 
00783 void eSoundPlayer::MakeGlobal(){
00784     wav->Load();
00785 
00786     se_SoundLock();
00787     se_globalPlayers.Add(this,id);
00788     se_SoundUnlock();
00789 }
00790 
00791 
00792 // ***************************************************************
00793 
00794 uMenu Sound_menu("$sound_menu_text");
00795 
00796 static uMenuItemInt sources_men
00797 (&Sound_menu,"$sound_menu_sources_text",
00798  "$sound_menu_sources_help",
00799  sound_sources,2,20,2);
00800 
00801 static uMenuItemSelection<int> sq_men
00802 (&Sound_menu,"$sound_menu_quality_text",
00803  "$sound_menu_quality_help",
00804  sound_quality);
00805 
00806 
00807 static uSelectEntry<int> a(sq_men,
00808                            "$sound_menu_quality_off_text",
00809                            "$sound_menu_quality_off_help",
00810                            SOUND_OFF);
00811 static uSelectEntry<int> b(sq_men,
00812                            "$sound_menu_quality_low_text",
00813                            "$sound_menu_quality_low_help",
00814                            SOUND_LOW);
00815 static uSelectEntry<int> c(sq_men,
00816                            "$sound_menu_quality_medium_text",
00817                            "$sound_menu_quality_medium_help",
00818                            SOUND_MED);
00819 static uSelectEntry<int> d(sq_men,
00820                            "$sound_menu_quality_high_text",
00821                            "$sound_menu_quality_high_help",
00822                            SOUND_HIGH);
00823 
00824 static uMenuItemSelection<int> bm_men
00825 (&Sound_menu,
00826  "$sound_menu_buffer_text",
00827  "$sound_menu_buffer_help",
00828  buffer_shift);
00829 
00830 static uSelectEntry<int> ba(bm_men,
00831                             "$sound_menu_buffer_vsmall_text",
00832                             "$sound_menu_buffer_vsmall_help",
00833                             -2);
00834 
00835 static uSelectEntry<int> bb(bm_men,
00836                             "$sound_menu_buffer_small_text",
00837                             "$sound_menu_buffer_small_help",
00838                             -1);
00839 
00840 static uSelectEntry<int> bc(bm_men,
00841                             "$sound_menu_buffer_med_text",
00842                             "$sound_menu_buffer_med_help",
00843                             0);
00844 
00845 static uSelectEntry<int> bd(bm_men,
00846                             "$sound_menu_buffer_high_text",
00847                             "$sound_menu_buffer_high_help",
00848                             1);
00849 
00850 static uSelectEntry<int> be(bm_men,
00851                             "$sound_menu_buffer_vhigh_text",
00852                             "$sound_menu_buffer_vhigh_help",
00853                             2);
00854 
00855 
00856 void se_SoundMenu(){
00857     //  se_SoundPause(true);
00858     //  se_SoundLock();
00859     int oldsettings=sound_quality;
00860     int oldshift=buffer_shift;
00861     Sound_menu.Enter();
00862     if (oldsettings!=sound_quality || oldshift!=buffer_shift){
00863         se_SoundExit();
00864         se_SoundInit();
00865     }
00866     //  se_SoundUnlock();
00867     //  se_SoundPause(false);
00868 }
00869 

Generated on Sat Mar 15 22:55:47 2008 for Armagetron Advanced by  doxygen 1.5.4