eWavData Class Reference

#include <eSound.h>

Inheritance diagram for eWavData:

Inheritance graph
[legend]
Collaboration diagram for eWavData:

Collaboration graph
[legend]

List of all members.

Public Member Functions

 eWavData (const char *fileName, const char *alternative_file="")
 ~eWavData ()
void Load ()
void Unload ()
bool Mix (Uint8 *dest, Uint32 len, eAudioPos &pos, REAL rvol, REAL lvol, REAL speed=1, bool loop=false)
void Loop ()
 eWavData ()
 ~eWavData ()
 eWavData (const char *filename)
void LoadWavFile (const char *filename)
Mix_Chunk * GetWavData ()
void SetVolume (int newVolume)
int GetVolume ()

Static Public Member Functions

static void UnloadAll ()

Public Attributes

bool alt

Private Attributes

SDL_AudioSpec spec
Uint8 * data
Uint32 len
Uint32 samples
tString filename
tString filename_alt
bool freeData
Mix_Chunk * m_WavData
int m_Volume
bool m_Playable

Static Private Attributes

static eWavDatas_anchor = NULL


Detailed Description

Definition at line 54 of file eSound.h.


Constructor & Destructor Documentation

eWavData::eWavData ( const char *  fileName,
const char *  alternative_file = "" 
)

Definition at line 332 of file eSound.cpp.

References filename, and filename_alt.

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 }

eWavData::~eWavData (  ) 

Definition at line 487 of file eSound.cpp.

References Unload().

00487                    {
00488 #ifndef DEDICATED
00489     Unload();
00490 #endif
00491 }

Here is the call graph for this function:

eWavData::eWavData (  ) 

Definition at line 38 of file eChannelSDLMixer.cpp.

References m_WavData, and NULL.

00038                    :
00039         m_Volume(64), m_Playable(false)
00040 {
00041 #ifdef HAVE_LIBSDL_MIXER
00042     // Do nothing constructor
00043     m_WavData = NULL;
00044 #endif // DEDICATED
00045 }

eWavData::~eWavData (  ) 

eWavData::eWavData ( const char *  filename  ) 

Definition at line 55 of file eChannelSDLMixer.cpp.

00055                                        {
00056 #ifdef HAVE_LIBSDL_MIXER
00057     // Construct a new wavdata by loading a file
00058 #endif // DEDICATED
00059 }


Member Function Documentation

void eWavData::Load (  ) 

Definition at line 340 of file eSound.cpp.

References alt, con, tDirectories::Data(), data, filename, filename_alt, freeData, tPath::GetReadPath(), tString::Len(), len, malloc, samples, tOutput::SetTemplateParameter(), and spec.

Referenced by eSoundPlayer::eSoundPlayer(), eSoundPlayer::MakeGlobal(), and eSoundPlayer::Reset().

00340                    {
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 }

Here is the call graph for this function:

Here is the caller graph for this function:

void eWavData::Unload (  ) 

Definition at line 447 of file eSound.cpp.

References data, free, freeData, len, NULL, se_SoundLock(), and se_SoundUnlock().

Referenced by UnloadAll(), and ~eWavData().

00447                      {
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 }

Here is the call graph for this function:

Here is the caller graph for this function:

void eWavData::UnloadAll (  )  [static]

Definition at line 476 of file eSound.cpp.

References tListItem< T >::Next(), s_anchor, and Unload().

Referenced by se_SoundExit().

