aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llaudio/audioengine_fmod.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llaudio/audioengine_fmod.cpp271
1 files changed, 91 insertions, 180 deletions
diff --git a/linden/indra/llaudio/audioengine_fmod.cpp b/linden/indra/llaudio/audioengine_fmod.cpp
index 16d820c..354ef95 100644
--- a/linden/indra/llaudio/audioengine_fmod.cpp
+++ b/linden/indra/llaudio/audioengine_fmod.cpp
@@ -1,7 +1,6 @@
1/** 1/**
2 * @file audioengine_fmod.cpp 2 * @file audioengine_fmod.cpp
3 * @brief Implementation of LLAudioEngine class abstracting the audio 3 * @brief Implementation of LLAudioEngine class abstracting the audio support as a FMOD 3D implementation
4 * support as a FMOD 3D implementation
5 * 4 *
6 * $LicenseInfo:firstyear=2002&license=viewergpl$ 5 * $LicenseInfo:firstyear=2002&license=viewergpl$
7 * 6 *
@@ -46,27 +45,12 @@
46 45
47#include "sound_ids.h" 46#include "sound_ids.h"
48 47
48extern "C" {
49 void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata);
50}
49 51
50void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata);
51FSOUND_DSPUNIT *gWindDSP = NULL; 52FSOUND_DSPUNIT *gWindDSP = NULL;
52 53
53// These globals for the wind filter. Blech!
54F64 gbuf0 = 0.0;
55F64 gbuf1 = 0.0;
56F64 gbuf2 = 0.0;
57F64 gbuf3 = 0.0;
58F64 gbuf4 = 0.0;
59F64 gbuf5 = 0.0;
60F64 gY0 = 0.0;
61F64 gY1 = 0.0;
62
63F32 gTargetGain = 0.f;
64F32 gCurrentGain = 0.f;
65F32 gTargetFreq = 100.f;
66F32 gCurrentFreq = 100.f;
67F32 gTargetPanGainR = 0.5f;
68F32 gCurrentPanGainR = 0.5f;
69
70 54
71// Safe strcpy 55// Safe strcpy
72#if 0 //(unused) //LL_WINDOWS || LL_LINUX 56#if 0 //(unused) //LL_WINDOWS || LL_LINUX
@@ -94,9 +78,10 @@ static size_t strlcpy( char* dest, const char* src, size_t dst_size )
94 78
95LLAudioEngine_FMOD::LLAudioEngine_FMOD() 79LLAudioEngine_FMOD::LLAudioEngine_FMOD()
96{ 80{
97 mInited = FALSE; 81 mInited = false;
98 mCurrentInternetStreamp = NULL; 82 mCurrentInternetStreamp = NULL;
99 mInternetStreamChannel = -1; 83 mInternetStreamChannel = -1;
84 mWindGen = NULL;
100} 85}
101 86
102 87
@@ -105,7 +90,7 @@ LLAudioEngine_FMOD::~LLAudioEngine_FMOD()
105} 90}
106 91
107 92
108BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) 93bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
109{ 94{
110 mFadeIn = -10000; 95 mFadeIn = -10000;
111 96
@@ -124,7 +109,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
124 { 109 {
125 LL_WARNS("AppInit") << "Error : You are using the wrong FMOD version (" << version 110 LL_WARNS("AppInit") << "Error : You are using the wrong FMOD version (" << version
126 << ")! You should be using FMOD " << FMOD_VERSION << LL_ENDL; 111 << ")! You should be using FMOD " << FMOD_VERSION << LL_ENDL;
127 //return FALSE; 112 //return false;
128 } 113 }
129 114
130 U32 fmod_flags = 0x0; 115 U32 fmod_flags = 0x0;
@@ -139,7 +124,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
139 { 124 {
140 LL_WARNS("AppInit") << "Error setting FMOD window: " 125 LL_WARNS("AppInit") << "Error setting FMOD window: "
141 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; 126 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
142 return FALSE; 127 return false;
143 } 128 }
144 // Play audio when we don't have focus. 129 // Play audio when we don't have focus.
145 // (For example, IM client on top of us.) 130 // (For example, IM client on top of us.)
@@ -167,7 +152,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
167 // on top of ALSA is ironically more reliable than raw ALSA. 152 // on top of ALSA is ironically more reliable than raw ALSA.
168 // Ack, and ESD has more reliable failure modes - but has worse 153 // Ack, and ESD has more reliable failure modes - but has worse
169 // latency - than all of them, so wins for now. 154 // latency - than all of them, so wins for now.
170 BOOL audio_ok = FALSE; 155 bool audio_ok = false;
171 156
172 if (!audio_ok) 157 if (!audio_ok)
173 if (NULL == getenv("LL_BAD_ESD")) /*Flawfinder: ignore*/ 158 if (NULL == getenv("LL_BAD_ESD")) /*Flawfinder: ignore*/
@@ -178,7 +163,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
178 { 163 {
179 LL_DEBUGS("AppInit") << "ESD audio output initialized OKAY" 164 LL_DEBUGS("AppInit") << "ESD audio output initialized OKAY"
180 << LL_ENDL; 165 << LL_ENDL;
181 audio_ok = TRUE; 166 audio_ok = true;
182 } else { 167 } else {
183 LL_WARNS("AppInit") << "ESD audio output FAILED to initialize: " 168 LL_WARNS("AppInit") << "ESD audio output FAILED to initialize: "
184 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; 169 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
@@ -195,7 +180,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
195 FSOUND_Init(44100, num_channels, fmod_flags)) 180 FSOUND_Init(44100, num_channels, fmod_flags))
196 { 181 {
197 LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL; 182 LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL;
198 audio_ok = TRUE; 183 audio_ok = true;
199 } else { 184 } else {
200 LL_WARNS("AppInit") << "OSS audio output FAILED to initialize: " 185 LL_WARNS("AppInit") << "OSS audio output FAILED to initialize: "
201 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; 186 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
@@ -212,7 +197,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
212 FSOUND_Init(44100, num_channels, fmod_flags)) 197 FSOUND_Init(44100, num_channels, fmod_flags))
213 { 198 {
214 LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL; 199 LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
215 audio_ok = TRUE; 200 audio_ok = true;
216 } else { 201 } else {
217 LL_WARNS("AppInit") << "ALSA audio output FAILED to initialize: " 202 LL_WARNS("AppInit") << "ALSA audio output FAILED to initialize: "
218 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; 203 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
@@ -224,7 +209,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
224 if (!audio_ok) 209 if (!audio_ok)
225 { 210 {
226 LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL; 211 LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL;
227 return FALSE; 212 return false;
228 } 213 }
229 214
230 // On Linux, FMOD causes a SIGPIPE for some netstream error 215 // On Linux, FMOD causes a SIGPIPE for some netstream error
@@ -250,7 +235,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
250 { 235 {
251 LL_WARNS("AppInit") << "Error initializing FMOD: " 236 LL_WARNS("AppInit") << "Error initializing FMOD: "
252 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; 237 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
253 return FALSE; 238 return false;
254 } 239 }
255 240
256#endif 241#endif
@@ -259,17 +244,9 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
259 244
260 LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() FMOD initialized correctly" << LL_ENDL; 245 LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() FMOD initialized correctly" << LL_ENDL;
261 246
262 mInited = TRUE; 247 mInited = true;
263 248
264 return TRUE; 249 return true;
265}
266
267
268void LLAudioEngine_FMOD::idle(F32 max_decode_time)
269{
270 LLAudioEngine::idle(max_decode_time);
271
272 updateInternetStream();
273} 250}
274 251
275 252
@@ -287,7 +264,7 @@ void LLAudioEngine_FMOD::shutdown()
287{ 264{
288 if (gWindDSP) 265 if (gWindDSP)
289 { 266 {
290 FSOUND_DSP_SetActive(gWindDSP,FALSE); 267 FSOUND_DSP_SetActive(gWindDSP,false);
291 FSOUND_DSP_Free(gWindDSP); 268 FSOUND_DSP_Free(gWindDSP);
292 } 269 }
293 270
@@ -318,13 +295,15 @@ LLAudioChannel *LLAudioEngine_FMOD::createChannel()
318 295
319void LLAudioEngine_FMOD::initWind() 296void LLAudioEngine_FMOD::initWind()
320{ 297{
298 mWindGen = new LLWindGen<MIXBUFFERFORMAT>;
299
321 if (!gWindDSP) 300 if (!gWindDSP)
322 { 301 {
323 gWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, NULL); 302 gWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, mWindGen);
324 } 303 }
325 if (gWindDSP) 304 if (gWindDSP)
326 { 305 {
327 FSOUND_DSP_SetActive(gWindDSP, TRUE); 306 FSOUND_DSP_SetActive(gWindDSP, true);
328 } 307 }
329 mNextWindUpdate = 0.0; 308 mNextWindUpdate = 0.0;
330} 309}
@@ -334,10 +313,13 @@ void LLAudioEngine_FMOD::cleanupWind()
334{ 313{
335 if (gWindDSP) 314 if (gWindDSP)
336 { 315 {
337 FSOUND_DSP_SetActive(gWindDSP, FALSE); 316 FSOUND_DSP_SetActive(gWindDSP, false);
338 FSOUND_DSP_Free(gWindDSP); 317 FSOUND_DSP_Free(gWindDSP);
339 gWindDSP = NULL; 318 gWindDSP = NULL;
340 } 319 }
320
321 delete mWindGen;
322 mWindGen = NULL;
341} 323}
342 324
343 325
@@ -367,9 +349,9 @@ void LLAudioEngine_FMOD::updateWind(LLVector3 wind_vec, F32 camera_height_above_
367 pitch = 1.0 + mapWindVecToPitch(wind_vec); 349 pitch = 1.0 + mapWindVecToPitch(wind_vec);
368 center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0)); 350 center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
369 351
370 gTargetFreq = (F32)center_freq; 352 mWindGen->mTargetFreq = (F32)center_freq;
371 gTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; 353 mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
372 gTargetPanGainR = (F32)mapWindVecToPan(wind_vec); 354 mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
373 } 355 }
374} 356}
375 357
@@ -457,11 +439,11 @@ LLAudioChannelFMOD::~LLAudioChannelFMOD()
457} 439}
458 440
459 441
460BOOL LLAudioChannelFMOD::updateBuffer() 442bool LLAudioChannelFMOD::updateBuffer()
461{ 443{
462 if (LLAudioChannel::updateBuffer()) 444 if (LLAudioChannel::updateBuffer())
463 { 445 {
464 // Base class update returned TRUE, which means that we need to actually 446 // Base class update returned true, which means that we need to actually
465 // set up the channel for a different buffer. 447 // set up the channel for a different buffer.
466 448
467 LLAudioBufferFMOD *bufferp = (LLAudioBufferFMOD *)mCurrentSourcep->getCurrentBuffer(); 449 LLAudioBufferFMOD *bufferp = (LLAudioBufferFMOD *)mCurrentSourcep->getCurrentBuffer();
@@ -473,13 +455,13 @@ BOOL LLAudioChannelFMOD::updateBuffer()
473 // This is bad, there should ALWAYS be a sample associated with a legit 455 // This is bad, there should ALWAYS be a sample associated with a legit
474 // buffer. 456 // buffer.
475 llerrs << "No FMOD sample!" << llendl; 457 llerrs << "No FMOD sample!" << llendl;
476 return FALSE; 458 return false;
477 } 459 }
478 460
479 461
480 // Actually play the sound. Start it off paused so we can do all the necessary 462 // Actually play the sound. Start it off paused so we can do all the necessary
481 // setup. 463 // setup.
482 mChannelID = FSOUND_PlaySoundEx(FSOUND_FREE, samplep, FSOUND_DSP_GetSFXUnit(), TRUE); 464 mChannelID = FSOUND_PlaySoundEx(FSOUND_FREE, samplep, FSOUND_DSP_GetSFXUnit(), true);
483 465
484 //llinfos << "Setting up channel " << std::hex << mChannelID << std::dec << llendl; 466 //llinfos << "Setting up channel " << std::hex << mChannelID << std::dec << llendl;
485 } 467 }
@@ -501,7 +483,7 @@ BOOL LLAudioChannelFMOD::updateBuffer()
501 } 483 }
502 } 484 }
503 485
504 return TRUE; 486 return true;
505} 487}
506 488
507 489
@@ -524,12 +506,12 @@ void LLAudioChannelFMOD::update3DPosition()
524 if (mCurrentSourcep->isAmbient()) 506 if (mCurrentSourcep->isAmbient())
525 { 507 {
526 // Ambient sound, don't need to do any positional updates. 508 // Ambient sound, don't need to do any positional updates.
527 bufferp->set3DMode(FALSE); 509 bufferp->set3DMode(false);
528 } 510 }
529 else 511 else
530 { 512 {
531 // Localized sound. Update the position and velocity of the sound. 513 // Localized sound. Update the position and velocity of the sound.
532 bufferp->set3DMode(TRUE); 514 bufferp->set3DMode(true);
533 515
534 LLVector3 float_pos; 516 LLVector3 float_pos;
535 float_pos.setVec(mCurrentSourcep->getPositionGlobal()); 517 float_pos.setVec(mCurrentSourcep->getPositionGlobal());
@@ -556,7 +538,7 @@ void LLAudioChannelFMOD::updateLoop()
556 U32 cur_pos = FSOUND_GetCurrentPosition(mChannelID); 538 U32 cur_pos = FSOUND_GetCurrentPosition(mChannelID);
557 if (cur_pos < (U32)mLastSamplePos) 539 if (cur_pos < (U32)mLastSamplePos)
558 { 540 {
559 mLoopedThisFrame = TRUE; 541 mLoopedThisFrame = true;
560 } 542 }
561 mLastSamplePos = cur_pos; 543 mLastSamplePos = cur_pos;
562} 544}
@@ -589,11 +571,11 @@ void LLAudioChannelFMOD::play()
589 return; 571 return;
590 } 572 }
591 573
592 if (!FSOUND_SetPaused(mChannelID, FALSE)) 574 if (!FSOUND_SetPaused(mChannelID, false))
593 { 575 {
594 llwarns << "LLAudioChannelFMOD::play error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl; 576 llwarns << "LLAudioChannelFMOD::play error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
595 } 577 }
596 getSource()->setPlayedOnce(TRUE); 578 getSource()->setPlayedOnce(true);
597} 579}
598 580
599 581
@@ -618,11 +600,11 @@ void LLAudioChannelFMOD::playSynced(LLAudioChannel *channelp)
618} 600}
619 601
620 602
621BOOL LLAudioChannelFMOD::isPlaying() 603bool LLAudioChannelFMOD::isPlaying()
622{ 604{
623 if (!mChannelID) 605 if (!mChannelID)
624 { 606 {
625 return FALSE; 607 return false;
626 } 608 }
627 609
628 return FSOUND_IsPlaying(mChannelID) && (!FSOUND_GetPaused(mChannelID)); 610 return FSOUND_IsPlaying(mChannelID) && (!FSOUND_GetPaused(mChannelID));
@@ -652,14 +634,14 @@ LLAudioBufferFMOD::~LLAudioBufferFMOD()
652} 634}
653 635
654 636
655BOOL LLAudioBufferFMOD::loadWAV(const std::string& filename) 637bool LLAudioBufferFMOD::loadWAV(const std::string& filename)
656{ 638{
657 // Try to open a wav file from disk. This will eventually go away, as we don't 639 // Try to open a wav file from disk. This will eventually go away, as we don't
658 // really want to block doing this. 640 // really want to block doing this.
659 if (filename.empty()) 641 if (filename.empty())
660 { 642 {
661 // invalid filename, abort. 643 // invalid filename, abort.
662 return FALSE; 644 return false;
663 } 645 }
664 646
665 S32 file_size = 0; 647 S32 file_size = 0;
@@ -667,7 +649,7 @@ BOOL LLAudioBufferFMOD::loadWAV(const std::string& filename)
667 if (!apr_file) 649 if (!apr_file)
668 { 650 {
669 // File not found, abort. 651 // File not found, abort.
670 return FALSE; 652 return false;
671 } 653 }
672 apr_file_close(apr_file); 654 apr_file_close(apr_file);
673 655
@@ -717,11 +699,11 @@ BOOL LLAudioBufferFMOD::loadWAV(const std::string& filename)
717 // 699 //
718 // file is probably corrupt - remove it. 700 // file is probably corrupt - remove it.
719 LLFile::remove(filename); 701 LLFile::remove(filename);
720 return FALSE; 702 return false;
721 } 703 }
722 704
723 // Everything went well, return TRUE 705 // Everything went well, return true
724 return TRUE; 706 return true;
725} 707}
726 708
727 709
@@ -736,7 +718,7 @@ U32 LLAudioBufferFMOD::getLength()
736} 718}
737 719
738 720
739void LLAudioBufferFMOD::set3DMode(BOOL use3d) 721void LLAudioBufferFMOD::set3DMode(bool use3d)
740{ 722{
741 U16 current_mode = FSOUND_Sample_GetMode(mSamplep); 723 U16 current_mode = FSOUND_Sample_GetMode(mSamplep);
742 724
@@ -765,7 +747,7 @@ void LLAudioEngine_FMOD::initInternetStream()
765{ 747{
766 // Number of milliseconds of audio to buffer for the audio card. 748 // Number of milliseconds of audio to buffer for the audio card.
767 // Must be larger than the usual Second Life frame stutter time. 749 // Must be larger than the usual Second Life frame stutter time.
768 FSOUND_Stream_SetBufferSize(200); 750 FSOUND_Stream_SetBufferSize(200);
769 751
770 // Here's where we set the size of the network buffer and some buffering 752 // Here's where we set the size of the network buffer and some buffering
771 // parameters. In this case we want a network buffer of 16k, we want it 753 // parameters. In this case we want a network buffer of 16k, we want it
@@ -810,19 +792,19 @@ signed char F_CALLBACKAPI LLAudioEngine_FMOD::callbackMetaData(char *name, char
810 if (!strcmp("ARTIST", name)) 792 if (!strcmp("ARTIST", name))
811 { 793 {
812 strlcpy(self->mInternetStreamArtist, value, 256); 794 strlcpy(self->mInternetStreamArtist, value, 256);
813 self->mInternetStreamNewMetaData = TRUE; 795 self->mInternetStreamNewMetaData = true;
814 return TRUE; 796 return true;
815 } 797 }
816 798
817 if (!strcmp("TITLE", name)) 799 if (!strcmp("TITLE", name))
818 { 800 {
819 strlcpy(self->mInternetStreamTitle, value, 256); 801 strlcpy(self->mInternetStreamTitle, value, 256);
820 self->mInternetStreamNewMetaData = TRUE; 802 self->mInternetStreamNewMetaData = true;
821 return TRUE; 803 return true;
822 } 804 }
823 */ 805 */
824 806
825 return TRUE; 807 return true;
826} 808}
827 809
828 810
@@ -867,7 +849,7 @@ void LLAudioEngine_FMOD::updateInternetStream()
867 { 849 {
868 // Reset volume to previously set volume 850 // Reset volume to previously set volume
869 setInternetStreamGain(mInternetStreamGain); 851 setInternetStreamGain(mInternetStreamGain);
870 FSOUND_SetPaused(mInternetStreamChannel, FALSE); 852 FSOUND_SetPaused(mInternetStreamChannel, false);
871 //FSOUND_Stream_Net_SetMetadataCallback(mInternetStream, callbackMetaData, this); 853 //FSOUND_Stream_Net_SetMetadataCallback(mInternetStream, callbackMetaData, this);
872 } 854 }
873 } 855 }
@@ -909,7 +891,7 @@ void LLAudioEngine_FMOD::stopInternetStream()
909{ 891{
910 if (mInternetStreamChannel != -1) 892 if (mInternetStreamChannel != -1)
911 { 893 {
912 FSOUND_SetPaused(mInternetStreamChannel, TRUE); 894 FSOUND_SetPaused(mInternetStreamChannel, true);
913 FSOUND_SetPriority(mInternetStreamChannel, 0); 895 FSOUND_SetPriority(mInternetStreamChannel, 0);
914 mInternetStreamChannel = -1; 896 mInternetStreamChannel = -1;
915 } 897 }
@@ -971,16 +953,10 @@ int LLAudioEngine_FMOD::isInternetStreamPlaying()
971} 953}
972 954
973 955
974void LLAudioEngine_FMOD::getInternetStreamInfo(char* artist_out, char* title_out)
975{
976 //strlcpy(artist_out, mInternetStreamArtist, 256);
977 //strlcpy(title_out, mInternetStreamTitle, 256);
978}
979
980
981void LLAudioEngine_FMOD::setInternetStreamGain(F32 vol) 956void LLAudioEngine_FMOD::setInternetStreamGain(F32 vol)
982{ 957{
983 LLAudioEngine::setInternetStreamGain(vol); 958 mInternetStreamGain = vol;
959
984 if (mInternetStreamChannel != -1) 960 if (mInternetStreamChannel != -1)
985 { 961 {
986 vol = llclamp(vol, 0.f, 1.f); 962 vol = llclamp(vol, 0.f, 1.f);
@@ -990,15 +966,9 @@ void LLAudioEngine_FMOD::setInternetStreamGain(F32 vol)
990} 966}
991 967
992 968
993const std::string& LLAudioEngine_FMOD::getInternetStreamURL()
994{
995 return mInternetStreamURL;
996}
997
998
999LLAudioStreamFMOD::LLAudioStreamFMOD(const std::string& url) : 969LLAudioStreamFMOD::LLAudioStreamFMOD(const std::string& url) :
1000 mInternetStream(NULL), 970 mInternetStream(NULL),
1001 mReady(FALSE) 971 mReady(false)
1002{ 972{
1003 mInternetStreamURL = url; 973 mInternetStreamURL = url;
1004 mInternetStream = FSOUND_Stream_Open(url.c_str(), FSOUND_NORMAL | FSOUND_NONBLOCKING, 0, 0); 974 mInternetStream = FSOUND_Stream_Open(url.c_str(), FSOUND_NORMAL | FSOUND_NONBLOCKING, 0, 0);
@@ -1007,11 +977,11 @@ LLAudioStreamFMOD::LLAudioStreamFMOD(const std::string& url) :
1007 llwarns << "Couldn't open fmod stream, error " 977 llwarns << "Couldn't open fmod stream, error "
1008 << FMOD_ErrorString(FSOUND_GetError()) 978 << FMOD_ErrorString(FSOUND_GetError())
1009 << llendl; 979 << llendl;
1010 mReady = FALSE; 980 mReady = false;
1011 return; 981 return;
1012 } 982 }
1013 983
1014 mReady = TRUE; 984 mReady = true;
1015} 985}
1016 986
1017int LLAudioStreamFMOD::startStream() 987int LLAudioStreamFMOD::startStream()
@@ -1026,10 +996,10 @@ int LLAudioStreamFMOD::startStream()
1026 // Make sure the stream is set to 2D mode. 996 // Make sure the stream is set to 2D mode.
1027 FSOUND_Stream_SetMode(mInternetStream, FSOUND_2D); 997 FSOUND_Stream_SetMode(mInternetStream, FSOUND_2D);
1028 998
1029 return FSOUND_Stream_PlayEx(FSOUND_FREE, mInternetStream, NULL, TRUE); 999 return FSOUND_Stream_PlayEx(FSOUND_FREE, mInternetStream, NULL, true);
1030} 1000}
1031 1001
1032BOOL LLAudioStreamFMOD::stopStream() 1002bool LLAudioStreamFMOD::stopStream()
1033{ 1003{
1034 if (mInternetStream) 1004 if (mInternetStream)
1035 { 1005 {
@@ -1039,34 +1009,34 @@ BOOL LLAudioStreamFMOD::stopStream()
1039 unsigned int flags = 0x0; 1009 unsigned int flags = 0x0;
1040 FSOUND_Stream_Net_GetStatus(mInternetStream, &status, &read_percent, &bitrate, &flags); 1010 FSOUND_Stream_Net_GetStatus(mInternetStream, &status, &read_percent, &bitrate, &flags);
1041 1011
1042 BOOL close = TRUE; 1012 bool close = true;
1043 switch (status) 1013 switch (status)
1044 { 1014 {
1045 case FSOUND_STREAM_NET_CONNECTING: 1015 case FSOUND_STREAM_NET_CONNECTING:
1046 close = FALSE; 1016 close = false;
1047 break; 1017 break;
1048 case FSOUND_STREAM_NET_NOTCONNECTED: 1018 case FSOUND_STREAM_NET_NOTCONNECTED:
1049 case FSOUND_STREAM_NET_BUFFERING: 1019 case FSOUND_STREAM_NET_BUFFERING:
1050 case FSOUND_STREAM_NET_READY: 1020 case FSOUND_STREAM_NET_READY:
1051 case FSOUND_STREAM_NET_ERROR: 1021 case FSOUND_STREAM_NET_ERROR:
1052 default: 1022 default:
1053 close = TRUE; 1023 close = true;
1054 } 1024 }
1055 1025
1056 if (close) 1026 if (close)
1057 { 1027 {
1058 FSOUND_Stream_Close(mInternetStream); 1028 FSOUND_Stream_Close(mInternetStream);
1059 mInternetStream = NULL; 1029 mInternetStream = NULL;
1060 return TRUE; 1030 return true;
1061 } 1031 }
1062 else 1032 else
1063 { 1033 {
1064 return FALSE; 1034 return false;
1065 } 1035 }
1066 } 1036 }
1067 else 1037 else
1068 { 1038 {
1069 return TRUE; 1039 return true;
1070 } 1040 }
1071} 1041}
1072 1042
@@ -1076,94 +1046,35 @@ int LLAudioStreamFMOD::getOpenState()
1076 return open_state; 1046 return open_state;
1077} 1047}
1078 1048
1079/* This determines the format of the mixbuffer being passed in. change if you want to support int32 or float32 */ 1049void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata)
1080#if LL_DARWIN
1081 #define MIXBUFFERFORMAT S32
1082#else
1083 #define MIXBUFFERFORMAT S16
1084#endif
1085
1086inline MIXBUFFERFORMAT clipSample(MIXBUFFERFORMAT sample, MIXBUFFERFORMAT min, MIXBUFFERFORMAT max)
1087{
1088 if (sample > max)
1089 sample = max;
1090 else if (sample < min)
1091 sample = min;
1092
1093 return sample;
1094}
1095
1096void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void*)
1097{ 1050{
1098// originalbuffer = fsounds original mixbuffer. 1051 // originalbuffer = fmod's original mixbuffer.
1099// newbuffer = the buffer passed from the previous DSP unit. 1052 // newbuffer = the buffer passed from the previous DSP unit.
1100// length = length in samples at this mix time. 1053 // length = length in samples at this mix time.
1101// param = user parameter passed through in FSOUND_DSP_Create. 1054 // param = user parameter passed through in FSOUND_DSP_Create.
1102// 1055 //
1103// modify the buffer in some fashion 1056 // modify the buffer in some fashion
1104 1057
1105 U8 *cursamplep = (U8*)newbuffer; 1058 LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *windgen =
1106 U8 wordsize = 2; 1059 (LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *)userdata;
1060 U8 stride;
1107 1061
1108#if LL_DARWIN 1062#if LL_DARWIN
1109 wordsize = sizeof(MIXBUFFERFORMAT); 1063 stride = sizeof(LLAudioEngine_FMOD::MIXBUFFERFORMAT);
1110#else 1064#else
1111 int mixertype = FSOUND_GetMixer(); 1065 int mixertype = FSOUND_GetMixer();
1112 if (mixertype == FSOUND_MIXER_BLENDMODE || mixertype == FSOUND_MIXER_QUALITY_FPU) 1066 if (mixertype == FSOUND_MIXER_BLENDMODE ||
1113 { 1067 mixertype == FSOUND_MIXER_QUALITY_FPU)
1114 wordsize = 4; 1068 {
1115 } 1069 stride = 4;
1116#endif 1070 }
1117 1071 else
1118 double bandwidth = 50; 1072 {
1119 double inputSamplingRate = 44100; 1073 stride = 2;
1120 double a0,b1,b2; 1074 }
1121
1122 // calculate resonant filter coeffs
1123 b2 = exp(-(F_TWO_PI) * (bandwidth / inputSamplingRate));
1124
1125 while (length--)
1126 {
1127 gCurrentFreq = (float)((0.999 * gCurrentFreq) + (0.001 * gTargetFreq));
1128 gCurrentGain = (float)((0.999 * gCurrentGain) + (0.001 * gTargetGain));
1129 gCurrentPanGainR = (float)((0.999 * gCurrentPanGainR) + (0.001 * gTargetPanGainR));
1130 b1 = (-4.0 * b2) / (1.0 + b2) * cos(F_TWO_PI * (gCurrentFreq / inputSamplingRate));
1131 a0 = (1.0 - b2) * sqrt(1.0 - (b1 * b1) / (4.0 * b2));
1132 double nextSample;
1133
1134 // start with white noise
1135 nextSample = ll_frand(2.0f) - 1.0f;
1136
1137#if 1 // LLAE_WIND_PINK apply pinking filter
1138 gbuf0 = 0.997f * gbuf0 + 0.0126502f * nextSample;
1139 gbuf1 = 0.985f * gbuf1 + 0.0139083f * nextSample;
1140 gbuf2 = 0.950f * gbuf2 + 0.0205439f * nextSample;
1141 gbuf3 = 0.850f * gbuf3 + 0.0387225f * nextSample;
1142 gbuf4 = 0.620f * gbuf4 + 0.0465932f * nextSample;
1143 gbuf5 = 0.250f * gbuf5 + 0.1093477f * nextSample;
1144
1145 nextSample = gbuf0 + gbuf1 + gbuf2 + gbuf3 + gbuf4 + gbuf5;
1146#endif
1147
1148#if 1 //LLAE_WIND_RESONANT // do a resonant filter on the noise
1149 nextSample = (double)( a0 * nextSample - b1 * gY0 - b2 * gY1 );
1150
1151 gY1 = gY0;
1152 gY0 = nextSample;
1153#endif 1075#endif
1154 1076
1155 nextSample *= gCurrentGain; 1077 newbuffer = windgen->windGenerate((LLAudioEngine_FMOD::MIXBUFFERFORMAT *)newbuffer, length, stride);
1156
1157 MIXBUFFERFORMAT sample;
1158
1159 sample = llfloor(((F32)nextSample*32768.f*(1.0f - gCurrentPanGainR))+0.5f);
1160 *(MIXBUFFERFORMAT*)cursamplep = clipSample((*(MIXBUFFERFORMAT*)cursamplep) + sample, -32768, 32767);
1161 cursamplep += wordsize;
1162
1163 sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f);
1164 *(MIXBUFFERFORMAT*)cursamplep = clipSample((*(MIXBUFFERFORMAT*)cursamplep) + sample, -32768, 32767);
1165 cursamplep += wordsize;
1166 }
1167 1078
1168 return newbuffer; 1079 return newbuffer;
1169} 1080}