#include <eSound.h>
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 eWavData * | s_anchor = NULL |
Definition at line 54 of file eSound.h.
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 }
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 }
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 }
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 }
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 }
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 }
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; };
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; };
SDL_AudioSpec eWavData::spec [private] |
Uint8* eWavData::data [private] |
Uint32 eWavData::len [private] |
Uint32 eWavData::samples [private] |
tString eWavData::filename [private] |
tString eWavData::filename_alt [private] |
bool eWavData::freeData [private] |
eWavData * eWavData::s_anchor = NULL [static, private] |
bool eWavData::alt |
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] |
bool eWavData::m_Playable [private] |