diff options
Diffstat (limited to 'linden/indra')
-rw-r--r-- | linden/indra/llaudio/llaudioengine_openal.cpp | 162 | ||||
-rw-r--r-- | linden/indra/llaudio/llaudioengine_openal.h | 3 |
2 files changed, 130 insertions, 35 deletions
diff --git a/linden/indra/llaudio/llaudioengine_openal.cpp b/linden/indra/llaudio/llaudioengine_openal.cpp index c33b992..08ec464 100644 --- a/linden/indra/llaudio/llaudioengine_openal.cpp +++ b/linden/indra/llaudio/llaudioengine_openal.cpp | |||
@@ -40,6 +40,35 @@ | |||
40 | 40 | ||
41 | static const float WIND_BUFFER_SIZE_SEC = 0.05f; // 1/20th sec | 41 | static const float WIND_BUFFER_SIZE_SEC = 0.05f; // 1/20th sec |
42 | 42 | ||
43 | std::string convertALErrorToString(ALenum error) | ||
44 | { | ||
45 | switch(error) | ||
46 | { | ||
47 | case AL_NO_ERROR: | ||
48 | return std::string("AL_NO_ERROR"); | ||
49 | break; | ||
50 | case AL_INVALID_NAME: | ||
51 | return std::string("AL_INVALID_NAME"); | ||
52 | break; | ||
53 | case AL_INVALID_ENUM: | ||
54 | return std::string("AL_INVALID_ENUM"); | ||
55 | break; | ||
56 | case AL_INVALID_VALUE: | ||
57 | return std::string("AL_INVALID_VALUE"); | ||
58 | break; | ||
59 | case AL_INVALID_OPERATION: | ||
60 | return std::string("AL_INVALID_OPERATION"); | ||
61 | break; | ||
62 | case AL_OUT_OF_MEMORY: | ||
63 | return std::string("AL_OUT_OF_MEMORY"); | ||
64 | break; | ||
65 | default: | ||
66 | std::stringstream s; | ||
67 | s << error; | ||
68 | return s.str(); | ||
69 | } | ||
70 | } | ||
71 | |||
43 | LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() | 72 | LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() |
44 | : | 73 | : |
45 | mWindGen(NULL), | 74 | mWindGen(NULL), |
@@ -72,39 +101,76 @@ bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata) | |||
72 | } | 101 | } |
73 | 102 | ||
74 | // check for extensions | 103 | // check for extensions |
75 | if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")) | 104 | const ALCchar* device_list(NULL); |
105 | const ALCchar* device_default(NULL); | ||
106 | if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE) | ||
76 | { | 107 | { |
108 | device_default = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); | ||
109 | device_list = alcGetString(NULL, ALC_DEVICE_SPECIFIER); | ||
77 | llinfos << "Results for ALC_ENUMERATION_EXT:\n" | 110 | llinfos << "Results for ALC_ENUMERATION_EXT:\n" |
78 | << ll_safe_string(alcGetString(NULL, ALC_DEVICE_SPECIFIER)) | 111 | << ll_safe_string(device_list) |
79 | << llendl; | 112 | << llendl; |
113 | |||
80 | } | 114 | } |
81 | 115 | ||
82 | // initialize device | 116 | // initialize device |
83 | ALCdevice* mDevice = alcOpenDevice(NULL); | 117 | ALCdevice* mDevice = alcOpenDevice(NULL); |
84 | if (!mDevice) | 118 | if (mDevice == NULL) |
85 | { | 119 | { |
86 | llinfos << "OpenAL could not find an installed audio device. Aborting" << llendl; | 120 | llinfos << "Could not find a default device, trying to open default manually: " |
87 | ALCenum error = alcGetError(mDevice); | 121 | << ll_safe_string(device_default) |
88 | if (error != ALC_NO_ERROR) | 122 | << llendl; |
123 | mDevice = alcOpenDevice(device_default); | ||
124 | if (mDevice == NULL) | ||
89 | { | 125 | { |
90 | llinfos << "ALC error:" << ll_safe_string(alcGetString(mDevice, error)) << llendl; | 126 | const ALCchar* device_list_walk = device_list; |
127 | do | ||
128 | { | ||
129 | mDevice = alcOpenDevice(device_list_walk); | ||
130 | if (mDevice != NULL) | ||
131 | { | ||
132 | break; | ||
133 | } | ||
134 | else | ||
135 | { | ||
136 | device_list_walk += strlen(device_list_walk)+1; | ||
137 | } | ||
138 | } | ||
139 | while (device_list_walk[0] != '\0'); | ||
140 | |||
141 | if (mDevice == NULL) | ||
142 | { | ||
143 | llinfos << "OpenAL could not find an installed audio device. Aborting" << llendl; | ||
144 | ALCenum error = alcGetError(mDevice); | ||
145 | if (error != ALC_NO_ERROR) | ||
146 | { | ||
147 | llinfos << "ALC error: " << ll_safe_string(alcGetString(mDevice, error)) << llendl; | ||
148 | } | ||
149 | return false; | ||
150 | } | ||
91 | } | 151 | } |
92 | return false; | ||
93 | } | 152 | } |
94 | 153 | ||
95 | // create context | 154 | // create context |
96 | ALCcontext* mContext = alcCreateContext(mDevice, NULL); | 155 | ALCcontext* mContext = alcCreateContext(mDevice, NULL); |
97 | if (mContext != NULL) | 156 | if (mContext != NULL) |
98 | { | 157 | { |
99 | alcMakeContextCurrent(mContext); | 158 | if (!alcMakeContextCurrent(mContext)) |
100 | if (alGetError() != AL_NO_ERROR) | ||
101 | { | 159 | { |
102 | llinfos << "ALC error:" << alGetError() << ". Could not set current context!" << llendl; | 160 | ALenum error = alGetError(); |
161 | if (error != AL_NO_ERROR) | ||
162 | { | ||
163 | llinfos << "ALC error: " << convertALErrorToString(error) << ". Could not set current context!" << llendl; | ||
164 | } | ||
165 | alcDestroyContext(mContext); | ||
166 | return false; | ||
103 | } | 167 | } |
104 | } | 168 | } |
105 | else | 169 | else |
106 | { | 170 | { |
107 | llinfos << "ALC error: could not create context from device!" << llendl; | 171 | llinfos << "ALC error: could not create context from device!" << llendl; |
172 | alcCloseDevice(mDevice); | ||
173 | return false; | ||
108 | } | 174 | } |
109 | 175 | ||
110 | llinfos << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << llendl; | 176 | llinfos << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << llendl; |
@@ -174,23 +240,43 @@ void LLAudioEngine_OpenAL::allocateListener() | |||
174 | void LLAudioEngine_OpenAL::shutdown() | 240 | void LLAudioEngine_OpenAL::shutdown() |
175 | { | 241 | { |
176 | llinfos << "About to LLAudioEngine::shutdown()" << llendl; | 242 | llinfos << "About to LLAudioEngine::shutdown()" << llendl; |
243 | |||
177 | LLAudioEngine::shutdown(); | 244 | LLAudioEngine::shutdown(); |
178 | 245 | ||
179 | llinfos << "About to alutExit()" << llendl; | 246 | llinfos << "About to alutExit()" << llendl; |
180 | if(!alutExit()) | 247 | if(!alutExit()) |
181 | { | 248 | { |
182 | llwarns << "Nuts." << llendl; | 249 | llwarns << "Nuts." << llendl; |
183 | llwarns << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << llendl; | 250 | llwarns << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString(alutGetError()) << llendl; |
184 | } | 251 | } |
185 | 252 | ||
186 | alcMakeContextCurrent(NULL); | ||
187 | alcDestroyContext(mContext); | ||
188 | alcCloseDevice(mDevice); | ||
189 | |||
190 | llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl; | 253 | llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl; |
191 | 254 | ||
192 | delete mListenerp; | 255 | delete mListenerp; |
193 | mListenerp = NULL; | 256 | mListenerp = NULL; |
257 | |||
258 | ALenum error; | ||
259 | |||
260 | alcMakeContextCurrent(NULL); | ||
261 | error = alGetError(); | ||
262 | if (error != AL_NO_ERROR) | ||
263 | { | ||
264 | llinfos << "AL error: " << convertALErrorToString(error) << ". Could not make current context NULL!" << llendl; | ||
265 | } | ||
266 | |||
267 | alcDestroyContext(mContext); | ||
268 | error = alGetError(); | ||
269 | if (error != AL_NO_ERROR) | ||
270 | { | ||
271 | llinfos << "AL error: " << convertALErrorToString(error) << ". Could not destroy context!" << llendl; | ||
272 | } | ||
273 | |||
274 | alcCloseDevice(mDevice); | ||
275 | error = alGetError(); | ||
276 | if (error != AL_NO_ERROR) | ||
277 | { | ||
278 | llinfos << "AL error: " << convertALErrorToString(error) << ". Could not close device!" << llendl; | ||
279 | } | ||
194 | } | 280 | } |
195 | 281 | ||
196 | LLAudioBuffer *LLAudioEngine_OpenAL::createBuffer() | 282 | LLAudioBuffer *LLAudioEngine_OpenAL::createBuffer() |
@@ -220,7 +306,11 @@ LLAudioChannelOpenAL::LLAudioChannelOpenAL() | |||
220 | LLAudioChannelOpenAL::~LLAudioChannelOpenAL() | 306 | LLAudioChannelOpenAL::~LLAudioChannelOpenAL() |
221 | { | 307 | { |
222 | cleanup(); | 308 | cleanup(); |
223 | alDeleteSources(1, &mALSource); | 309 | if (mALSource != AL_NONE) //MC |
310 | { | ||
311 | alDeleteSources(1, &mALSource); | ||
312 | mALSource = AL_NONE; | ||
313 | } | ||
224 | } | 314 | } |
225 | 315 | ||
226 | void LLAudioChannelOpenAL::cleanup() | 316 | void LLAudioChannelOpenAL::cleanup() |
@@ -379,18 +469,20 @@ bool LLAudioBufferOpenAL::loadWAV(const std::string& filename) | |||
379 | ALenum error = alutGetError(); | 469 | ALenum error = alutGetError(); |
380 | if (gDirUtilp->fileExists(filename)) | 470 | if (gDirUtilp->fileExists(filename)) |
381 | { | 471 | { |
382 | llwarns << | 472 | llwarns << "LLAudioBufferOpenAL::loadWAV() Error loading " |
383 | "LLAudioBufferOpenAL::loadWAV() Error loading " | 473 | << filename << " " |
384 | << filename | 474 | << convertALErrorToString(error) << ": " |
385 | << " " << alutGetErrorString(error) << llendl; | 475 | << alutGetErrorString(error) |
476 | << llendl; | ||
386 | } | 477 | } |
387 | else | 478 | else |
388 | { | 479 | { |
389 | // It's common for the file to not actually exist. | 480 | // It's common for the file to not actually exist. |
390 | lldebugs << | 481 | lldebugs << "LLAudioBufferOpenAL::loadWAV() Error loading " |
391 | "LLAudioBufferOpenAL::loadWAV() Error loading " | 482 | << filename << " " |
392 | << filename | 483 | << convertALErrorToString(error) << ": " |
393 | << " " << alutGetErrorString(error) << llendl; | 484 | << alutGetErrorString(error) |
485 | << llendl; | ||
394 | } | 486 | } |
395 | return false; | 487 | return false; |
396 | } | 488 | } |
@@ -424,7 +516,7 @@ void LLAudioEngine_OpenAL::initWind() | |||
424 | 516 | ||
425 | if((error=alGetError()) != AL_NO_ERROR) | 517 | if((error=alGetError()) != AL_NO_ERROR) |
426 | { | 518 | { |
427 | llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: "<<error<<llendl; | 519 | llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: " << convertALErrorToString(error) << llendl; |
428 | } | 520 | } |
429 | 521 | ||
430 | mWindGen = new LLWindGen<WIND_SAMPLE_T>; | 522 | mWindGen = new LLWindGen<WIND_SAMPLE_T>; |
@@ -524,14 +616,14 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) | |||
524 | 616 | ||
525 | //llinfos << "mNumEmptyWindALBuffers: " << mNumEmptyWindALBuffers <<" (" << unprocessed << ":" << processed << ")" << llendl; | 617 | //llinfos << "mNumEmptyWindALBuffers: " << mNumEmptyWindALBuffers <<" (" << unprocessed << ":" << processed << ")" << llendl; |
526 | 618 | ||
527 | while(processed--) // unqueue old buffers | 619 | while (processed--) // unqueue old buffers |
528 | { | 620 | { |
529 | ALuint buffer; | 621 | ALuint buffer; |
530 | ALenum error; | 622 | ALenum error; |
531 | alGetError(); /* clear error */ | 623 | alGetError(); /* clear error */ |
532 | alSourceUnqueueBuffers(mWindSource, 1, &buffer); | 624 | alSourceUnqueueBuffers(mWindSource, 1, &buffer); |
533 | error = alGetError(); | 625 | error = alGetError(); |
534 | if(error != AL_NO_ERROR) | 626 | if (error != AL_NO_ERROR) |
535 | { | 627 | { |
536 | llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << llendl; | 628 | llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << llendl; |
537 | } | 629 | } |
@@ -547,9 +639,9 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) | |||
547 | ALuint buffer; | 639 | ALuint buffer; |
548 | alGetError(); /* clear error */ | 640 | alGetError(); /* clear error */ |
549 | alGenBuffers(1,&buffer); | 641 | alGenBuffers(1,&buffer); |
550 | if((error=alGetError()) != AL_NO_ERROR) | 642 | if ((error=alGetError()) != AL_NO_ERROR) |
551 | { | 643 | { |
552 | llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << error << llendl; | 644 | llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << convertALErrorToString(error) << llendl; |
553 | break; | 645 | break; |
554 | } | 646 | } |
555 | 647 | ||
@@ -560,14 +652,14 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) | |||
560 | mWindBufBytes, | 652 | mWindBufBytes, |
561 | mWindBufFreq); | 653 | mWindBufFreq); |
562 | error = alGetError(); | 654 | error = alGetError(); |
563 | if(error != AL_NO_ERROR) | 655 | if (error != AL_NO_ERROR) |
564 | { | 656 | { |
565 | llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << llendl; | 657 | llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << llendl; |
566 | } | 658 | } |
567 | 659 | ||
568 | alSourceQueueBuffers(mWindSource, 1, &buffer); | 660 | alSourceQueueBuffers(mWindSource, 1, &buffer); |
569 | error = alGetError(); | 661 | error = alGetError(); |
570 | if(error != AL_NO_ERROR) | 662 | if (error != AL_NO_ERROR) |
571 | { | 663 | { |
572 | llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << llendl; | 664 | llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << llendl; |
573 | } | 665 | } |
@@ -577,11 +669,13 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) | |||
577 | 669 | ||
578 | ALint playing; | 670 | ALint playing; |
579 | alGetSourcei(mWindSource, AL_SOURCE_STATE, &playing); | 671 | alGetSourcei(mWindSource, AL_SOURCE_STATE, &playing); |
580 | if(playing != AL_PLAYING) | 672 | if (playing != AL_PLAYING) |
581 | { | 673 | { |
582 | alSourcePlay(mWindSource); | 674 | alSourcePlay(mWindSource); |
583 | 675 | ||
584 | lldebugs << "Wind had stopped - probably ran out of buffers - restarting: " << (unprocessed+mNumEmptyWindALBuffers) << " now queued." << llendl; | 676 | lldebugs << "Wind had stopped - probably ran out of buffers - restarting: " |
677 | << (unprocessed+mNumEmptyWindALBuffers) << " now queued." | ||
678 | << llendl; | ||
585 | } | 679 | } |
586 | } | 680 | } |
587 | 681 | ||
diff --git a/linden/indra/llaudio/llaudioengine_openal.h b/linden/indra/llaudio/llaudioengine_openal.h index 9b52b88..df32e13 100644 --- a/linden/indra/llaudio/llaudioengine_openal.h +++ b/linden/indra/llaudio/llaudioengine_openal.h | |||
@@ -97,7 +97,8 @@ class LLAudioChannelOpenAL : public LLAudioChannel | |||
97 | ALint mLastSamplePos; | 97 | ALint mLastSamplePos; |
98 | }; | 98 | }; |
99 | 99 | ||
100 | class LLAudioBufferOpenAL : public LLAudioBuffer{ | 100 | class LLAudioBufferOpenAL : public LLAudioBuffer |
101 | { | ||
101 | public: | 102 | public: |
102 | LLAudioBufferOpenAL(); | 103 | LLAudioBufferOpenAL(); |
103 | virtual ~LLAudioBufferOpenAL(); | 104 | virtual ~LLAudioBufferOpenAL(); |