00476                         {
00477     //wavs.Add(this,id);
00478     eWavData* wav = s_anchor;
00479     while ( wav )
00480     {
00481         wav->Unload();
00482         wav = wav->Next();
00483     }
00484 
00485 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool eWavData::Mix ( Uint8 *  dest,
Uint32  len,
eAudioPos pos,
REAL  rvol,
REAL  lvol,
REAL  speed = 1,
bool  loop = false 
)

Definition at line 493 of file eSound.cpp.

References audio, d, data, eAudioPos::fraction, MAX_VAL, MIN_VAL, eAudioPos::pos, REAL, samples, spec, SPEED_FRACTION, VOL_FRACTION, and VOL_SHIFT.

Referenced by eSoundPlayer::Mix().

00494                                                             {
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 }

Here is the caller graph for this function:

void eWavData::Loop (  ) 

Definition at line 669 of file eSound.cpp.

References a, b, data, len, REAL, samples, spec, and tNEW.

00669                    {
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 }

void eWavData::LoadWavFile ( const char *  filename  ) 

Reimplemented in eWavDataSDLMixer.

Definition at line 61 of file eChannelSDLMixer.cpp.

References m_WavData, and tERR_WARN.

00061                                                {
00062 #ifdef HAVE_LIBSDL_MIXER
00063 #ifdef MACOSX
00064     // BUG: This call is very very slow on my system. Disable it until I figure out what is wrong. -- Dan
00065     return;
00066 #endif
00067 
00068     m_WavData = Mix_LoadWAV(filename);
00069 
00070     if(!m_WavData) {
00071         tERR_WARN("Couldn't load wav file\n");
00072     } else {
00073         //std::cout << "Successfully loaded sound effect: " << filename << "\n";
00074     }
00075 #endif // DEDICATED
00076 }

Mix_Chunk* eWavData::GetWavData (  )  [inline]

Reimplemented in eWavDataSDLMixer.

Definition at line 64 of file eChannel.h.

References m_WavData.

Referenced by eChannel::LoopSound(), and eChannel::PlaySound().

00065 { return m_WavData; };

Here is the caller graph for this function:

void eWavData::SetVolume ( int  newVolume  )  [inline]

Reimplemented in eWavDataSDLMixer.

Definition at line 66 of file eChannel.h.

00067 { m_Volume = newVolume; };

int eWavData::GetVolume (  )  [inline]

Reimplemented in eWavDataSDLMixer.

Definition at line 67 of file eChannel.h.

Referenced by eChannel::LoopSound(), and eChannel::PlaySound().

00067 { m_Volume = newVolume; };

Here is the caller graph for this function:


Member Data Documentation

SDL_AudioSpec eWavData::spec [private]

Definition at line 55 of file eSound.h.

Referenced by Load(), Loop(), and Mix().

Uint8* eWavData::data [private]

Definition at line 56 of file eSound.h.

Referenced by Load(), Loop(), Mix(), and Unload().

Uint32 eWavData::len [private]

Definition at line 57 of file eSound.h.

Referenced by Load(), Loop(), and Unload().

Uint32 eWavData::samples [private]

Definition at line 58 of file eSound.h.

Referenced by Load(), Loop(), and Mix().

tString eWavData::filename [private]

Definition at line 59 of file eSound.h.

Referenced by eWavData(), and Load().

tString eWavData::filename_alt [private]

Definition at line 60 of file eSound.h.

Referenced by eWavData(), and Load().

bool eWavData::freeData [private]

Definition at line 61 of file eSound.h.

Referenced by Load(), and Unload().

eWavData * eWavData::s_anchor = NULL [static, private]

Definition at line 63 of file eSound.h.

Referenced by UnloadAll().

bool eWavData::alt

Definition at line 66 of file eSound.h.

Referenced by Load().

Mix_Chunk* eWavData::m_WavData [private]

Reimplemented in eWavDataSDLMixer.

Definition at line 67 of file eChannel.h.

Referenced by eWavData(), GetWavData(), and LoadWavFile().

int eWavData::m_Volume [private]

Reimplemented in eWavDataSDLMixer.

Definition at line 71 of file eChannel.h.

bool eWavData::m_Playable [private]

Reimplemented in eWavDataSDLMixer.

Definition at line 72 of file eChannel.h.


The documentation for this class was generated from the following files:
Generated on Sat Mar 15 23:32:34 2008 for Armagetron Advanced by  doxygen 1.5.4