diff options
Diffstat (limited to 'linden/indra/llaudio')
-rw-r--r-- | linden/indra/llaudio/audioengine.cpp | 198 | ||||
-rw-r--r-- | linden/indra/llaudio/audioengine.h | 75 | ||||
-rw-r--r-- | linden/indra/llaudio/audioengine_openal.cpp | 689 | ||||
-rw-r--r-- | linden/indra/llaudio/audioengine_openal.h | 62 | ||||
-rw-r--r-- | linden/indra/llaudio/listener_openal.cpp | 8 | ||||
-rw-r--r-- | linden/indra/llaudio/listener_openal.h | 13 | ||||
-rw-r--r-- | linden/indra/llaudio/llaudiodecodemgr.cpp | 23 |
7 files changed, 689 insertions, 379 deletions
diff --git a/linden/indra/llaudio/audioengine.cpp b/linden/indra/llaudio/audioengine.cpp index 0a450e9..5fb38c0 100644 --- a/linden/indra/llaudio/audioengine.cpp +++ b/linden/indra/llaudio/audioengine.cpp | |||
@@ -51,6 +51,9 @@ extern void request_sound(const LLUUID &sound_guid); | |||
51 | 51 | ||
52 | LLAudioEngine* gAudiop = NULL; | 52 | LLAudioEngine* gAudiop = NULL; |
53 | 53 | ||
54 | // Maximum amount of time we wait for a transfer to complete before starting | ||
55 | // off another one. | ||
56 | const F32 MAX_CURRENT_TRANSFER_TIME = 60.f; | ||
54 | 57 | ||
55 | // | 58 | // |
56 | // LLAudioEngine implementation | 59 | // LLAudioEngine implementation |
@@ -74,8 +77,7 @@ void LLAudioEngine::setDefaults() | |||
74 | 77 | ||
75 | mListenerp = NULL; | 78 | mListenerp = NULL; |
76 | 79 | ||
77 | mMuted = false; | 80 | mMuted = FALSE; |
78 | mUserData = NULL; | ||
79 | 81 | ||
80 | mLastStatus = 0; | 82 | mLastStatus = 0; |
81 | 83 | ||
@@ -96,17 +98,16 @@ void LLAudioEngine::setDefaults() | |||
96 | mInternetStreamGain = 0.125f; | 98 | mInternetStreamGain = 0.125f; |
97 | mNextWindUpdate = 0.f; | 99 | mNextWindUpdate = 0.f; |
98 | 100 | ||
99 | mInternetStreamMedia = NULL; | 101 | for (U32 i = 0; i < LLAudioEngine::AUDIO_TYPE_COUNT; i++) |
100 | mInternetStreamURL.clear(); | 102 | mSecondaryGain[i] = 1.0f; |
101 | } | 103 | } |
102 | 104 | ||
103 | 105 | ||
104 | bool LLAudioEngine::init(const S32 num_channels, void* userdata) | 106 | BOOL LLAudioEngine::init(const S32 num_channels) |
105 | { | 107 | { |
106 | setDefaults(); | 108 | setDefaults(); |
107 | 109 | ||
108 | mNumChannels = num_channels; | 110 | mNumChannels = num_channels; |
109 | mUserData = userdata; | ||
110 | 111 | ||
111 | allocateListener(); | 112 | allocateListener(); |
112 | 113 | ||
@@ -145,146 +146,22 @@ void LLAudioEngine::shutdown() | |||
145 | S32 i; | 146 | S32 i; |
146 | for (i = 0; i < MAX_CHANNELS; i++) | 147 | for (i = 0; i < MAX_CHANNELS; i++) |
147 | { | 148 | { |
148 | delete mChannels[i]; | 149 | if (mChannels[i]) |
149 | mChannels[i] = NULL; | 150 | { |
151 | delete mChannels[i]; | ||
152 | mChannels[i] = NULL; | ||
153 | } | ||
150 | } | 154 | } |
151 | 155 | ||
152 | // Clean up buffers | 156 | // Clean up buffers |
153 | for (i = 0; i < MAX_BUFFERS; i++) | 157 | for (i = 0; i < MAX_BUFFERS; i++) |
154 | { | 158 | { |
155 | delete mBuffers[i]; | 159 | if (mBuffers[i]) |
156 | mBuffers[i] = NULL; | ||
157 | } | ||
158 | |||
159 | delete mInternetStreamMedia; | ||
160 | mInternetStreamMedia = NULL; | ||
161 | mInternetStreamURL.clear(); | ||
162 | } | ||
163 | |||
164 | |||
165 | // virtual | ||
166 | void LLAudioEngine::startInternetStream(const std::string& url) | ||
167 | { | ||
168 | llinfos << "entered startInternetStream()" << llendl; | ||
169 | |||
170 | if (!mInternetStreamMedia) | ||
171 | { | ||
172 | LLMediaManager* mgr = LLMediaManager::getInstance(); | ||
173 | if (mgr) | ||
174 | { | 160 | { |
175 | mInternetStreamMedia = mgr->createSourceFromMimeType(LLURI(url).scheme(), "audio/mpeg"); // assumes that whatever media implementation supports mp3 also supports vorbis. | 161 | delete mBuffers[i]; |
176 | llinfos << "mInternetStreamMedia is now " << mInternetStreamMedia << llendl; | 162 | mBuffers[i] = NULL; |
177 | } | ||
178 | } | ||
179 | |||
180 | if(!mInternetStreamMedia) | ||
181 | return; | ||
182 | |||
183 | if (!url.empty()) { | ||
184 | llinfos << "Starting internet stream: " << url << llendl; | ||
185 | mInternetStreamURL = url; | ||
186 | mInternetStreamMedia->navigateTo ( url ); | ||
187 | llinfos << "Playing....." << llendl; | ||
188 | mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START); | ||
189 | mInternetStreamMedia->updateMedia(); | ||
190 | } else { | ||
191 | llinfos << "setting stream to NULL"<< llendl; | ||
192 | mInternetStreamURL.clear(); | ||
193 | mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP); | ||
194 | mInternetStreamMedia->updateMedia(); | ||
195 | } | ||
196 | //#endif | ||
197 | } | ||
198 | |||
199 | // virtual | ||
200 | void LLAudioEngine::stopInternetStream() | ||
201 | { | ||
202 | llinfos << "entered stopInternetStream()" << llendl; | ||
203 | |||
204 | if(mInternetStreamMedia) | ||
205 | { | ||
206 | if( ! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP)){ | ||
207 | llinfos << "attempting to stop stream failed!" << llendl; | ||
208 | } | 163 | } |
209 | mInternetStreamMedia->updateMedia(); | ||
210 | } | 164 | } |
211 | |||
212 | mInternetStreamURL.clear(); | ||
213 | } | ||
214 | |||
215 | // virtual | ||
216 | void LLAudioEngine::pauseInternetStream(int pause) | ||
217 | { | ||
218 | llinfos << "entered pauseInternetStream()" << llendl; | ||
219 | |||
220 | if(!mInternetStreamMedia) | ||
221 | return; | ||
222 | |||
223 | if(pause) | ||
224 | { | ||
225 | if(! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_PAUSE)) | ||
226 | { | ||
227 | llinfos << "attempting to pause stream failed!" << llendl; | ||
228 | } | ||
229 | } else { | ||
230 | if(! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START)) | ||
231 | { | ||
232 | llinfos << "attempting to unpause stream failed!" << llendl; | ||
233 | } | ||
234 | } | ||
235 | mInternetStreamMedia->updateMedia(); | ||
236 | } | ||
237 | |||
238 | // virtual | ||
239 | void LLAudioEngine::updateInternetStream() | ||
240 | { | ||
241 | if (mInternetStreamMedia) | ||
242 | mInternetStreamMedia->updateMedia(); | ||
243 | } | ||
244 | |||
245 | // virtual | ||
246 | int LLAudioEngine::isInternetStreamPlaying() | ||
247 | { | ||
248 | if (!mInternetStreamMedia) | ||
249 | return 0; | ||
250 | |||
251 | if (mInternetStreamMedia->getStatus() == LLMediaBase::STATUS_STARTED) | ||
252 | { | ||
253 | return 1; // Active and playing | ||
254 | } | ||
255 | |||
256 | if (mInternetStreamMedia->getStatus() == LLMediaBase::STATUS_PAUSED) | ||
257 | { | ||
258 | return 2; // paused | ||
259 | } | ||
260 | |||
261 | return 0; // Stopped | ||
262 | } | ||
263 | |||
264 | // virtual | ||
265 | void LLAudioEngine::getInternetStreamInfo(char* artist, char* title) | ||
266 | { | ||
267 | artist[0] = 0; | ||
268 | title[0] = 0; | ||
269 | } | ||
270 | |||
271 | // virtual | ||
272 | void LLAudioEngine::setInternetStreamGain(F32 vol) | ||
273 | { | ||
274 | mInternetStreamGain = vol; | ||
275 | |||
276 | if(!mInternetStreamMedia) | ||
277 | return; | ||
278 | |||
279 | vol = llclamp(vol, 0.f, 1.f); | ||
280 | mInternetStreamMedia->setVolume(vol); | ||
281 | mInternetStreamMedia->updateMedia(); | ||
282 | } | ||
283 | |||
284 | // virtual | ||
285 | const std::string& LLAudioEngine::getInternetStreamURL() | ||
286 | { | ||
287 | return mInternetStreamURL; | ||
288 | } | 165 | } |
289 | 166 | ||
290 | 167 | ||
@@ -295,6 +172,13 @@ void LLAudioEngine::updateChannels() | |||
295 | { | 172 | { |
296 | if (mChannels[i]) | 173 | if (mChannels[i]) |
297 | { | 174 | { |
175 | // set secondary gain if type is available | ||
176 | LLAudioSource* source = mChannels[i]->getSource(); | ||
177 | if (source) | ||
178 | { | ||
179 | mChannels[i]->setSecondaryGain(mSecondaryGain[source->getType()]); | ||
180 | } | ||
181 | |||
298 | mChannels[i]->updateBuffer(); | 182 | mChannels[i]->updateBuffer(); |
299 | mChannels[i]->update3DPosition(); | 183 | mChannels[i]->update3DPosition(); |
300 | mChannels[i]->updateLoop(); | 184 | mChannels[i]->updateLoop(); |
@@ -565,8 +449,6 @@ void LLAudioEngine::idle(F32 max_decode_time) | |||
565 | // missed picking it up in all the places that can add | 449 | // missed picking it up in all the places that can add |
566 | // or request new data. | 450 | // or request new data. |
567 | startNextTransfer(); | 451 | startNextTransfer(); |
568 | |||
569 | updateInternetStream(); | ||
570 | } | 452 | } |
571 | 453 | ||
572 | 454 | ||
@@ -775,6 +657,18 @@ F32 LLAudioEngine::getMasterGain() | |||
775 | return mMasterGain; | 657 | return mMasterGain; |
776 | } | 658 | } |
777 | 659 | ||
660 | void LLAudioEngine::setSecondaryGain(S32 type, F32 gain) | ||
661 | { | ||
662 | llassert(type < LLAudioEngine::AUDIO_TYPE_COUNT); | ||
663 | |||
664 | mSecondaryGain[type] = gain; | ||
665 | } | ||
666 | |||
667 | F32 LLAudioEngine::getSecondaryGain(S32 type) | ||
668 | { | ||
669 | return mSecondaryGain[type]; | ||
670 | } | ||
671 | |||
778 | F32 LLAudioEngine::getInternetStreamGain() | 672 | F32 LLAudioEngine::getInternetStreamGain() |
779 | { | 673 | { |
780 | return mInternetStreamGain; | 674 | return mInternetStreamGain; |
@@ -850,7 +744,8 @@ F64 LLAudioEngine::mapWindVecToPan(LLVector3 wind_vec) | |||
850 | } | 744 | } |
851 | 745 | ||
852 | 746 | ||
853 | void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const LLVector3d &pos_global) | 747 | void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, |
748 | const S32 type, const LLVector3d &pos_global) | ||
854 | { | 749 | { |
855 | // Create a new source (since this can't be associated with an existing source. | 750 | // Create a new source (since this can't be associated with an existing source. |
856 | //llinfos << "Localized: " << audio_uuid << llendl; | 751 | //llinfos << "Localized: " << audio_uuid << llendl; |
@@ -1317,12 +1212,13 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 | |||
1317 | mOwnerID(owner_id), | 1212 | mOwnerID(owner_id), |
1318 | mPriority(0.f), | 1213 | mPriority(0.f), |
1319 | mGain(gain), | 1214 | mGain(gain), |
1320 | mAmbient(false), | 1215 | mType(type), |
1321 | mLoop(false), | 1216 | mAmbient(FALSE), |
1322 | mSyncMaster(false), | 1217 | mLoop(FALSE), |
1323 | mSyncSlave(false), | 1218 | mSyncMaster(FALSE), |
1324 | mQueueSounds(false), | 1219 | mSyncSlave(FALSE), |
1325 | mPlayedOnce(false), | 1220 | mQueueSounds(FALSE), |
1221 | mPlayedOnce(FALSE), | ||
1326 | mChannelp(NULL), | 1222 | mChannelp(NULL), |
1327 | mCurrentDatap(NULL), | 1223 | mCurrentDatap(NULL), |
1328 | mQueuedDatap(NULL) | 1224 | mQueuedDatap(NULL) |
@@ -1468,8 +1364,7 @@ bool LLAudioSource::play(const LLUUID &audio_uuid) | |||
1468 | bool LLAudioSource::isDone() | 1364 | bool LLAudioSource::isDone() |
1469 | { | 1365 | { |
1470 | const F32 MAX_AGE = 60.f; | 1366 | const F32 MAX_AGE = 60.f; |
1471 | const F32 MAX_UNPLAYED_AGE = 15.f; | 1367 | const F32 MAX_UNPLAYED_AGE = 30.f; |
1472 | |||
1473 | if (isLoop()) | 1368 | if (isLoop()) |
1474 | { | 1369 | { |
1475 | // Looped sources never die on their own. | 1370 | // Looped sources never die on their own. |
@@ -1647,8 +1542,9 @@ LLAudioBuffer *LLAudioSource::getCurrentBuffer() | |||
1647 | LLAudioChannel::LLAudioChannel() : | 1542 | LLAudioChannel::LLAudioChannel() : |
1648 | mCurrentSourcep(NULL), | 1543 | mCurrentSourcep(NULL), |
1649 | mCurrentBufferp(NULL), | 1544 | mCurrentBufferp(NULL), |
1650 | mLoopedThisFrame(false), | 1545 | mLoopedThisFrame(FALSE), |
1651 | mWaiting(false) | 1546 | mWaiting(FALSE), |
1547 | mSecondaryGain(1.0f) | ||
1652 | { | 1548 | { |
1653 | } | 1549 | } |
1654 | 1550 | ||
diff --git a/linden/indra/llaudio/audioengine.h b/linden/indra/llaudio/audioengine.h index 94134f5..937a8e1 100644 --- a/linden/indra/llaudio/audioengine.h +++ b/linden/indra/llaudio/audioengine.h | |||
@@ -80,11 +80,23 @@ class LLAudioBuffer; | |||
80 | class LLAudioEngine | 80 | class LLAudioEngine |
81 | { | 81 | { |
82 | public: | 82 | public: |
83 | enum LLAudioType | ||
84 | { | ||
85 | AUDIO_TYPE_NONE = 0, | ||
86 | AUDIO_TYPE_SFX = 1, | ||
87 | AUDIO_TYPE_UI = 2, | ||
88 | AUDIO_TYPE_AMBIENT = 3, | ||
89 | AUDIO_TYPE_COUNT = 4 // last | ||
90 | }; | ||
91 | |||
83 | LLAudioEngine(); | 92 | LLAudioEngine(); |
84 | virtual ~LLAudioEngine(); | 93 | virtual ~LLAudioEngine(); |
85 | 94 | ||
86 | // initialization/startup/shutdown | 95 | // initialization/startup/shutdown |
87 | virtual bool init(const S32 num_channels, void *userdata); | 96 | //virtual BOOL init(); |
97 | |||
98 | virtual BOOL init(const S32 num_channels); | ||
99 | virtual std::string getDriverName(bool verbose) = 0; | ||
88 | virtual void shutdown(); | 100 | virtual void shutdown(); |
89 | 101 | ||
90 | // Used by the mechanics of the engine | 102 | // Used by the mechanics of the engine |
@@ -109,6 +121,9 @@ public: | |||
109 | F32 getMasterGain(); | 121 | F32 getMasterGain(); |
110 | void setMasterGain(F32 gain); | 122 | void setMasterGain(F32 gain); |
111 | 123 | ||
124 | F32 getSecondaryGain(S32 type); | ||
125 | void setSecondaryGain(S32 type, F32 gain); | ||
126 | |||
112 | F32 getInternetStreamGain(); | 127 | F32 getInternetStreamGain(); |
113 | 128 | ||
114 | virtual void setDopplerFactor(F32 factor); | 129 | virtual void setDopplerFactor(F32 factor); |
@@ -122,8 +137,10 @@ public: | |||
122 | 137 | ||
123 | // Methods actually related to setting up and removing sounds | 138 | // Methods actually related to setting up and removing sounds |
124 | // Owner ID is the owner of the object making the request | 139 | // Owner ID is the owner of the object making the request |
125 | void triggerSound(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, const LLVector3d &pos_global = LLVector3d::zero); | 140 | void triggerSound(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, |
126 | bool preloadSound(const LLUUID &id); | 141 | const S32 type = LLAudioEngine::AUDIO_TYPE_NONE, |
142 | const LLVector3d &pos_global = LLVector3d::zero); | ||
143 | BOOL preloadSound(const LLUUID &id); | ||
127 | 144 | ||
128 | void addAudioSource(LLAudioSource *asp); | 145 | void addAudioSource(LLAudioSource *asp); |
129 | void cleanupAudioSource(LLAudioSource *asp); | 146 | void cleanupAudioSource(LLAudioSource *asp); |
@@ -132,16 +149,15 @@ public: | |||
132 | LLAudioData *getAudioData(const LLUUID &audio_uuid); | 149 | LLAudioData *getAudioData(const LLUUID &audio_uuid); |
133 | 150 | ||
134 | 151 | ||
135 | // Internet stream methods | 152 | virtual void startInternetStream(const std::string& url) = 0; |
136 | virtual void startInternetStream(const std::string& url); | 153 | virtual void stopInternetStream() = 0; |
137 | virtual void stopInternetStream(); | 154 | virtual void pauseInternetStream(int pause) = 0; |
138 | virtual void pauseInternetStream(int pause); | 155 | virtual int isInternetStreamPlaying() = 0; |
139 | virtual void updateInternetStream(); | 156 | virtual void getInternetStreamInfo(char* artist, char* title) { artist[0] = 0; title[0] = 0; } |
140 | virtual int isInternetStreamPlaying(); | ||
141 | virtual void getInternetStreamInfo(char* artist, char* title); | ||
142 | // use a value from 0.0 to 1.0, inclusive | 157 | // use a value from 0.0 to 1.0, inclusive |
143 | virtual void setInternetStreamGain(F32 vol); | 158 | virtual void setInternetStreamGain(F32 vol) { mInternetStreamGain = vol; } |
144 | virtual const std::string& getInternetStreamURL(); | 159 | virtual const std::string& getInternetStreamURL() { return LLStringUtil::null; } |
160 | virtual void InitStreamer() = 0; | ||
145 | 161 | ||
146 | // For debugging usage | 162 | // For debugging usage |
147 | virtual LLVector3 getListenerPos(); | 163 | virtual LLVector3 getListenerPos(); |
@@ -177,6 +193,11 @@ protected: | |||
177 | virtual void allocateListener() = 0; | 193 | virtual void allocateListener() = 0; |
178 | 194 | ||
179 | 195 | ||
196 | // Internet stream methods | ||
197 | virtual void initInternetStream() {} | ||
198 | virtual void updateInternetStream() {} | ||
199 | |||
200 | |||
180 | // listener methods | 201 | // listener methods |
181 | virtual void setListenerPos(LLVector3 vec); | 202 | virtual void setListenerPos(LLVector3 vec); |
182 | virtual void setListenerVelocity(LLVector3 vec); | 203 | virtual void setListenerVelocity(LLVector3 vec); |
@@ -191,8 +212,7 @@ protected: | |||
191 | protected: | 212 | protected: |
192 | LLListener *mListenerp; | 213 | LLListener *mListenerp; |
193 | 214 | ||
194 | bool mMuted; | 215 | BOOL mMuted; |
195 | void* mUserData; | ||
196 | 216 | ||
197 | S32 mLastStatus; | 217 | S32 mLastStatus; |
198 | 218 | ||
@@ -218,10 +238,10 @@ protected: | |||
218 | LLAudioBuffer *mBuffers[MAX_BUFFERS]; | 238 | LLAudioBuffer *mBuffers[MAX_BUFFERS]; |
219 | 239 | ||
220 | F32 mMasterGain; | 240 | F32 mMasterGain; |
241 | F32 mSecondaryGain[AUDIO_TYPE_COUNT]; | ||
221 | 242 | ||
222 | // Hack! Internet streams are treated differently from other sources! | 243 | // Hack! Internet streams are treated differently from other sources! |
223 | F32 mInternetStreamGain; | 244 | F32 mInternetStreamGain; |
224 | std::string mInternetStreamURL; | ||
225 | 245 | ||
226 | F32 mNextWindUpdate; | 246 | F32 mNextWindUpdate; |
227 | 247 | ||
@@ -229,7 +249,6 @@ protected: | |||
229 | 249 | ||
230 | private: | 250 | private: |
231 | void setDefaults(); | 251 | void setDefaults(); |
232 | LLMediaBase *mInternetStreamMedia; | ||
233 | }; | 252 | }; |
234 | 253 | ||
235 | 254 | ||
@@ -272,6 +291,9 @@ public: | |||
272 | 291 | ||
273 | void setPlayedOnce(const bool played_once) { mPlayedOnce = played_once; } | 292 | void setPlayedOnce(const bool played_once) { mPlayedOnce = played_once; } |
274 | 293 | ||
294 | void setType(S32 type) { mType = type; } | ||
295 | S32 getType() { return mType; } | ||
296 | |||
275 | void setPositionGlobal(const LLVector3d &position_global) { mPositionGlobal = position_global; } | 297 | void setPositionGlobal(const LLVector3d &position_global) { mPositionGlobal = position_global; } |
276 | LLVector3d getPositionGlobal() const { return mPositionGlobal; } | 298 | LLVector3d getPositionGlobal() const { return mPositionGlobal; } |
277 | LLVector3 getVelocity() const { return mVelocity; } | 299 | LLVector3 getVelocity() const { return mVelocity; } |
@@ -304,12 +326,13 @@ protected: | |||
304 | LLUUID mOwnerID; // owner of the object playing the sound | 326 | LLUUID mOwnerID; // owner of the object playing the sound |
305 | F32 mPriority; | 327 | F32 mPriority; |
306 | F32 mGain; | 328 | F32 mGain; |
307 | bool mAmbient; | 329 | BOOL mAmbient; |
308 | bool mLoop; | 330 | BOOL mLoop; |
309 | bool mSyncMaster; | 331 | BOOL mSyncMaster; |
310 | bool mSyncSlave; | 332 | BOOL mSyncSlave; |
311 | bool mQueueSounds; | 333 | BOOL mQueueSounds; |
312 | bool mPlayedOnce; | 334 | BOOL mPlayedOnce; |
335 | S32 mType; | ||
313 | LLVector3d mPositionGlobal; | 336 | LLVector3d mPositionGlobal; |
314 | LLVector3 mVelocity; | 337 | LLVector3 mVelocity; |
315 | 338 | ||
@@ -378,6 +401,9 @@ public: | |||
378 | virtual void setSource(LLAudioSource *sourcep); | 401 | virtual void setSource(LLAudioSource *sourcep); |
379 | LLAudioSource *getSource() const { return mCurrentSourcep; } | 402 | LLAudioSource *getSource() const { return mCurrentSourcep; } |
380 | 403 | ||
404 | void setSecondaryGain(F32 gain) { mSecondaryGain = gain; } | ||
405 | F32 getSecondaryGain() { return mSecondaryGain; } | ||
406 | |||
381 | friend class LLAudioEngine; | 407 | friend class LLAudioEngine; |
382 | friend class LLAudioSource; | 408 | friend class LLAudioSource; |
383 | protected: | 409 | protected: |
@@ -394,8 +420,9 @@ protected: | |||
394 | protected: | 420 | protected: |
395 | LLAudioSource *mCurrentSourcep; | 421 | LLAudioSource *mCurrentSourcep; |
396 | LLAudioBuffer *mCurrentBufferp; | 422 | LLAudioBuffer *mCurrentBufferp; |
397 | bool mLoopedThisFrame; | 423 | BOOL mLoopedThisFrame; |
398 | bool mWaiting; // Waiting for sync. | 424 | BOOL mWaiting; // Waiting for sync. |
425 | F32 mSecondaryGain; | ||
399 | }; | 426 | }; |
400 | 427 | ||
401 | 428 | ||
diff --git a/linden/indra/llaudio/audioengine_openal.cpp b/linden/indra/llaudio/audioengine_openal.cpp index 85d2080..65203dd 100644 --- a/linden/indra/llaudio/audioengine_openal.cpp +++ b/linden/indra/llaudio/audioengine_openal.cpp | |||
@@ -36,29 +36,31 @@ | |||
36 | #include "audioengine_openal.h" | 36 | #include "audioengine_openal.h" |
37 | #include "listener_openal.h" | 37 | #include "listener_openal.h" |
38 | 38 | ||
39 | LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() | ||
40 | { | ||
39 | 41 | ||
40 | // Variables and definitions for Wind | 42 | #if LL_GSTREAMER_ENABLED |
41 | #define MAX_NUM_WIND_BUFFERS 40 | 43 | mMedia_data = new LLMediaManagerData; |
42 | static int empty_num_wind_buffers = MAX_NUM_WIND_BUFFERS; | 44 | // initialize GStreamer |
43 | static const float wind_buffer_size_sec = 0.05f; // 1/20th sec | 45 | LLMediaImplGStreamer::startup( mMedia_data ); |
44 | static const U32 wind_gen_freq = LLWindGen<S16>::getInputSamplingRate(); | ||
45 | static ALuint wind_source; | ||
46 | static S16 *winddata=NULL; | ||
47 | 46 | ||
47 | m_streamer=new LLMediaImplGStreamer (); | ||
48 | 48 | ||
49 | LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() | 49 | if(!m_streamer) |
50 | { | 50 | { |
51 | mWindGen = NULL; | 51 | llwarns << "LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() Failed to create our private gstreamer audio instance" << llendl; |
52 | } | ||
53 | #endif | ||
52 | } | 54 | } |
53 | 55 | ||
54 | LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL() | 56 | LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL() |
55 | { | 57 | { |
56 | } | 58 | } |
57 | 59 | ||
58 | bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata) | 60 | |
61 | BOOL LLAudioEngine_OpenAL::init(const S32 num_channels) | ||
59 | { | 62 | { |
60 | mWindGen = NULL; | 63 | LLAudioEngine::init(num_channels); |
61 | LLAudioEngine::init(num_channels, userdata); | ||
62 | 64 | ||
63 | if(!alutInit(NULL, NULL)) | 65 | if(!alutInit(NULL, NULL)) |
64 | { | 66 | { |
@@ -66,35 +68,61 @@ bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata) | |||
66 | return false; | 68 | return false; |
67 | } | 69 | } |
68 | 70 | ||
71 | initInternetStream(); | ||
72 | |||
69 | llinfos << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << llendl; | 73 | llinfos << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << llendl; |
70 | 74 | ||
71 | llinfos << "OpenAL version: " | 75 | llinfos << "LLAudioEngine_OpenAL::init() Speed of sound is: " << alGetFloat(AL_SPEED_OF_SOUND) << llendl; |
72 | << ll_safe_string(alGetString(AL_VERSION)) << llendl; | ||
73 | llinfos << "OpenAL vendor: " | ||
74 | << ll_safe_string(alGetString(AL_VENDOR)) << llendl; | ||
75 | llinfos << "OpenAL renderer: " | ||
76 | << ll_safe_string(alGetString(AL_RENDERER)) << llendl; | ||
77 | 76 | ||
78 | ALint major = alutGetMajorVersion (); | 77 | return TRUE; |
79 | ALint minor = alutGetMinorVersion (); | 78 | } |
80 | llinfos << "ALUT version: " << major << "." << minor << llendl; | ||
81 | 79 | ||
80 | std::string LLAudioEngine_OpenAL::getDriverName(bool verbose) | ||
81 | { | ||
82 | ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext()); | 82 | ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext()); |
83 | |||
84 | std::ostringstream version; | ||
85 | |||
86 | ALint major = alutGetMajorVersion (); | ||
87 | ALint minor = alutGetMinorVersion (); | ||
83 | 88 | ||
84 | alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major); | 89 | alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major); |
85 | alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &minor); | 90 | alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &minor); |
86 | llinfos << "ALC version: " << major << "." << minor << llendl; | ||
87 | 91 | ||
88 | llinfos << "ALC default device: " | 92 | version << |
89 | << ll_safe_string(alcGetString(device, | 93 | "OpenAL"; |
90 | ALC_DEFAULT_DEVICE_SPECIFIER)) | ||
91 | << llendl; | ||
92 | 94 | ||
93 | llinfos << "LLAudioEngine_OpenAL::init() Speed of sound is: " << alGetFloat(AL_SPEED_OF_SOUND) << llendl; | 95 | if (verbose) |
96 | { | ||
97 | version << | ||
98 | ", version " << | ||
99 | ll_safe_string(alGetString(AL_VERSION)) << | ||
100 | " / " << | ||
101 | ll_safe_string(alGetString(AL_VENDOR)) << | ||
102 | " / " << | ||
103 | ll_safe_string(alGetString(AL_RENDERER)); | ||
104 | |||
105 | if (device) | ||
106 | version << | ||
107 | ": " << | ||
108 | ll_safe_string(alcGetString(device, | ||
109 | ALC_DEFAULT_DEVICE_SPECIFIER)); | ||
110 | } | ||
94 | 111 | ||
95 | return true; | 112 | return version.str(); |
113 | } | ||
114 | |||
115 | |||
116 | void LLAudioEngine_OpenAL::idle(F32 max_decode_time) | ||
117 | { | ||
118 | LLAudioEngine::idle(max_decode_time); | ||
119 | #if LL_GSTREAMER_ENABLED | ||
120 | if(m_streamer != NULL) | ||
121 | m_streamer->updateMedia(); | ||
122 | #endif | ||
96 | } | 123 | } |
97 | 124 | ||
125 | |||
98 | void LLAudioEngine_OpenAL::allocateListener() | 126 | void LLAudioEngine_OpenAL::allocateListener() |
99 | { | 127 | { |
100 | mListenerp = (LLListener *) new LLListener_OpenAL(); | 128 | mListenerp = (LLListener *) new LLListener_OpenAL(); |
@@ -115,11 +143,21 @@ void LLAudioEngine_OpenAL::shutdown() | |||
115 | llwarns << "Nuts." << llendl; | 143 | llwarns << "Nuts." << llendl; |
116 | llwarns << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << llendl; | 144 | llwarns << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << llendl; |
117 | } | 145 | } |
118 | 146 | else | |
119 | llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl; | 147 | { |
120 | 148 | llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl; | |
149 | } | ||
150 | |||
121 | delete mListenerp; | 151 | delete mListenerp; |
122 | mListenerp = NULL; | 152 | mListenerp = NULL; |
153 | |||
154 | #if LL_GSTREAMER_ENABLED | ||
155 | if(m_streamer) | ||
156 | { | ||
157 | delete m_streamer; | ||
158 | m_streamer = NULL; | ||
159 | } | ||
160 | #endif | ||
123 | } | 161 | } |
124 | 162 | ||
125 | LLAudioBuffer *LLAudioEngine_OpenAL::createBuffer() | 163 | LLAudioBuffer *LLAudioEngine_OpenAL::createBuffer() |
@@ -140,26 +178,27 @@ void LLAudioEngine_OpenAL::setInternalGain(F32 gain) | |||
140 | 178 | ||
141 | LLAudioChannelOpenAL::LLAudioChannelOpenAL() | 179 | LLAudioChannelOpenAL::LLAudioChannelOpenAL() |
142 | { | 180 | { |
143 | alGenSources(1, &mALSource); | 181 | alGenSources(1, &ALSource); |
144 | } | 182 | } |
145 | 183 | ||
146 | LLAudioChannelOpenAL::~LLAudioChannelOpenAL() | 184 | LLAudioChannelOpenAL::~LLAudioChannelOpenAL() |
147 | { | 185 | { |
148 | cleanup(); | 186 | cleanup(); |
149 | alDeleteSources(1, &mALSource); | 187 | alDeleteSources(1, &ALSource); |
150 | } | 188 | } |
151 | 189 | ||
152 | void LLAudioChannelOpenAL::cleanup() | 190 | void LLAudioChannelOpenAL::cleanup() |
153 | { | 191 | { |
154 | alSourceStop(mALSource); | 192 | alSourceStop(ALSource); |
155 | mCurrentBufferp = NULL; | 193 | mCurrentBufferp = NULL; |
156 | } | 194 | } |
157 | 195 | ||
158 | void LLAudioChannelOpenAL::play() | 196 | void LLAudioChannelOpenAL::play() |
159 | { | 197 | { |
160 | if(!isPlaying()){ | 198 | if(!isPlaying()) |
161 | alSourcePlay(mALSource); | 199 | { |
162 | getSource()->setPlayedOnce(true); | 200 | alSourcePlay(ALSource); |
201 | getSource()->setPlayedOnce(TRUE); | ||
163 | } | 202 | } |
164 | } | 203 | } |
165 | 204 | ||
@@ -171,9 +210,10 @@ void LLAudioChannelOpenAL::playSynced(LLAudioChannel *channelp) | |||
171 | bool LLAudioChannelOpenAL::isPlaying() | 210 | bool LLAudioChannelOpenAL::isPlaying() |
172 | { | 211 | { |
173 | ALint state; | 212 | ALint state; |
174 | alGetSourcei(mALSource, AL_SOURCE_STATE, &state); | 213 | alGetSourcei(ALSource, AL_SOURCE_STATE, &state); |
175 | if(state == AL_PLAYING){ | 214 | if(state == AL_PLAYING) |
176 | return true; | 215 | { |
216 | return TRUE; | ||
177 | } | 217 | } |
178 | return false; | 218 | return false; |
179 | } | 219 | } |
@@ -185,9 +225,9 @@ bool LLAudioChannelOpenAL::updateBuffer() | |||
185 | // Base class update returned true, which means that we need to actually | 225 | // Base class update returned true, which means that we need to actually |
186 | // set up the source for a different buffer. | 226 | // set up the source for a different buffer. |
187 | LLAudioBufferOpenAL *bufferp = (LLAudioBufferOpenAL *)mCurrentSourcep->getCurrentBuffer(); | 227 | LLAudioBufferOpenAL *bufferp = (LLAudioBufferOpenAL *)mCurrentSourcep->getCurrentBuffer(); |
188 | alSourcei(mALSource, AL_BUFFER, bufferp->getBuffer()); | 228 | alSourcei(ALSource, AL_BUFFER, bufferp->getBuffer()); |
189 | alSourcef(mALSource, AL_GAIN, mCurrentSourcep->getGain()); | 229 | alSourcef(ALSource, AL_GAIN, mCurrentSourcep->getGain()); |
190 | alSourcei(mALSource, AL_LOOPING, mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE); | 230 | alSourcei(ALSource, AL_LOOPING, mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE); |
191 | } | 231 | } |
192 | 232 | ||
193 | return true; | 233 | return true; |
@@ -201,28 +241,30 @@ void LLAudioChannelOpenAL::update3DPosition() | |||
201 | } | 241 | } |
202 | if (mCurrentSourcep->isAmbient()) | 242 | if (mCurrentSourcep->isAmbient()) |
203 | { | 243 | { |
204 | alSource3f(mALSource, AL_POSITION, 0.0, 0.0, 0.0); | 244 | alSource3f(ALSource, AL_POSITION, 0.0, 0.0, 0.0); |
205 | alSource3f(mALSource, AL_VELOCITY, 0.0, 0.0, 0.0); | 245 | alSource3f(ALSource, AL_VELOCITY, 0.0, 0.0, 0.0); |
206 | //alSource3f(mALSource, AL_DIRECTION, 0.0, 0.0, 0.0); | 246 | //alSource3f(ALSource, AL_DIRECTION, 0.0, 0.0, 0.0); |
207 | alSourcef (mALSource, AL_ROLLOFF_FACTOR, 0.0); | 247 | alSourcef (ALSource, AL_ROLLOFF_FACTOR, 0.0); |
208 | alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_TRUE); | 248 | alSourcei (ALSource, AL_SOURCE_RELATIVE, AL_TRUE); |
209 | } else { | 249 | } |
250 | else | ||
251 | { | ||
210 | LLVector3 float_pos; | 252 | LLVector3 float_pos; |
211 | float_pos.setVec(mCurrentSourcep->getPositionGlobal()); | 253 | float_pos.setVec(mCurrentSourcep->getPositionGlobal()); |
212 | alSourcefv(mALSource, AL_POSITION, float_pos.mV); | 254 | alSourcefv(ALSource, AL_POSITION, float_pos.mV); |
213 | //llinfos << "LLAudioChannelOpenAL::update3DPosition() Velocity: " << mCurrentSourcep->getVelocity() << llendl; | 255 | //llinfos << "LLAudioChannelOpenAL::update3DPosition() Velocity: " << mCurrentSourcep->getVelocity() << llendl; |
214 | alSourcefv(mALSource, AL_VELOCITY, mCurrentSourcep->getVelocity().mV); | 256 | alSourcefv(ALSource, AL_VELOCITY, mCurrentSourcep->getVelocity().mV); |
215 | //alSource3f(mALSource, AL_DIRECTION, 0.0, 0.0, 0.0); | 257 | //alSource3f(ALSource, AL_DIRECTION, 0.0, 0.0, 0.0); |
216 | alSourcef (mALSource, AL_ROLLOFF_FACTOR, 1.0); | 258 | alSourcef (ALSource, AL_ROLLOFF_FACTOR, 1.0); |
217 | alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_FALSE); | 259 | alSourcei (ALSource, AL_SOURCE_RELATIVE, AL_FALSE); |
218 | } | 260 | } |
219 | //llinfos << "LLAudioChannelOpenAL::update3DPosition() Gain: " << mCurrentSourcep->getGain() << llendl; | 261 | //llinfos << "LLAudioChannelOpenAL::update3DPosition() Gain: " << mCurrentSourcep->getGain() << llendl; |
220 | alSourcef(mALSource, AL_GAIN, mCurrentSourcep->getGain()); | 262 | alSourcef(ALSource, AL_GAIN, mCurrentSourcep->getGain()); |
221 | } | 263 | } |
222 | 264 | ||
223 | LLAudioBufferOpenAL::LLAudioBufferOpenAL() | 265 | LLAudioBufferOpenAL::LLAudioBufferOpenAL() |
224 | { | 266 | { |
225 | mALBuffer = AL_NONE; | 267 | ALBuffer = AL_NONE; |
226 | } | 268 | } |
227 | 269 | ||
228 | LLAudioBufferOpenAL::~LLAudioBufferOpenAL() | 270 | LLAudioBufferOpenAL::~LLAudioBufferOpenAL() |
@@ -232,99 +274,99 @@ LLAudioBufferOpenAL::~LLAudioBufferOpenAL() | |||
232 | 274 | ||
233 | void LLAudioBufferOpenAL::cleanup() | 275 | void LLAudioBufferOpenAL::cleanup() |
234 | { | 276 | { |
235 | if(mALBuffer != AL_NONE) | 277 | if(ALBuffer != AL_NONE) |
236 | { | 278 | { |
237 | alDeleteBuffers(1, &mALBuffer); | 279 | alDeleteBuffers(1, &ALBuffer); |
238 | mALBuffer = AL_NONE; | ||
239 | } | 280 | } |
240 | } | 281 | } |
241 | 282 | ||
242 | bool LLAudioBufferOpenAL::loadWAV(const std::string& filename) | 283 | bool LLAudioBufferOpenAL::loadWAV(const std::string& filename) |
243 | { | 284 | { |
244 | cleanup(); | 285 | cleanup(); |
245 | mALBuffer = alutCreateBufferFromFile(filename.c_str()); | 286 | ALBuffer = alutCreateBufferFromFile(filename.c_str()); |
246 | if(mALBuffer == AL_NONE){ | 287 | if(ALBuffer == AL_NONE) |
247 | ALenum error = alutGetError(); | 288 | { |
248 | if (gDirUtilp->fileExists(filename)) { | 289 | return FALSE; |
249 | llwarns << | ||
250 | "LLAudioBufferOpenAL::loadWAV() Error loading " | ||
251 | << filename | ||
252 | << " " << alutGetErrorString(error) << llendl; | ||
253 | } else { | ||
254 | // It's common for the file to not actually exist. | ||
255 | lldebugs << | ||
256 | "LLAudioBufferOpenAL::loadWAV() Error loading " | ||
257 | << filename | ||
258 | << " " << alutGetErrorString(error) << llendl; | ||
259 | } | ||
260 | return false; | ||
261 | } | 290 | } |
262 | 291 | ||
263 | return true; | 292 | return true; |
264 | } | 293 | } |
265 | 294 | ||
266 | U32 LLAudioBufferOpenAL::getLength(){ | 295 | |
267 | if(mALBuffer == AL_NONE){ | 296 | U32 LLAudioBufferOpenAL::getLength() |
297 | { | ||
298 | if(ALBuffer == AL_NONE) | ||
299 | { | ||
268 | return 0; | 300 | return 0; |
269 | } | 301 | } |
270 | ALint length; | 302 | ALint length; |
271 | alGetBufferi(mALBuffer, AL_SIZE, &length); | 303 | alGetBufferi(ALBuffer, AL_SIZE, &length); |
272 | return length >> 2; | 304 | return length >> 2; |
273 | } | 305 | } |
274 | 306 | ||
275 | // ------------ | 307 | // ------------ |
276 | 308 | ||
277 | void LLAudioEngine_OpenAL::initWind(){ | 309 | void LLAudioEngine_OpenAL::initWind() |
278 | ALenum error; | 310 | { |
279 | llinfos << "LLAudioEngine_OpenAL::initWind() start" << llendl; | ||
280 | 311 | ||
281 | alGetError(); /* clear error */ | 312 | if (true) |
282 | 313 | return; | |
283 | alGenSources(1,&wind_source); | ||
284 | |||
285 | if((error=alGetError()) != AL_NO_ERROR) | ||
286 | { | ||
287 | llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: "<<error<<llendl; | ||
288 | } | ||
289 | |||
290 | winddata=(S16*)malloc(sizeof(S16)*llceil(wind_gen_freq*wind_buffer_size_sec*2*2)); //200ms @wind_gen_freqHz Stereo | ||
291 | 314 | ||
292 | if(winddata==NULL) | 315 | llinfos << "initWind() start" << llendl; |
316 | |||
317 | alGenBuffers(mNumWindBuffers,mWindBuffers); | ||
318 | alGenSources(1,&mWindSource); | ||
319 | checkALError(); | ||
320 | |||
321 | // ok lets make a wind buffer now | ||
322 | for(int counter=0;counter<mNumWindBuffers;counter++) | ||
293 | { | 323 | { |
294 | llerrs << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << llendl; | 324 | |
295 | mEnableWind=false; | 325 | alBufferData(mWindBuffers[counter],AL_FORMAT_STEREO16,windDSP((void*)mWindData,mWindDataSize/mBytesPerSample),mWindDataSize,mSampleRate); |
326 | checkALError(); | ||
296 | } | 327 | } |
297 | 328 | ||
298 | mWindGen = new LLWindGen<S16>; | 329 | alSourceQueueBuffers(mWindSource, mNumWindBuffers, mWindBuffers); |
330 | checkALError(); | ||
331 | |||
332 | alSourcePlay(mWindSource); | ||
333 | checkALError(); | ||
299 | 334 | ||
300 | llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl; | 335 | llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl; |
336 | |||
301 | } | 337 | } |
302 | 338 | ||
303 | void LLAudioEngine_OpenAL::cleanupWind(){ | 339 | void LLAudioEngine_OpenAL::cleanupWind(){ |
304 | llinfos << "LLAudioEngine_OpenAL::cleanupWind()" << llendl; | 340 | llinfos << "LLAudioEngine_OpenAL::cleanupWind()" << llendl; |
305 | 341 | ||
306 | alDeleteSources(1, &wind_source); | 342 | alDeleteBuffers(mNumWindBuffers,mWindBuffers); |
307 | 343 | alDeleteSources(1, &mWindSource); | |
308 | if(winddata) | 344 | |
309 | free(winddata); | 345 | checkALError(); |
346 | } | ||
347 | |||
348 | void LLAudioEngine_OpenAL::checkALError() | ||
349 | { | ||
350 | ALenum error; | ||
351 | if((error=alGetError()) != AL_NO_ERROR) | ||
352 | llwarns << "LLAudioEngine_OpenAL Error: "<<error<<llendl; | ||
310 | 353 | ||
311 | delete mWindGen; | ||
312 | mWindGen = NULL; | ||
313 | } | 354 | } |
314 | 355 | ||
315 | void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) | 356 | void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) |
316 | { | 357 | { |
358 | |||
359 | if (true) | ||
360 | return; | ||
361 | |||
317 | LLVector3 wind_pos; | 362 | LLVector3 wind_pos; |
318 | F64 pitch; | 363 | F32 pitch; |
319 | F64 center_freq; | 364 | F32 center_freq; |
320 | ALenum error; | 365 | |
321 | 366 | if (!mEnableWind) | |
322 | mMaxWindGain=1.0; | ||
323 | |||
324 | if (mEnableWind) | ||
325 | return; | 367 | return; |
326 | 368 | ||
327 | if(winddata) | 369 | if(!mWindData) |
328 | return; | 370 | return; |
329 | 371 | ||
330 | if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL)) | 372 | if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL)) |
@@ -335,88 +377,385 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) | |||
335 | // where +X = right, +Y = up, +Z = backwards | 377 | // where +X = right, +Y = up, +Z = backwards |
336 | 378 | ||
337 | wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]); | 379 | wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]); |
338 | |||
339 | pitch = 1.0 + mapWindVecToPitch(wind_vec); | ||
340 | center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0)); | ||
341 | |||
342 | mWindGen->mTargetFreq = (F32)center_freq; | ||
343 | mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; | ||
344 | mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec); | ||
345 | |||
346 | alSourcei(wind_source, AL_LOOPING, AL_FALSE); | ||
347 | alSource3f(wind_source, AL_POSITION, 0.0, 0.0, 0.0); | ||
348 | alSource3f(wind_source, AL_VELOCITY, 0.0, 0.0, 0.0); | ||
349 | alSourcef(wind_source, AL_ROLLOFF_FACTOR, 0.0); | ||
350 | alSourcei(wind_source, AL_SOURCE_RELATIVE, AL_TRUE); | ||
351 | } | ||
352 | 380 | ||
353 | // ok lets make a wind buffer now | ||
354 | 381 | ||
355 | int processed, queued, unprocessed; | 382 | pitch = 1.0f + mapWindVecToPitch(wind_vec); |
356 | alGetSourcei(wind_source, AL_BUFFERS_PROCESSED, &processed); | 383 | center_freq = 80.0f * powf(pitch,2.5f*(mapWindVecToGain(wind_vec)+1.0f)); |
357 | alGetSourcei(wind_source, AL_BUFFERS_QUEUED, &queued); | ||
358 | unprocessed = queued - processed; | ||
359 | 384 | ||
360 | // ensure that there are always at least 3x as many filled buffers | 385 | //TESTING |
361 | // queued as we managed to empty since last time. | 386 | mMaxWindGain=1.0; |
362 | empty_num_wind_buffers = llmin(empty_num_wind_buffers + processed * 3 - unprocessed, MAX_NUM_WIND_BUFFERS-unprocessed); | ||
363 | empty_num_wind_buffers = llmax(empty_num_wind_buffers, 0); | ||
364 | 387 | ||
365 | //llinfos << "empty_num_wind_buffers: " << empty_num_wind_buffers <<" (" << unprocessed << ":" << processed << ")" << llendl; | 388 | mTargetFreq = center_freq; |
389 | mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; | ||
390 | mTargetPanGainR = (F32)mapWindVecToPan(wind_vec); | ||
366 | 391 | ||
367 | while(processed--) // unqueue old buffers | 392 | ALfloat source0Pos[]={mListenerp->getPosition().mV[0],mListenerp->getPosition().mV[1],mListenerp->getPosition().mV[2]}; |
393 | ALfloat source0Vel[]={ 0.0, 0.0, 0.0}; | ||
394 | |||
395 | alSourcef(mWindSource, AL_GAIN, mTargetGain); | ||
396 | alSourcef(mWindSource, AL_PITCH, pitch); | ||
397 | alSourcefv(mWindSource, AL_POSITION, source0Pos); | ||
398 | alSourcefv(mWindSource, AL_VELOCITY, source0Vel); | ||
399 | alSourcei(mWindSource, AL_LOOPING, AL_FALSE); | ||
400 | |||
401 | } | ||
402 | |||
403 | int processed; | ||
404 | alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed); | ||
405 | |||
406 | while(processed--) | ||
368 | { | 407 | { |
369 | ALuint buffer; | 408 | ALuint buffer; |
370 | int error; | 409 | alSourceUnqueueBuffers(mWindSource, 1, &buffer); |
371 | alGetError(); /* clear error */ | 410 | checkALError(); |
372 | alSourceUnqueueBuffers(wind_source, 1, &buffer); | 411 | alBufferData(buffer,AL_FORMAT_STEREO16,windDSP((void*)mWindData,mWindDataSize/mBytesPerSample),mWindDataSize,mSampleRate); |
373 | error = alGetError(); | 412 | checkALError(); |
374 | if(error != AL_NO_ERROR) | 413 | alSourceQueueBuffers(mWindSource, 1, &buffer); |
375 | { | 414 | checkALError(); |
376 | llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << llendl; | 415 | } |
377 | } | 416 | |
378 | else | 417 | int playing; |
418 | alGetSourcei(mWindSource, AL_SOURCE_STATE, &playing); | ||
419 | if(playing==AL_STOPPED) | ||
420 | alSourcePlay(mWindSource); | ||
421 | |||
422 | checkALError(); | ||
423 | } | ||
424 | |||
425 | |||
426 | void * LLAudioEngine_OpenAL::windDSP(void *newbuffer, int length) | ||
427 | { | ||
428 | // *NOTE: This function gets called a *lot*. | ||
429 | // Keep performance in mind if you mess with this. | ||
430 | // newbuffer = the buffer being constructed | ||
431 | // length = length in samples of the buffer | ||
432 | |||
433 | |||
434 | //clear the buffer | ||
435 | memset(newbuffer, 0, length*mBytesPerSample); | ||
436 | |||
437 | // This turns off wind synth if it is muted or very very low volume | ||
438 | if (mTargetGain < 0.0005f) | ||
439 | { | ||
440 | llinfos << "Wind off" << llendl; | ||
441 | return newbuffer; | ||
442 | } | ||
443 | |||
444 | static const U8 SUBSAMPLES = 2; | ||
445 | static const F32 FILTER_SAMPLE_PERIOD = (F32)SUBSAMPLES / float(mSampleRate); | ||
446 | static const F32 BANDWIDTH = 50.0f; | ||
447 | static const F32 B2 = expf(-F_TWO_PI * BANDWIDTH * FILTER_SAMPLE_PERIOD); | ||
448 | |||
449 | static F32 pinking_buf0 = 0.0f; | ||
450 | static F32 pinking_buf1 = 0.0f; | ||
451 | static F32 pinking_buf2 = 0.0f; | ||
452 | static F32 Y0 = 0.0f; | ||
453 | static F32 Y1 = 0.0f; | ||
454 | static F32 last_sample = 0.0f; | ||
455 | static F32 current_freq = 0.0f; | ||
456 | static F32 current_gain = 0.0f; | ||
457 | static F32 current_pan_gain_r = 0.0f; | ||
458 | |||
459 | F32 a0 = 0.0f, b1 = 0.0f; | ||
460 | |||
461 | U8 *cursamplep = (U8*)newbuffer; | ||
462 | |||
463 | //we assume 16-bit samples, because the ALUT specification maxes out there | ||
464 | U8 wordsize = 2; | ||
465 | |||
466 | bool interp_freq = false; | ||
467 | |||
468 | //if the frequency isn't changing much, we don't need to interpolate in the inner loop | ||
469 | if (llabs(mTargetFreq - current_freq) > 200.0f) | ||
470 | { | ||
471 | interp_freq = true; | ||
472 | } | ||
473 | else | ||
474 | { | ||
475 | // calculate resonant filter coefficients | ||
476 | current_freq = mTargetFreq; | ||
477 | b1 = (-4.0f * B2) / (1.0f + B2) * cosf(F_TWO_PI * (current_freq * FILTER_SAMPLE_PERIOD)); | ||
478 | a0 = (1.0f - B2) * sqrtf(1.0f - (b1 * b1) / (4.0f * B2)); | ||
479 | } | ||
480 | |||
481 | while (length) | ||
482 | { | ||
483 | F32 next_sample; | ||
484 | |||
485 | // Start with white noise [-16384, 16383] | ||
486 | next_sample = (F32)rand() * (1.0f / (F32)(RAND_MAX / (U16_MAX / 4))) + (S16_MIN / 4); | ||
487 | |||
488 | // Apply a pinking filter | ||
489 | // Magic numbers taken from PKE method at http://www.firstpr.com.au/dsp/pink-noise/ | ||
490 | pinking_buf0 = pinking_buf0 * 0.99765f + next_sample * 0.0990460f; | ||
491 | pinking_buf1 = pinking_buf1 * 0.96300f + next_sample * 0.2965164f; | ||
492 | pinking_buf2 = pinking_buf2 * 0.57000f + next_sample * 1.0526913f; | ||
493 | |||
494 | next_sample = pinking_buf0 + pinking_buf1 + pinking_buf2 + next_sample * 0.1848f; | ||
495 | |||
496 | if (interp_freq) | ||
497 | { | ||
498 | // calculate resonant filter coefficients | ||
499 | current_freq = (0.999f * current_freq) + (0.001f * mTargetFreq); | ||
500 | b1 = (-4.0f * B2) / (1.0f + B2) * cosf(F_TWO_PI * (current_freq * FILTER_SAMPLE_PERIOD)); | ||
501 | a0 = (1.0f - B2) * sqrtf(1.0f - (b1 * b1) / (4.0f * B2)); | ||
502 | } | ||
503 | |||
504 | // Apply a resonant low-pass filter on the pink noise | ||
505 | next_sample = ( a0 * next_sample - b1 * Y0 - B2 * Y1 ); | ||
506 | |||
507 | Y1 = Y0; | ||
508 | Y0 = next_sample; | ||
509 | |||
510 | current_gain = (0.999f * current_gain) + (0.001f * mTargetGain); | ||
511 | current_pan_gain_r = (0.999f * current_pan_gain_r) + (0.001f * mTargetPanGainR); | ||
512 | |||
513 | next_sample *= current_gain; | ||
514 | F32 delta = (next_sample - last_sample) / (F32)SUBSAMPLES; | ||
515 | |||
516 | S32 sample_left; | ||
517 | S32 sample_right; | ||
518 | |||
519 | // Mix into the audio buffer, clipping if necessary for 16-bit mix buffers. | ||
520 | // *TODO: Should do something more intelligent like reducing wind gain to avoid clipping | ||
521 | for (int i=SUBSAMPLES; i && length; --i, --length) | ||
522 | { | ||
523 | last_sample = last_sample + delta; | ||
524 | sample_right = (S32)(last_sample * current_pan_gain_r); | ||
525 | sample_left = (S32)(last_sample - sample_right); | ||
526 | |||
527 | *(S16*)cursamplep = llclamp(sample_left, S16_MIN, S16_MAX); | ||
528 | cursamplep += wordsize; | ||
529 | |||
530 | *(S16*)cursamplep = llclamp(sample_right, S16_MIN, S16_MAX); | ||
531 | cursamplep += wordsize; | ||
532 | } | ||
533 | } | ||
534 | return newbuffer; | ||
535 | |||
536 | } | ||
537 | |||
538 | |||
539 | |||
540 | |||
541 | /* | ||
542 | |||
543 | |||
544 | |||
545 | |||
546 | // newbuffer = the buffer passed from the previous DSP unit. | ||
547 | // length = length in samples at this mix time. | ||
548 | |||
549 | U8 *cursamplep = (U8*)newbuffer; | ||
550 | U8 wordsize = 2; | ||
551 | |||
552 | double bandwidth = 50; | ||
553 | double inputSamplingRate = 44100; | ||
554 | double a0,b1,b2; | ||
555 | |||
556 | // calculate resonant filter coeffs | ||
557 | b2 = exp(-(F_TWO_PI) * (bandwidth / inputSamplingRate)); | ||
558 | |||
559 | while (length--) | ||
560 | { | ||
561 | gCurrentFreq = (float)((0.999 * gCurrentFreq) + (0.001 * gTargetFreq)); | ||
562 | gCurrentGain = (float)((0.999 * gCurrentGain) + (0.001 * gTargetGain)); | ||
563 | gCurrentPanGainR = (float)((0.999 * gCurrentPanGainR) + (0.001 * gTargetPanGainR)); | ||
564 | b1 = (-4.0 * b2) / (1.0 + b2) * cos(F_TWO_PI * (gCurrentFreq / inputSamplingRate)); | ||
565 | a0 = (1.0 - b2) * sqrt(1.0 - (b1 * b1) / (4.0 * b2)); | ||
566 | double nextSample; | ||
567 | |||
568 | // start with white noise | ||
569 | nextSample = ll_frand(2.0f) - 1.0f; | ||
570 | |||
571 | gbuf0 = 0.997f * gbuf0 + 0.0126502f * nextSample; | ||
572 | gbuf1 = 0.985f * gbuf1 + 0.0139083f * nextSample; | ||
573 | gbuf2 = 0.950f * gbuf2 + 0.0205439f * nextSample; | ||
574 | gbuf3 = 0.850f * gbuf3 + 0.0387225f * nextSample; | ||
575 | gbuf4 = 0.620f * gbuf4 + 0.0465932f * nextSample; | ||
576 | gbuf5 = 0.250f * gbuf5 + 0.1093477f * nextSample; | ||
577 | |||
578 | nextSample = gbuf0 + gbuf1 + gbuf2 + gbuf3 + gbuf4 + gbuf5; | ||
579 | |||
580 | nextSample = (double)( a0 * nextSample - b1 * gY0 - b2 * gY1 ); | ||
581 | |||
582 | gY1 = gY0; | ||
583 | gY0 = nextSample; | ||
584 | nextSample *= gCurrentGain; | ||
585 | |||
586 | S16 sample; | ||
587 | |||
588 | sample = llfloor(((F32)nextSample*32768.f*(1.0f - gCurrentPanGainR))+0.5f); | ||
589 | *(S16*)cursamplep = clipSample(sample, -32768, 32767); | ||
590 | |||
591 | cursamplep += wordsize; | ||
592 | |||
593 | sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f); | ||
594 | |||
595 | sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f); | ||
596 | *(S16*)cursamplep = clipSample(sample, -32768, 32767); | ||
597 | cursamplep += wordsize; | ||
598 | } | ||
599 | |||
600 | return newbuffer; | ||
601 | } | ||
602 | */ | ||
603 | |||
604 | // ------------ | ||
605 | |||
606 | void LLAudioEngine_OpenAL::InitStreamer() | ||
607 | { | ||
608 | #if LL_GSTREAMER_ENABLED | ||
609 | m_streamer=new LLMediaImplGStreamer (); | ||
610 | |||
611 | if(!m_streamer) | ||
612 | { | ||
613 | llwarns << "LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() Failed to create our private gstreamer audio instance" << llendl; | ||
614 | } | ||
615 | |||
616 | if(m_streamer) | ||
617 | { | ||
618 | m_streamer->init (); | ||
619 | } | ||
620 | #endif | ||
621 | } | ||
622 | |||
623 | |||
624 | // ------------ | ||
625 | |||
626 | void LLAudioEngine_OpenAL::initInternetStream() | ||
627 | { | ||
628 | if(!mInternetStreamURL.empty()) | ||
629 | mInternetStreamURL.erase(); | ||
630 | } | ||
631 | |||
632 | |||
633 | void LLAudioEngine_OpenAL::startInternetStream(const std::string& url_cstr) | ||
634 | { | ||
635 | |||
636 | std::string url(url_cstr); | ||
637 | |||
638 | #if LL_GSTREAMER_ENABLED | ||
639 | if(!m_streamer) | ||
640 | return; | ||
641 | // DCF_DEBUG | ||
642 | llinfos << "entered LLAudioEngine_OpenAL::startInternetStream()" << llendl; | ||
643 | |||
644 | if (!url.empty()) | ||
645 | { | ||
646 | llinfos << "LLAudioEngine_OpenAL::startInternetStream() Starting internet stream: " << url << llendl; | ||
647 | mInternetStreamURL=url; | ||
648 | m_streamer->navigateTo ( url ); | ||
649 | llinfos << "Playing....." << llendl; | ||
650 | m_streamer->addCommand(LLMediaBase::COMMAND_START); | ||
651 | m_streamer->updateMedia(); | ||
652 | |||
653 | } | ||
654 | else | ||
655 | { | ||
656 | llinfos << "LLAudioEngine_OpenAL setting stream to NULL"<< llendl; | ||
657 | mInternetStreamURL.erase(); | ||
658 | m_streamer->addCommand(LLMediaBase::COMMAND_STOP); | ||
659 | m_streamer->updateMedia(); | ||
660 | } | ||
661 | #endif | ||
662 | } | ||
663 | |||
664 | |||
665 | void LLAudioEngine_OpenAL::updateInternetStream() | ||
666 | { | ||
667 | // DCF_DEBUG | ||
668 | llinfos << "entered LLAudioEngine_OpenAL::updateInternetStream()" << llendl; | ||
669 | |||
670 | } | ||
671 | |||
672 | |||
673 | void LLAudioEngine_OpenAL::stopInternetStream() | ||
674 | { | ||
675 | // DCF_DEBUG | ||
676 | llinfos << "entered LLAudioEngine_OpenAL::stopInternetStream()" << llendl; | ||
677 | |||
678 | #if LL_GSTREAMER_ENABLED | ||
679 | if( ! m_streamer->addCommand(LLMediaBase::COMMAND_STOP)) | ||
680 | { | ||
681 | llinfos << "attempting to stop stream failed!" << llendl; | ||
682 | } | ||
683 | m_streamer->updateMedia(); | ||
684 | #endif | ||
685 | mInternetStreamURL.erase(); | ||
686 | } | ||
687 | |||
688 | |||
689 | void LLAudioEngine_OpenAL::pauseInternetStream(int pause) | ||
690 | { | ||
691 | #if LL_GSTREAMER_ENABLED | ||
692 | if(!m_streamer) | ||
693 | return; | ||
694 | // DCF_DEBUG | ||
695 | llinfos << "entered LLAudioEngine_OpenAL::pauseInternetStream()" << llendl; | ||
696 | |||
697 | if(pause) | ||
698 | { | ||
699 | if(!m_streamer->addCommand(LLMediaBase::COMMAND_PAUSE)) | ||
379 | { | 700 | { |
380 | alDeleteBuffers(1, &buffer); | 701 | llinfos << "attempting to pause stream failed!" << llendl; |
381 | } | 702 | } |
703 | m_streamer->updateMedia(); | ||
382 | } | 704 | } |
383 | 705 | else | |
384 | while (empty_num_wind_buffers > 0) // fill+queue new buffers | ||
385 | { | 706 | { |
386 | ALuint buffer; | 707 | if( ! m_streamer->addCommand(LLMediaBase::COMMAND_START)) |
387 | alGetError(); /* clear error */ | ||
388 | alGenBuffers(1,&buffer); | ||
389 | if((error=alGetError()) != AL_NO_ERROR) | ||
390 | { | 708 | { |
391 | llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << error << llendl; | 709 | llinfos << "attempting to pause stream failed!" << llendl; |
392 | break; | ||
393 | } | 710 | } |
711 | m_streamer->updateMedia(); | ||
712 | } | ||
713 | #endif | ||
714 | } | ||
394 | 715 | ||
395 | alBufferData(buffer, | ||
396 | AL_FORMAT_STEREO16, | ||
397 | mWindGen->windGenerate(winddata, | ||
398 | int(wind_gen_freq*wind_buffer_size_sec), 2), | ||
399 | int(2*wind_gen_freq*wind_buffer_size_sec*sizeof(S16)), | ||
400 | wind_gen_freq); | ||
401 | error = alGetError(); | ||
402 | if(error != AL_NO_ERROR) | ||
403 | llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << llendl; | ||
404 | |||
405 | alSourceQueueBuffers(wind_source, 1, &buffer); | ||
406 | error = alGetError(); | ||
407 | if(error != AL_NO_ERROR) | ||
408 | llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << llendl; | ||
409 | 716 | ||
410 | --empty_num_wind_buffers; | 717 | int LLAudioEngine_OpenAL::isInternetStreamPlaying() |
411 | } | 718 | { |
412 | 719 | ||
413 | int playing; | 720 | #if LL_GSTREAMER_ENABLED |
414 | alGetSourcei(wind_source, AL_SOURCE_STATE, &playing); | 721 | if(!m_streamer) |
415 | if(playing != AL_PLAYING) | 722 | return 0; |
723 | |||
724 | if(m_streamer->getStatus() == LLMediaBase::STATUS_STARTED) | ||
416 | { | 725 | { |
417 | alSourcePlay(wind_source); | 726 | return 1; // Active and playing |
727 | } | ||
418 | 728 | ||
419 | llinfos << "Wind had stopped - probably ran out of buffers - restarting: " << (unprocessed+empty_num_wind_buffers) << " now queued." << llendl; | 729 | if(m_streamer->getStatus() == LLMediaBase::STATUS_PAUSED) |
730 | { | ||
731 | return 2; // paused | ||
420 | } | 732 | } |
733 | |||
734 | #endif | ||
735 | return 0; // Stopped | ||
736 | } | ||
737 | |||
738 | |||
739 | void LLAudioEngine_OpenAL::getInternetStreamInfo(char* artist_out, char* title_out) | ||
740 | { | ||
741 | } | ||
742 | |||
743 | |||
744 | void LLAudioEngine_OpenAL::setInternetStreamGain(F32 vol) | ||
745 | { | ||
746 | #if LL_GSTREAMER_ENABLED | ||
747 | // Set the gstreamer volume here | ||
748 | if(!m_streamer) | ||
749 | return; | ||
750 | |||
751 | vol = llclamp(vol, 0.f, 1.f); | ||
752 | m_streamer->setVolume(vol); | ||
753 | m_streamer->updateMedia(); | ||
754 | #endif | ||
421 | } | 755 | } |
422 | 756 | ||
757 | |||
758 | const std::string& LLAudioEngine_OpenAL::getInternetStreamURL() | ||
759 | { | ||
760 | return mInternetStreamURL; | ||
761 | } | ||
diff --git a/linden/indra/llaudio/audioengine_openal.h b/linden/indra/llaudio/audioengine_openal.h index 6289f99..5d5c7d8 100644 --- a/linden/indra/llaudio/audioengine_openal.h +++ b/linden/indra/llaudio/audioengine_openal.h | |||
@@ -34,9 +34,13 @@ | |||
34 | #ifndef LL_AUDIOENGINE_OpenAL_H | 34 | #ifndef LL_AUDIOENGINE_OpenAL_H |
35 | #define LL_AUDIOENGINE_OpenAL_H | 35 | #define LL_AUDIOENGINE_OpenAL_H |
36 | 36 | ||
37 | #include <string> | ||
38 | |||
37 | #include "audioengine.h" | 39 | #include "audioengine.h" |
38 | #include "listener_openal.h" | 40 | #include "listener_openal.h" |
39 | #include "windgen.h" | 41 | #include "llmediamanager.h" |
42 | #include "llmediaimplgstreamer.h" | ||
43 | #include "llrand.h" | ||
40 | 44 | ||
41 | class LLAudioEngine_OpenAL : public LLAudioEngine | 45 | class LLAudioEngine_OpenAL : public LLAudioEngine |
42 | { | 46 | { |
@@ -44,23 +48,58 @@ class LLAudioEngine_OpenAL : public LLAudioEngine | |||
44 | LLAudioEngine_OpenAL(); | 48 | LLAudioEngine_OpenAL(); |
45 | virtual ~LLAudioEngine_OpenAL(); | 49 | virtual ~LLAudioEngine_OpenAL(); |
46 | 50 | ||
47 | virtual bool init(const S32 num_channels, void *user_data); | 51 | virtual BOOL init(const S32 num_channels); |
52 | virtual std::string getDriverName(bool verbose); | ||
48 | virtual void allocateListener(); | 53 | virtual void allocateListener(); |
49 | 54 | ||
50 | virtual void shutdown(); | 55 | virtual void shutdown(); |
51 | 56 | ||
57 | virtual void idle(F32 max_decode_time = 0.f); | ||
58 | |||
52 | void setInternalGain(F32 gain); | 59 | void setInternalGain(F32 gain); |
53 | 60 | ||
54 | LLAudioBuffer* createBuffer(); | 61 | LLAudioBuffer* createBuffer(); |
55 | LLAudioChannel* createChannel(); | 62 | LLAudioChannel* createChannel(); |
56 | 63 | ||
57 | /*virtual*/ void initWind(); | 64 | // Internet stream methods |
58 | /*virtual*/ void cleanupWind(); | 65 | virtual void initInternetStream(); |
59 | /*virtual*/ void updateWind(LLVector3 direction, F32 camera_altitude); | 66 | virtual void startInternetStream(const std::string& url_cstr); |
60 | 67 | virtual void stopInternetStream(); | |
61 | private: | 68 | virtual void updateInternetStream(); |
69 | virtual void pauseInternetStream(int pause); | ||
70 | virtual int isInternetStreamPlaying(); | ||
71 | virtual void getInternetStreamInfo(char* artist, char* title); | ||
72 | virtual void setInternetStreamGain(F32 vol); | ||
73 | virtual const std::string& getInternetStreamURL(); | ||
74 | virtual void InitStreamer(); | ||
75 | |||
76 | void checkALError(); | ||
77 | |||
78 | void initWind(); | ||
79 | void cleanupWind(); | ||
80 | void updateWind(LLVector3 direction, F32 camera_altitude); | ||
81 | |||
82 | protected: | ||
83 | static const S32 mNumWindBuffers=20; | ||
84 | static const S32 mSampleRate=44100; | ||
85 | static const S32 mBytesPerSample=4; | ||
86 | static const S32 mWindDataSize=8820; //44100 * 0.200 * 2 channels * 2 bytes per sample | ||
87 | |||
88 | BOOL mFirstWind; | ||
89 | ALuint mWindBuffers[mNumWindBuffers]; | ||
90 | ALuint mWindSource; | ||
91 | |||
92 | F32 mTargetGain; | ||
93 | F32 mTargetFreq; | ||
94 | F32 mTargetPanGainR; | ||
95 | S16 mWindData[mWindDataSize]; | ||
96 | |||
97 | std::string mInternetStreamURL; | ||
62 | void * windDSP(void *newbuffer, int length); | 98 | void * windDSP(void *newbuffer, int length); |
63 | LLWindGen<S16> *mWindGen; | 99 | #if LL_GSTREAMER_ENABLED |
100 | LLMediaManagerData * mMedia_data; | ||
101 | LLMediaImplGStreamer * m_streamer; | ||
102 | #endif | ||
64 | }; | 103 | }; |
65 | 104 | ||
66 | class LLAudioChannelOpenAL : public LLAudioChannel | 105 | class LLAudioChannelOpenAL : public LLAudioChannel |
@@ -78,7 +117,7 @@ class LLAudioChannelOpenAL : public LLAudioChannel | |||
78 | void update3DPosition(); | 117 | void update3DPosition(); |
79 | void updateLoop(){}; | 118 | void updateLoop(){}; |
80 | 119 | ||
81 | ALuint mALSource; | 120 | ALuint ALSource; |
82 | }; | 121 | }; |
83 | 122 | ||
84 | class LLAudioBufferOpenAL : public LLAudioBuffer{ | 123 | class LLAudioBufferOpenAL : public LLAudioBuffer{ |
@@ -92,9 +131,8 @@ class LLAudioBufferOpenAL : public LLAudioBuffer{ | |||
92 | friend class LLAudioChannelOpenAL; | 131 | friend class LLAudioChannelOpenAL; |
93 | protected: | 132 | protected: |
94 | void cleanup(); | 133 | void cleanup(); |
95 | ALuint getBuffer() {return mALBuffer;} | 134 | ALuint getBuffer(){return ALBuffer;} |
96 | 135 | ALuint ALBuffer; | |
97 | ALuint mALBuffer; | ||
98 | }; | 136 | }; |
99 | 137 | ||
100 | #endif | 138 | #endif |
diff --git a/linden/indra/llaudio/listener_openal.cpp b/linden/indra/llaudio/listener_openal.cpp index e72b078..637af30 100644 --- a/linden/indra/llaudio/listener_openal.cpp +++ b/linden/indra/llaudio/listener_openal.cpp | |||
@@ -81,14 +81,18 @@ void LLListener_OpenAL::commitDeferredChanges(){ | |||
81 | } | 81 | } |
82 | 82 | ||
83 | void LLListener_OpenAL::setDopplerFactor(F32 factor){ | 83 | void LLListener_OpenAL::setDopplerFactor(F32 factor){ |
84 | // Effect is way too strong by default, scale it down here. | ||
85 | // Scaling the speed of sound up causes crashes. | ||
86 | factor *= 0.005f; | ||
84 | //llinfos << "LLListener_OpenAL::setDopplerFactor() : " << factor << llendl; | 87 | //llinfos << "LLListener_OpenAL::setDopplerFactor() : " << factor << llendl; |
85 | alDopplerFactor(factor); | 88 | alDopplerFactor(factor); |
86 | } | 89 | } |
87 | 90 | ||
88 | F32 LLListener_OpenAL::getDopplerFactor(){ | 91 | F32 LLListener_OpenAL::getDopplerFactor(){ |
89 | ALfloat factor; | 92 | ALfloat factor; |
90 | factor = alGetFloat(AL_DOPPLER_FACTOR); | 93 | factor = 0.0f; |
91 | //llinfos << "LLListener_OpenAL::getDopplerFactor() : " << factor << llendl; | 94 | alDopplerFactor(factor); |
95 | llinfos << "LLListener_OpenAL::getDopplerFactor() : " << factor << llendl; | ||
92 | return factor; | 96 | return factor; |
93 | } | 97 | } |
94 | 98 | ||
diff --git a/linden/indra/llaudio/listener_openal.h b/linden/indra/llaudio/listener_openal.h index 33063bb..7551161 100644 --- a/linden/indra/llaudio/listener_openal.h +++ b/linden/indra/llaudio/listener_openal.h | |||
@@ -35,11 +35,18 @@ | |||
35 | 35 | ||
36 | #include "listener.h" | 36 | #include "listener.h" |
37 | 37 | ||
38 | #include "al.h" | 38 | |
39 | #include "alut.h" | 39 | //#include "AL/al.h" |
40 | #include "AL/alut.h" | ||
40 | 41 | ||
41 | class LLListener_OpenAL : public LLListener | 42 | class LLListener_OpenAL : public LLListener |
42 | { | 43 | { |
44 | private: | ||
45 | protected: | ||
46 | public: | ||
47 | |||
48 | private: | ||
49 | protected: | ||
43 | public: | 50 | public: |
44 | LLListener_OpenAL(); | 51 | LLListener_OpenAL(); |
45 | virtual ~LLListener_OpenAL(); | 52 | virtual ~LLListener_OpenAL(); |
@@ -52,8 +59,6 @@ class LLListener_OpenAL : public LLListener | |||
52 | 59 | ||
53 | virtual void setDopplerFactor(F32 factor); | 60 | virtual void setDopplerFactor(F32 factor); |
54 | virtual F32 getDopplerFactor(); | 61 | virtual F32 getDopplerFactor(); |
55 | |||
56 | protected: | ||
57 | }; | 62 | }; |
58 | 63 | ||
59 | #endif | 64 | #endif |
diff --git a/linden/indra/llaudio/llaudiodecodemgr.cpp b/linden/indra/llaudio/llaudiodecodemgr.cpp index 7cd48a9..cfd0500 100644 --- a/linden/indra/llaudio/llaudiodecodemgr.cpp +++ b/linden/indra/llaudio/llaudiodecodemgr.cpp | |||
@@ -374,16 +374,16 @@ BOOL LLVorbisDecodeState::finishDecode() | |||
374 | 374 | ||
375 | // write "data" chunk length, in little-endian format | 375 | // write "data" chunk length, in little-endian format |
376 | S32 data_length = mWAVBuffer.size() - WAV_HEADER_SIZE; | 376 | S32 data_length = mWAVBuffer.size() - WAV_HEADER_SIZE; |
377 | mWAVBuffer[40] = (data_length) & 0x000000FF; | 377 | mWAVBuffer[40] = (data_length - 8) & 0x000000FF; |
378 | mWAVBuffer[41] = (data_length >> 8) & 0x000000FF; | 378 | mWAVBuffer[41] = ((data_length - 8)>> 8) & 0x000000FF; |
379 | mWAVBuffer[42] = (data_length >> 16) & 0x000000FF; | 379 | mWAVBuffer[42] = ((data_length - 8)>> 16) & 0x000000FF; |
380 | mWAVBuffer[43] = (data_length >> 24) & 0x000000FF; | 380 | mWAVBuffer[43] = ((data_length - 8)>> 24) & 0x000000FF; |
381 | |||
381 | // write overall "RIFF" length, in little-endian format | 382 | // write overall "RIFF" length, in little-endian format |
382 | data_length += 36; | 383 | mWAVBuffer[4] = (data_length + 28) & 0x000000FF; |
383 | mWAVBuffer[4] = (data_length) & 0x000000FF; | 384 | mWAVBuffer[5] = ((data_length + 28) >> 8) & 0x000000FF; |
384 | mWAVBuffer[5] = (data_length >> 8) & 0x000000FF; | 385 | mWAVBuffer[6] = ((data_length + 28) >> 16) & 0x000000FF; |
385 | mWAVBuffer[6] = (data_length >> 16) & 0x000000FF; | 386 | mWAVBuffer[7] = ((data_length + 28) >> 24) & 0x000000FF; |
386 | mWAVBuffer[7] = (data_length >> 24) & 0x000000FF; | ||
387 | 387 | ||
388 | // | 388 | // |
389 | // FUDGECAKES!!! Vorbis encode/decode messes up loop point transitions (pop) | 389 | // FUDGECAKES!!! Vorbis encode/decode messes up loop point transitions (pop) |
@@ -395,7 +395,8 @@ BOOL LLVorbisDecodeState::finishDecode() | |||
395 | S32 fade_length; | 395 | S32 fade_length; |
396 | char pcmout[4096]; /*Flawfinder: ignore*/ | 396 | char pcmout[4096]; /*Flawfinder: ignore*/ |
397 | 397 | ||
398 | fade_length = llmin((S32)128,(S32)(data_length-36)/8); | 398 | fade_length = llmin((S32)128,(S32)(data_length)/8); |
399 | |||
399 | if((S32)mWAVBuffer.size() >= (WAV_HEADER_SIZE + 2* fade_length)) | 400 | if((S32)mWAVBuffer.size() >= (WAV_HEADER_SIZE + 2* fade_length)) |
400 | { | 401 | { |
401 | memcpy(pcmout, &mWAVBuffer[WAV_HEADER_SIZE], (2 * fade_length)); /*Flawfinder: ignore*/ | 402 | memcpy(pcmout, &mWAVBuffer[WAV_HEADER_SIZE], (2 * fade_length)); /*Flawfinder: ignore*/ |
@@ -435,7 +436,7 @@ BOOL LLVorbisDecodeState::finishDecode() | |||
435 | } | 436 | } |
436 | } | 437 | } |
437 | 438 | ||
438 | if (36 == data_length) | 439 | if (0 == data_length) |
439 | { | 440 | { |
440 | llwarns << "BAD Vorbis decode in finishDecode!" << llendl; | 441 | llwarns << "BAD Vorbis decode in finishDecode!" << llendl; |
441 | mValid = FALSE; | 442 | mValid = FALSE; |