diff options
author | Jacek Antonelli | 2008-11-19 12:51:29 -0600 |
---|---|---|
committer | Jacek Antonelli | 2008-11-19 16:55:13 -0600 |
commit | 97e6c15e935666c1b295b7508a182d0da4b481f1 (patch) | |
tree | ef1d5e6a33a71b51a3deadb6de54a67b6a8c7f5e /linden/indra/llaudio/audioengine_fmod.cpp | |
parent | Changed to Imprudence.exec_marker to match llappviewer.cpp. (diff) | |
download | meta-impy-97e6c15e935666c1b295b7508a182d0da4b481f1.zip meta-impy-97e6c15e935666c1b295b7508a182d0da4b481f1.tar.gz meta-impy-97e6c15e935666c1b295b7508a182d0da4b481f1.tar.bz2 meta-impy-97e6c15e935666c1b295b7508a182d0da4b481f1.tar.xz |
VWR-2662: OpenAL support (patch by Tofu Linden)
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llaudio/audioengine_fmod.cpp | 271 |
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 | ||
48 | extern "C" { | ||
49 | void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata); | ||
50 | } | ||
49 | 51 | ||
50 | void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata); | ||
51 | FSOUND_DSPUNIT *gWindDSP = NULL; | 52 | FSOUND_DSPUNIT *gWindDSP = NULL; |
52 | 53 | ||
53 | // These globals for the wind filter. Blech! | ||
54 | F64 gbuf0 = 0.0; | ||
55 | F64 gbuf1 = 0.0; | ||
56 | F64 gbuf2 = 0.0; | ||
57 | F64 gbuf3 = 0.0; | ||
58 | F64 gbuf4 = 0.0; | ||
59 | F64 gbuf5 = 0.0; | ||
60 | F64 gY0 = 0.0; | ||
61 | F64 gY1 = 0.0; | ||
62 | |||
63 | F32 gTargetGain = 0.f; | ||
64 | F32 gCurrentGain = 0.f; | ||
65 | F32 gTargetFreq = 100.f; | ||
66 | F32 gCurrentFreq = 100.f; | ||
67 | F32 gTargetPanGainR = 0.5f; | ||
68 | F32 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 | ||
95 | LLAudioEngine_FMOD::LLAudioEngine_FMOD() | 79 | LLAudioEngine_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 | ||
108 | BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) | 93 | bool 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 | |||
268 | void 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 | ||
319 | void LLAudioEngine_FMOD::initWind() | 296 | void 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 | ||
460 | BOOL LLAudioChannelFMOD::updateBuffer() | 442 | bool 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 | ||
621 | BOOL LLAudioChannelFMOD::isPlaying() | 603 | bool 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 | ||
655 | BOOL LLAudioBufferFMOD::loadWAV(const std::string& filename) | 637 | bool 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 | ||
739 | void LLAudioBufferFMOD::set3DMode(BOOL use3d) | 721 | void 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 | ||
974 | void 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 | |||
981 | void LLAudioEngine_FMOD::setInternetStreamGain(F32 vol) | 956 | void 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 | ||
993 | const std::string& LLAudioEngine_FMOD::getInternetStreamURL() | ||
994 | { | ||
995 | return mInternetStreamURL; | ||
996 | } | ||
997 | |||
998 | |||
999 | LLAudioStreamFMOD::LLAudioStreamFMOD(const std::string& url) : | 969 | LLAudioStreamFMOD::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 | ||
1017 | int LLAudioStreamFMOD::startStream() | 987 | int 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 | ||
1032 | BOOL LLAudioStreamFMOD::stopStream() | 1002 | bool 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 */ | 1049 | void * 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 | |||
1086 | inline 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 | |||
1096 | void * 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 | } |