diff --git a/.hgtags b/.hgtags
index ed123d344095d95678737354958ebe69dcf1919a..9d495cfc6ba04e143a16be8542cc0dcf561d1529 100644
--- a/.hgtags
+++ b/.hgtags
@@ -72,35 +72,35 @@ b53a0576eec80614d7767ed72b40ed67aeff27c9 DRTVWR-38_2.5.2-release
 461c8c65b5c799ddfe365422f9be9c0095d91e7d 2.6.0-beta1-tip
 9e4641f4a7870c0f565a25a2971368d5a29516a1 2.6.0-beta2
 9e4641f4a7870c0f565a25a2971368d5a29516a1 DRTVWR-41_2.6.0-beta2
+42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release
+42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release
 c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-beta1
 c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-start
 c5bdef3aaa2744626aef3c217ce29e1900d357b3 DRTVWR-43_2.6.1-beta1
+c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release
+c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release
 56b2778c743c2a964d82e1caf11084d76a87de2c 2.6.2-start
 d1203046bb653b763f835b04d184646949d8dd5c 2.6.2-beta1
 d1203046bb653b763f835b04d184646949d8dd5c DRTVWR-45_2.6.2-beta1
-42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release
-42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release
-c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release
-c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release
+214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release
+214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release
 52b2263ab28f0976c689fd0b76c55a9eb027cdbf end-of-develop.py
 ec32f1045e7c2644015245df3a9933620aa194b8 2.6.3-start
 d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc 2.6.3-beta1
 d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc DRTVWR-47_2.6.3-beta1
 0630e977504af5ea320c58d33cae4e1ddee793e9 2.6.3-beta2
 0630e977504af5ea320c58d33cae4e1ddee793e9 DRTVWR-48_2.6.3-beta2
+8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release
+8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release
 3178e311da3a8739a85363665006ea3c4610cad4 dons-headless-hackathon-work
-214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release
-214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release
 7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd 2.6.5-beta1
 7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd DRTVWR-50_2.6.5-beta1
-8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release
-8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release
 800cefce8d364ffdd2f383cbecb91294da3ea424 2.6.6-start
 bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 2.6.6-beta1
 bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 DRTVWR-52_2.6.6-beta1
-5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start
 dac76a711da5f1489a01c1fa62ec97d99c25736d 2.6.6-release
 dac76a711da5f1489a01c1fa62ec97d99c25736d DRTVWR-51_2.6.6-release
+5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start
 beafa8a9bd1d1b670b7523d865204dc4a4b38eef 2.6.8-beta1
 beafa8a9bd1d1b670b7523d865204dc4a4b38eef DRTVWR-55_2.6.8-beta1
 be2000b946f8cb3de5f44b2d419287d4c48ec4eb 2.6.8-release
@@ -119,50 +119,50 @@ e67da2c6e3125966dd49eef98b36317afac1fcfe 2.6.9-start
 9f79a6ed8fdcd2f3dac33ea6b3236eeb278dccfe 2.7.2-start
 e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb 2.7.2-beta1
 e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb DRTVWR-63_2.7.2-beta1
-6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start
 fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.1-release
 fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.2-release
 fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release
 fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-62_2.7.2-release
+6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start
 6af10678de4736222b2c3f7e010e984fb5b327de 2.7.4-start
 be963a4eef635542f9617d7f5fd22ba48fb71958 2.7.4-beta1
 be963a4eef635542f9617d7f5fd22ba48fb71958 DRTVWR-67_2.7.4-beta1
+057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release
+057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release
 19a498fa62570f352d7d246f17e3c81cc1d82d8b 2.7.5-start
 09984bfa6cae17e0f72d02b75c1b7393c65eecfc 2.7.5-beta1
 09984bfa6cae17e0f72d02b75c1b7393c65eecfc DRTVWR-69_2.7.5-beta1
+6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release
+6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release
 e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-beta1
 e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-start
 e1ed60913230dd64269a7f7fc52cbc6004f6d52c DRTVWR-71_2.8.0-beta1
-057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release
-057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release
-6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release
-6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release
+493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release
+493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release
 502f6a5deca9365ddae57db4f1e30172668e171e 2.8.1-start
 2c7e459e0c883f8e406b932e41e60097e9ee077e 2.8.1-beta1
 2c7e459e0c883f8e406b932e41e60097e9ee077e DRTVWR-73_2.8.1-beta1
-493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release
-493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release
-54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start
-ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start
 29e93d7e19991011bd12b5748142b11a5dcb4370 2.8.1-release
 29e93d7e19991011bd12b5748142b11a5dcb4370 DRTVWR-72_2.8.1-release
 4780e3bd2b3042f91be3426151f28c30d199bb3b 2.8.1-hotfix
 4780e3bd2b3042f91be3426151f28c30d199bb3b DRTVWR-76_2.8.1-hotfix
+54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start
+ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start
 599677276b227357140dda35bea4a2c18e2e67b5 2.8.3-beta1
 599677276b227357140dda35bea4a2c18e2e67b5 DRTVWR-75_2.8.3-beta1
+fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release
+fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release
 6b678ea52f90d5c14181661dcd2546e25bde483e 3.0.0-start
 b0be6ce3adfef3a014a2389d360539f8a86c5439 3.0.0-beta1
 b0be6ce3adfef3a014a2389d360539f8a86c5439 DRTVWR-78_3.0.0-beta1
-fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release
-fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release
+1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release
+1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release
 82a2079ffcb57ecb1b3849cb41376b443e1eb912 3.0.1-start
 364fd63517fbacbbcb9129d096187171ba8c9e48 3.0.1-beta1
 364fd63517fbacbbcb9129d096187171ba8c9e48 DRTVWR-81_3.0.1-beta1
 f2412ecd6740803ea9452f1d17fd872e263a0df7 3.0.2-start
 42784bf50fa01974bada2a1af3892ee09c93fcda 3.0.2-beta1
 42784bf50fa01974bada2a1af3892ee09c93fcda DRTVWR-83_3.0.2-beta1
-1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release
-1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release
 e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e 3.0.2-beta2
 e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e DRTVWR-86_3.0.2-beta2
 b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start
@@ -170,9 +170,9 @@ b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start
 6694f3f062aa45f64ab391d25a3eb3d5eb1b0871 DRTVWR-85_3.0.3-beta1
 61aa7974df089e8621fe9a4c69bcdefdb3cc208a 3.0.3-beta2
 61aa7974df089e8621fe9a4c69bcdefdb3cc208a DRTVWR-89_3.0.3-beta2
-586907287be581817b2422b5137971b22d54ea48 3.0.4-start
 0496d2f74043cf4e6058e76ac3db03d44cff42ce 3.0.3-release
 0496d2f74043cf4e6058e76ac3db03d44cff42ce DRTVWR-84_3.0.3-release
+586907287be581817b2422b5137971b22d54ea48 3.0.4-start
 92a3aa04775438226399b19deee12ac3b5a62838 3.0.5-start
 c7282e59f374ee904bd793c3c444455e3399b0c5 3.1.0-start
 2657fa785bbfac115852c41bd0adaff74c2ad5da 3.1.0-beta1
@@ -193,11 +193,11 @@ e440cd1dfbd128d7d5467019e497f7f803640ad6 DRTVWR-95_3.2.0-beta1
 c4911ec8cd81e676dfd2af438b3e065407a94a7a 3.2.1-start
 9e390d76807fa70d356b8716fb83b8ce42a629ef 3.2.1-beta1
 9e390d76807fa70d356b8716fb83b8ce42a629ef DRTVWR-100_3.2.1-beta1
+a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
+a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
 40b46edba007d15d0059c80864b708b99c1da368 3.2.2-start
 523df3e67378541498d516d52af4402176a26bac 3.2.2-beta1
 523df3e67378541498d516d52af4402176a26bac DRTVWR-102_3.2.2-beta1
-a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
-a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
 80f3e30d8aa4d8f674a48bd742aaa6d8e9eae0b5 3.2.3-start
 3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-beta1
 3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-start
@@ -248,57 +248,67 @@ bb9932a7a5fd00edf52d95f354e3b37ae6a942db DRTVWR-156
 6414ecdabc5d89515b08d1f872cf923ed3a5523a DRTVWR-148
 2a3965b3ad202df7ea25d2be689291bb14a1280e DRTVWR-155
 24a7281bef42bd4430ceb25db8b195449c2c7de3 DRTVWR-153
+a716684aa7c07c440b1de5815b8a1f3dd3fd8bfb DRTVWR-159
+9a78ac13f047056f788c4734dd91aebfe30970e3 DRTVWR-157
 5910f8063a7e1ddddf504c2f35ca831cc5e8f469 DRTVWR-160
 f0a174c2adb4bc39b16722a61d7eeb4f2a1d4843 3.3.3-beta1
 f0a174c2adb4bc39b16722a61d7eeb4f2a1d4843 DRTVWR-144
-2d6c0634b11e6f3df11002b8510a72a0433da00a DRTVWR-164
+089e5c84b2dece68f2b016c842ef9b5de4786842 DRTVWR-161
 600f3b3920d94de805ac6dc8bb6def9c069dd360 DRTVWR-162
+c08e2ac17a99973b2a94477659220b99b8847ae2 DRTVWR-163
+2d6c0634b11e6f3df11002b8510a72a0433da00a DRTVWR-164
 80b5e5e9775966d3839331ffa7a16a60f9d7c930 DRTVWR-165
 fdcc08a4f20ae9bb060f4693c8980d216534efdf 3.3.3-beta2
 af5f3e43e6e4424b1da19d9e16f6b853a7b822ed DRTVWR-169
 4b3c68199a86cabaa5d9466d7b0f7e141e901d7a 3.3.3-beta3
 6428242e124b523813bfaf4c45b3d422f0298c81 3.3.3-release
-a716684aa7c07c440b1de5815b8a1f3dd3fd8bfb DRTVWR-159
-9a78ac13f047056f788c4734dd91aebfe30970e3 DRTVWR-157
-089e5c84b2dece68f2b016c842ef9b5de4786842 DRTVWR-161
-c08e2ac17a99973b2a94477659220b99b8847ae2 DRTVWR-163
 b9d0170b62eb1c7c3adaa37a0b13a833e5e659f9 DRTVWR-171
 050e48759337249130f684b4a21080b683f61732 DRTVWR-168
 09ef7fd1b0781f33b8a3a9af6236b7bcb4831910 DRTVWR-170
 f87bfbe0b62d26f451d02a47c80ebef6b9168fc2 DRTVWR-158
 f91d003091a61937a044652c4c674447f7dcbb7a 3.3.4-beta1
+005dfe5c4c377207d065fb27858d2eb0b53b143a DRTVWR-167
 bce218b2b45b730b22cc51e4807aa8b571cadef3 DRTVWR-173
 cbea6356ce9cb0c313b6777f10c5c14783264fcc DRTVWR-174
 82b5330bc8b17d0d4b598832e9c5a92e90075682 3.3.4-beta2
 57d221de3df94f90b55204313c2cef044a3c0ae2 DRTVWR-176
 eb539c65e6ee26eea2bf373af2d0f4b52dc91289 DRTVWR-177
 a8057e1b9a1246b434a27405be35e030f7d28b0c 3.3.4-beta3
+888768f162d2c0a8de1dcc5fb9a08bd8bd120a6b DRTVWR-175
 4281aa899fb2cedb7a9ca7ce91c5c29d4aa69594 DRTVWR-180
 5c08e1d8edd871807153603b690e3ee9dbb548aa DRTVWR-183
 6c75f220b103db1420919c8b635fe53e2177f318 3.3.4-beta4
 9cd174d3a54d93d409a7c346a15b8bfb40fc58f4 DRTVWR-184
 ab2ffc547c8a8950ff187c4f6c95e5334fab597b 3.3.4-beta5
 28e100d0379a2b0710c57647a28fc5239d3d7b99 3.3.4-release
-005dfe5c4c377207d065fb27858d2eb0b53b143a DRTVWR-167
-888768f162d2c0a8de1dcc5fb9a08bd8bd120a6b DRTVWR-175
 a8b3eca451a9eaab59987efb0ab1c4217e3f2dcc DRTVWR-182
 1f27cdfdc54246484f8afbbe42ce48e954175cbd 3.4.0-beta1
-9ee9387789701d597130f879d9011a4958753862 DRTVWR-189
+81f6b745ef27f5915fd07f988fdec9944f2bb73e DRTVWR-186
 47f0d08ba7ade0a3905074009067c6d3df7e16ae DRTVWR-190
+cc953f00956be52cc64c30637bbeec310eea603f DRTVWR-181
+c04e68e1b0034fd0a20815ae24c77e5f8428e822 DRTVWR-188
+9ee9387789701d597130f879d9011a4958753862 DRTVWR-189
 421126293dcbde918e0da027ca0ab9deb5b4fbf2 DRTVWR-192
+4b2c52aecb7a75de31dbb12d9f5b9a251d8707be DRTVWR-191
 33a2fc7a910ae29ff8b4850316ed7fbff9f64d33 DRTVWR-195
 e9732c739c8a72a590216951505ea9c76a526a84 DRTVWR-193
+78ca0bbf43a92e8914d4cfa87d69a6717ef7d4cf DRTVWR-194
 7602f61c804a512764e349c034c02ddabeefebc4 DRTVWR-196
 ae5c83dd61d2d37c45f1d5b8bf2b036d87599f1b DRTVWR-198
 507bdfbd6bf844a511c1ffeda4baa80016ed1346 DRTVWR-197
 b1dbb1a83f48f93f6f878cff9e52d2cb635e145c 3.4.0-beta2
 37402e2b19af970d51b0a814d79892cc5647532b DRTVWR-200
 182a9bf30e81070361bb020a78003b1cf398e79c 3.4.0-beta3
+248f4acd92a706c79e842bc83d80baa7369c0c2e DRTVWR-203
 6dfb0fba782c9233dd95f24ec48146db0d3f210b DRTVWR-199
 7c9102fb998885621919f2474a002c35b583539b 3.3.4-release2
 7649a3dff5ec22d3727377e5f02efd0f421e4cb5 DRTVWR-201
 84fb70dfe3444e75a44fb4bee43e2fc8221cebdd 3.4.0-beta4
+de3be913f68813a9bac7d1c671fef96d1159bcd6 DRTVWR-202
 573e863be2f26d3687161def4b9fea9b7038dda8 3.4.0-beta5
+34dbbe2b00afe90352d3acf8290eb10ab90d1c8b oz-build-test-tag
+6ee71714935ffcd159db3d4f5800c1929aac54e1 DRTVWR-205
+7b22c612fc756e0ea63b10b163e81d107f85dbf8 DRTVWR-206
 8c9085066c78ed5f6c9379dc054c82a6fcdb1851 DRTVWR-207
 351eea5f9dc192fc5ddea3b02958de97677a0a12 3.3.4-release3
 af7b28e75bd5a629cd9e0dc46fb3f1757626f493 DRTVWR-212
@@ -309,6 +319,7 @@ ceed0b65a69f1eac20d523e0203320a32f9a3f3c DRTVWR-215
 97977c67245f52db20eb15f1918cc0f24778cabc 3.4.0-release
 5adb2b8f96c3cac88ad7c7d996d707f1b29df336 3.4.1-beta1
 b3f74858a1c8720c82d0978f3877a3fc8ba459ec 3.4.1-beta1a
+b61afe175b829c149d369524a4e974dfda99facf DRTVWR-219
 2b779f233ee6f38c89cb921650c773a96e63da92 DRTVWR-220
 0b9d95f4bfb6867cbf56eaec51633b0da2f1262d DRTVWR-221
 e6e553761829dc0270eaaa712b7cb0622535b076 3.4.1-beta3
@@ -333,36 +344,31 @@ baf97f06ae17223614c5e31aa42e71d87cff07fe DRTVWR-236
 b2f21e3442542283a80e7eaebae9f833e5a927b6 DRTVWR-237
 3f9be82de642d468c5fc272cb9d96b46b5498402 3.4.1-beta12
 e59ffd3fe0838ae6b09b242a6e9df71761b88f41 3.4.1-release
-81f6b745ef27f5915fd07f988fdec9944f2bb73e DRTVWR-186
-cc953f00956be52cc64c30637bbeec310eea603f DRTVWR-181
-c04e68e1b0034fd0a20815ae24c77e5f8428e822 DRTVWR-188
-4b2c52aecb7a75de31dbb12d9f5b9a251d8707be DRTVWR-191
-78ca0bbf43a92e8914d4cfa87d69a6717ef7d4cf DRTVWR-194
-248f4acd92a706c79e842bc83d80baa7369c0c2e DRTVWR-203
-de3be913f68813a9bac7d1c671fef96d1159bcd6 DRTVWR-202
-34dbbe2b00afe90352d3acf8290eb10ab90d1c8b oz-build-test-tag
-6ee71714935ffcd159db3d4f5800c1929aac54e1 DRTVWR-205
-7b22c612fc756e0ea63b10b163e81d107f85dbf8 DRTVWR-206
-b61afe175b829c149d369524a4e974dfda99facf DRTVWR-219
 32896d5e920ca9a29256ff3b747c2e99752aa5ae DRTVWR-217
 704bbae7b182a1f2811a47a054e680522966f54a 3.4.2-beta1
+d799593b53ed733862e9a13871e318e886469377 DRTVWR-208
+e497dcde7a3653e384eb223a8a460030e89c294c DRTVWR-223
 288539fc0408ed4b69a99665de33bbbc2c3c08fe DRTVWR-216
 e664473c16df1d82ffaff382e7b3e023da202d52 3.4.2-beta2
+93ab02d83f51e30a3cabad98aff89601befd9413 DRTVWR-240
 0891d7a773a31397dcad48be3fa66531d567a821 DRTVWR-242
 710785535362b3cb801b6a3dc4703be3373bd0cd 3.4.2-beta3
-e9a5886052433d5db9e504ffaca10890f9932979 DRTVWR-243
-73b84b9864dc650fe7c8fc9f52361450f0849004 3.4.2-beta4
-16310aabccf315870f7cc9bf966926c0ad6954fa 3.4.2-release
-d799593b53ed733862e9a13871e318e886469377 DRTVWR-208
-e497dcde7a3653e384eb223a8a460030e89c294c DRTVWR-223
-93ab02d83f51e30a3cabad98aff89601befd9413 DRTVWR-240
 2aa72e3372a83dece4df9cf72fb1e7c34f90b5e3 DRTVWR-209
 f7bedce18ad52283e6072814db23318907261487 DRTVWR-238
 7b64c96fbcadf360bd2feaae19d330166b70877c DRTVWR-210
+e9a5886052433d5db9e504ffaca10890f9932979 DRTVWR-243
+73b84b9864dc650fe7c8fc9f52361450f0849004 3.4.2-beta4
+16310aabccf315870f7cc9bf966926c0ad6954fa 3.4.2-release
 5e4e4128b256525bafc07a62e35ae8527aaa9c9d DRTVWR-241
 f1d3b3fcab28ed9ea532bf50db0ba96f5c8cc8e9 DRTVWR-232
 4918b150e75df6b516fb6c2616d32043fa6b4cac DRTVWR-245
 94ab2b49458ab372a95d2d6949fdf574f413068d 3.4.3-beta1
+4c3460cb1fb7c6da9965e09c734d282a8e9c81f0 DRTVWR-229
+f4481df42f9a4a92bf475a80f0c51d1a4bbdfd59 DRTVWR-246
+39c5204b6e800983a41ccac8ad6dc993120197c6 DRTVWR-247
+7c7d57d393e8ae7b61623279de06eb4a62ccae6a DRTVWR-249
+f72b50ef168c159d6e79e97aa2bcafaf8577ab99 DRTVWR-230
+b418be80903520c492e1173f3afbc4021cad5d07 DRTVWR-255
 965b9a35e260c0f53be1a25f0db7abc8a67eaf47 DRTVWR-252
 bb10adc4f76cf0067fca7075146f00cdc0740e9d DRTVWR-251
 ab0aa2f6ba22b52fed30a2337197f589156edc75 DRTVWR-253
@@ -371,31 +377,25 @@ ab0aa2f6ba22b52fed30a2337197f589156edc75 DRTVWR-253
 44e764a6ac9e672a4f3bce821a4b6a218590c374 DRTVWR-258
 c23d734065ed593b2413385aecd8366d8e0ee96b DRTVWR-257
 452ce96d4046dc05a3ecaecc203e2cc8ddd72e76 DRTVWR-259
+9aa1aa9f1fe13c194695a0b8f0af298296241dc2 DRTVWR-260
 daca610d840625b5bebb966a57cb49581852c417 DRTVWR-265
 9afbdc4e24cc04feacfb2b7a10b78a64f780901a DRTVWR-266
 73280db02501f5ad041fc18b1eba68e73a81996c DRTVWR-267
 870e2d79e0063fda87187f17bbc2747766733194 3.4.3-beta3
 0a2ca6546b499239afeb66d17b2fadbcdbe36ab1 3.4.3-release
-4c3460cb1fb7c6da9965e09c734d282a8e9c81f0 DRTVWR-229
-f4481df42f9a4a92bf475a80f0c51d1a4bbdfd59 DRTVWR-246
-39c5204b6e800983a41ccac8ad6dc993120197c6 DRTVWR-247
-7c7d57d393e8ae7b61623279de06eb4a62ccae6a DRTVWR-249
-f72b50ef168c159d6e79e97aa2bcafaf8577ab99 DRTVWR-230
-b418be80903520c492e1173f3afbc4021cad5d07 DRTVWR-255
-9aa1aa9f1fe13c194695a0b8f0af298296241dc2 DRTVWR-260
 84fbaf2d4141bd161731430e760949dc787ca206 DRTVWR-244
 083d2d36b5bb1c54fc3dd7caac0e7ac381a9cef0 3.4.4-beta1
+391a8c74cec7275c5d26c85ad108d4782a3e3dd9 DRTVWR-268
 b634dec987c16e8c9c938e11e52591d9ead8fa9b DRTVWR-270
 cd39255bd23330fd30c04105f2811e941d8524fe 3.4.4-beta2
 2c4011bbc2b15b82198fd8b51f3a9fe765a08c4d DRTVWR-271
 2f8a3ef687bc55828abcb17ac1ad7cde70536d7e 3.4.4-beta3
 35cfd4cf5b895fa776592f2e630e330be7f0604e DRTVWR-273
+a36f1f354b02aa6e448ca13685de167d0a0a3d03 DRTVWR-272
+37dba00ad820de3a808d4039396b162a9c275b3e DRTVWR-269
 c374035d459af3c03dea2dd90880dfc25de64706 DRTVWR-275
 05d9f1dd7a954069af2a33abedb7713fa36a04cb 3.4.4-beta4
 e1bb1ae7d8b12faeb37933a737c199cc9b9f89cc 3.4.4-release
-391a8c74cec7275c5d26c85ad108d4782a3e3dd9 DRTVWR-268
-a36f1f354b02aa6e448ca13685de167d0a0a3d03 DRTVWR-272
-37dba00ad820de3a808d4039396b162a9c275b3e DRTVWR-269
 7c6dfdc1b7a2ce0d8e3a8f3ce3058547ea065c0f DRTVWR-250
 b9ff9730daa53a541925300cbd02bb14575a5705 DRTVWR-277
 af6b711a97073431953b55ee808aaa09900c27e5 DRTVWR-276
@@ -405,6 +405,8 @@ c296133849d1f103c0e2abc41e6599daed00b67b DRTVWR-280
 5df4802bec93c8d0a509946d826bb4c50c5442ec DRTVWR-281
 7c1c33ba4cfd2d15ca51cc1ac440eca551331a4a DRTVWR-283
 6b9c7dbebef793230d64e1b452577c8b142d4143 3.4.5-beta2
+37947e4f771f001b551581bf7cd0051c3153beed DRTVWR-282
+6482cceb91cda68b799f3e6cdc66d33bf123547a DRTVWR-284
 ccf991e02dc2f63fb646324230d54832683f4a9b DRTVWR-286
 2d849850558a5a0324b398d1c102d30bcbdfb88f DRTVWR-287
 e06898df8644fe567bee94f817d03abc1c380993 3.4.5-beta3
@@ -417,8 +419,6 @@ b23419a2748483c98f3b84b630468a21c88feba5 DRTVWR-292
 0a5d409161ef2a89b28c9a741051dd2dedc707d6 DRTVWR-297
 852b69ef0b5fe6b13b69cc2217282cc64de6afab 3.4.5-beta5
 a49c715243a36a8a380504d14cb7416b3039c956 3.4.5-release
-37947e4f771f001b551581bf7cd0051c3153beed DRTVWR-282
-6482cceb91cda68b799f3e6cdc66d33bf123547a DRTVWR-284
 092a9effbedd1a0276fa5ced520992ce00f96fbf CHUI-PV-0
 279ef1dfc9b749a6cc499cf190fec0c090b6d682 DRTVWR-288
 9b19edaf1d8ddf435f60fbbb444dd25db8f63953 3.5.0-beta1
@@ -434,9 +434,8 @@ fd6b510e83f56830e45670c428653134899d3e25 DRTVWR-305
 902caf2b9fdbdbc5c399c4d5ebcecaf9cb97bab8 DRTVWR-306
 5c6098fd17d40ee3a38ca6b64f6be9db7f61f0a8 3.5.0-beta7
 adc360e6bf21390d2665380951d85937cd29a604 3.5.0-release
-0ca3910763cec967703e45bc6208a325dccb9f95 3.5.1-beta1
 1ada73295ed0eaa4a772ef079c29f57069342c32 DRTVWR-310
-0ca3910763cec967703e45bc6208a325dccb9f95 3.5.1-beta1
 20cdf370f5c8be6193bef6fb3a81cc3f81275191 3.5.1-beta1
 2319904200de367646b9a9442239a38d52c1eeb5 DRTVWR-313
 9d8726eca785acad694564516f16dd639faf45c0 3.5.1-beta2
+78a8fe6abf331944d6b6bb1ce1024a6bc08141f4 DRTVWR-298
diff --git a/autobuild.xml b/autobuild.xml
index 80a44ec75dba602f268adc759c3b0d94cbd9dad4..ba6b76e7b21baa30284948608e67f211aefcdec3 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -483,14 +483,14 @@
           </map>
         </map>
       </map>
-      <key>fmod</key>
+      <key>fmodex</key>
       <map>
         <key>license</key>
-        <string>fmod</string>
+        <string>fmodex</string>
         <key>license_file</key>
-        <string>LICENSES/fmod.txt</string>
+        <string>LICENSES/fmodex.txt</string>
         <key>name</key>
-        <string>fmod</string>
+        <string>fmodex</string>
         <key>platforms</key>
         <map>
           <key>darwin</key>
@@ -498,9 +498,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>61ead113e6479452e6b690c84b4e9d30</string>
+	      <string>89a3df89da75444877cf3197416fed67</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmod-private/rev/221852/arch/Darwin/installer/fmod-3.75-darwin-20110222.tar.bz2</string>
+	      <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/270029/arch/Darwin/installer/fmodex-4.44-darwin-20130205.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin</string>
@@ -510,9 +510,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>0c61d643db54d2e5999be8254569d8b3</string>
+          <string>fd787931f49ece9bf99f4d1d1596f04b</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmod-private/rev/221852/arch/Linux/installer/fmod-3.75-linux-20110223.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/269984/arch/Linux/installer/fmodex-4.44-linux-20130205.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux</string>
@@ -522,9 +522,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d9a9a6ad86895353bcd63374a4c1a91d</string>
+	      <string>9e0f62be63e74af18f670f864cac93da</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmod-private/rev/221852/arch/CYGWIN/installer/fmod-3.75-windows-20110222.tar.bz2</string>
+	      <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/270026/arch/CYGWIN/installer/fmodex-4.44-windows-20130205.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -2531,7 +2531,6 @@
                   <string>"Visual Studio 10"</string>
                   <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DUSE_KDU=FALSE</string>
-                  <string>-DFMOD=FALSE</string>
                 </array>
               </map>
               <key>name</key>
@@ -2620,7 +2619,6 @@
                   <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
-                  <string>-DFMOD=FALSE</string>
                 </array>
               </map>
               <key>name</key>
@@ -2708,7 +2706,6 @@
                   <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
-                  <string>-DFMOD=FALSE</string>
                 </array>
               </map>
               <key>name</key>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index a63e3a22b03a37aa140c98c2a836dbe91c74f24c..9f2f51f248a9f2dcd8425e740fdbc55b0a426a54 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -1068,10 +1068,12 @@ Sheet Spotter
 Shnurui Troughton
 Shyotl Kuhr
 	MAINT-1138
+	MAINT-2334
 Siana Gearz
 	STORM-960
 	STORM-1088
 	MAINT-1138
+	MAINT-2334
 sicarius Thorne
 Sicarius Toxx
 SignpostMarv Martin
@@ -1089,6 +1091,8 @@ SLB Wirefly
 Slee Mayo
     SEC-1075
 snowy Sidran
+Sovereign Engineer
+    MAINT-2334
 SpacedOut Frye
 	VWR-34
 	VWR-45
@@ -1342,3 +1346,4 @@ Zoex Flanagan
 
 
 
+
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index a21fa9095073456a2dad5a9ad18bf07e44729c82..10a23ea068f91945d0071edf1a6b9bf349ea913e 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -24,12 +24,11 @@ set(cmake_SOURCE_FILES
     DragDrop.cmake
     EXPAT.cmake
     ExamplePlugin.cmake
-    FMOD.cmake
     FindAPR.cmake
     FindAutobuild.cmake
     FindBerkeleyDB.cmake
     FindCARes.cmake
-    FindFMOD.cmake
+    FindFMODEX.cmake
     FindGLH.cmake
     FindGoogleBreakpad.cmake
     FindGooglePerfTools.cmake
@@ -40,6 +39,7 @@ set(cmake_SOURCE_FILES
     FindSCP.cmake
     FindXmlRpcEpi.cmake
     FindZLIB.cmake
+    FMODEX.cmake
     FreeType.cmake
     GLEXT.cmake
     GLH.cmake
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 338da4743e5252c08fe6278d5f5501894c186e76..ef529c32d329a42239439eb29990220d9b26bb8f 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -62,10 +62,9 @@ if(WINDOWS)
       set(release_files ${release_files} libtcmalloc_minimal.dll)
     endif(USE_TCMALLOC)
 
-    if (FMOD)
-      set(debug_files ${debug_files} fmod.dll)
-      set(release_files ${release_files} fmod.dll)
-    endif (FMOD)
+    if (FMODEX)
+      set(release_files ${release_files} fmodex.dll)
+    endif (FMODEX)
 
 #*******************************
 # Copy MS C runtime dlls, required for packaging.
@@ -222,8 +221,10 @@ elseif(DARWIN)
         libcollada14dom.dylib
        )
 
-    # fmod is statically linked on darwin
-    set(fmod_files "")
+    if (FMODEX)
+      set(debug_files ${debug_files} libfmodexL.dylib)
+      set(release_files ${release_files} libfmodex.dylib)
+    endif (FMODEX)
 
 elseif(LINUX)
     # linux is weird, multiple side by side configurations aren't supported
@@ -288,9 +289,9 @@ elseif(LINUX)
       set(release_files ${release_files} "libtcmalloc_minimal.so")
     endif (USE_TCMALLOC)
 
-    if (FMOD)
-      set(release_files ${release_files} "libfmod-3.75.so")
-    endif (FMOD)
+    if (FMODEX)
+      set(release_file ${release_files} "libfmodex.so")
+    endif (FMODEX)
 
 else(WINDOWS)
     message(STATUS "WARNING: unrecognized platform for staging 3rd party libs, skipping...")
@@ -305,8 +306,6 @@ else(WINDOWS)
     set(release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-linux/lib/release")
     set(release_files "")
 
-    set(fmod_files "")
-
     set(debug_llkdu_src "")
     set(debug_llkdu_dst "")
     set(release_llkdu_src "")
@@ -369,30 +368,6 @@ copy_if_different(
     )
 set(third_party_targets ${third_party_targets} ${out_targets})
 
-if (FMOD_SDK_DIR)
-    copy_if_different(
-        ${FMOD_SDK_DIR} 
-        "${CMAKE_CURRENT_BINARY_DIR}/Debug"
-        out_targets 
-        ${fmod_files}
-        )
-    set(all_targets ${all_targets} ${out_targets})
-    copy_if_different(
-        ${FMOD_SDK_DIR} 
-        "${CMAKE_CURRENT_BINARY_DIR}/Release"
-        out_targets 
-        ${fmod_files}
-        )
-    set(all_targets ${all_targets} ${out_targets})
-    copy_if_different(
-        ${FMOD_SDK_DIR} 
-        "${CMAKE_CURRENT_BINARY_DIR}/RelWithDbgInfo"
-        out_targets 
-        ${fmod_files}
-        )
-    set(all_targets ${all_targets} ${out_targets})
-endif (FMOD_SDK_DIR)
-
 if(NOT STANDALONE)
   add_custom_target(
       stage_third_party_libs ALL
diff --git a/indra/cmake/FMOD.cmake b/indra/cmake/FMOD.cmake
deleted file mode 100644
index 3586c1160aa9e72cdfdc65f08acf659beb509d6f..0000000000000000000000000000000000000000
--- a/indra/cmake/FMOD.cmake
+++ /dev/null
@@ -1,39 +0,0 @@
-# -*- cmake -*-
-
-# FMOD can be set when launching the make using the argument -DFMOD:BOOL=ON
-# When building using proprietary binaries though (i.e. having access to LL private servers),
-# we always build with FMOD.
-# Open source devs should use the -DFMOD:BOOL=ON then if they want to build with FMOD, whether
-# they are using STANDALONE or not.
-if (INSTALL_PROPRIETARY)
-  set(FMOD ON CACHE BOOL "Use FMOD sound library.")
-endif (INSTALL_PROPRIETARY)
-
-if (FMOD)
-  if (STANDALONE)
-    # In that case, we use the version of the library installed on the system
-    set(FMOD_FIND_REQUIRED ON)
-    include(FindFMOD)
-  else (STANDALONE)
-    if (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
-      # If the path have been specified in the arguments, use that
-      set(FMOD_LIBRARIES ${FMOD_LIBRARY})
-      MESSAGE(STATUS "Using FMOD path: ${FMOD_LIBRARIES}, ${FMOD_INCLUDE_DIR}")
-    else (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
-      # If not, we're going to try to get the package listed in autobuild.xml
-      # Note: if you're not using INSTALL_PROPRIETARY, the package URL should be local (file:/// URL) 
-      # as accessing the private LL location will fail if you don't have the credential
-      include(Prebuilt)
-      use_prebuilt_binary(fmod)    
-      if (WINDOWS)
-        set(FMOD_LIBRARY fmod)
-      elseif (DARWIN)
-        set(FMOD_LIBRARY fmod)
-      elseif (LINUX)
-        set(FMOD_LIBRARY fmod-3.75)
-      endif (WINDOWS)
-      set(FMOD_LIBRARIES ${FMOD_LIBRARY})
-      set(FMOD_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
-    endif (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
-  endif (STANDALONE)
-endif (FMOD)
diff --git a/indra/cmake/FMODEX.cmake b/indra/cmake/FMODEX.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..65bc1cabeb8fd77340ea80cf78d50dd1c7bd5d75
--- /dev/null
+++ b/indra/cmake/FMODEX.cmake
@@ -0,0 +1,46 @@
+# -*- cmake -*-
+
+# FMOD can be set when launching the make using the argument -DFMOD:BOOL=ON
+# When building using proprietary binaries though (i.e. having access to LL private servers),
+# we always build with FMODEX.
+# Open source devs should use the -DFMODEX:BOOL=ON then if they want to build with FMOD, whether
+# they are using STANDALONE or not.
+if (INSTALL_PROPRIETARY)
+  set(FMODEX ON CACHE BOOL "Using FMOD Ex sound library.")
+endif (INSTALL_PROPRIETARY)
+
+if (FMODEX)
+  if (STANDALONE)
+    # In that case, we use the version of the library installed on the system
+    set(FMODEX_FIND_REQUIRED ON)
+    include(FindFMODEX)
+  else (STANDALONE)
+    if (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
+      # If the path have been specified in the arguments, use that
+      set(FMODEX_LIBRARIES ${FMODEX_LIBRARY})
+      MESSAGE(STATUS "Using FMODEX path: ${FMODEX_LIBRARIES}, ${FMODEX_INCLUDE_DIR}")
+    else (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
+      # If not, we're going to try to get the package listed in autobuild.xml
+      # Note: if you're not using INSTALL_PROPRIETARY, the package URL should be local (file:/// URL) 
+      # as accessing the private LL location will fail if you don't have the credential
+      include(Prebuilt)
+      use_prebuilt_binary(fmodex)    
+      if (WINDOWS)
+        set(FMODEX_LIBRARY 
+            debug fmodexL_vc
+            optimized fmodex_vc)
+      elseif (DARWIN)
+        set(FMODEX_LIBRARY 
+            debug fmodexL
+            optimized fmodex)
+      elseif (LINUX)
+        set(FMODEX_LIBRARY 
+            debug fmodexL
+            optimized fmodex)
+      endif (WINDOWS)
+      set(FMODEX_LIBRARIES ${FMODEX_LIBRARY})
+      set(FMODEX_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodex)
+    endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
+  endif (STANDALONE)
+endif (FMODEX)
+
diff --git a/indra/cmake/FindFMOD.cmake b/indra/cmake/FindFMOD.cmake
deleted file mode 100644
index 1ebbc8c96e5e3627f2de7d434ff2e73e5add235c..0000000000000000000000000000000000000000
--- a/indra/cmake/FindFMOD.cmake
+++ /dev/null
@@ -1,44 +0,0 @@
-# -*- cmake -*-
-
-# - Find FMOD
-# Find the FMOD includes and library
-# This module defines
-#  FMOD_INCLUDE_DIR, where to find fmod.h and fmod_errors.h
-#  FMOD_LIBRARIES, the libraries needed to use FMOD.
-#  FMOD, If false, do not try to use FMOD.
-# also defined, but not for general use are
-#  FMOD_LIBRARY, where to find the FMOD library.
-
-FIND_PATH(FMOD_INCLUDE_DIR fmod.h PATH_SUFFIXES fmod)
-
-SET(FMOD_NAMES ${FMOD_NAMES} fmod fmodvc fmodex fmod-3.75)
-FIND_LIBRARY(FMOD_LIBRARY
-  NAMES ${FMOD_NAMES}
-  PATH_SUFFIXES fmod
-  )
-
-IF (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
-  SET(FMOD_LIBRARIES ${FMOD_LIBRARY})
-  SET(FMOD_FOUND "YES")
-ELSE (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
-  SET(FMOD_FOUND "NO")
-ENDIF (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
-
-IF (FMOD_FOUND)
-  IF (NOT FMOD_FIND_QUIETLY)
-    MESSAGE(STATUS "Found FMOD: ${FMOD_LIBRARIES}")
-  ENDIF (NOT FMOD_FIND_QUIETLY)
-ELSE (FMOD_FOUND)
-  IF (FMOD_FIND_REQUIRED)
-    MESSAGE(FATAL_ERROR "Could not find FMOD library")
-  ENDIF (FMOD_FIND_REQUIRED)
-ENDIF (FMOD_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_FMOD_INCLUDE_PATH ${FMOD_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_FMOD_LIB_PATH ${FMOD_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  FMOD_LIBRARY
-  FMOD_INCLUDE_DIR
-  )
diff --git a/indra/cmake/FindFMODEX.cmake b/indra/cmake/FindFMODEX.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..b621727c0ea490c8d55c7d89f243813ab698bda6
--- /dev/null
+++ b/indra/cmake/FindFMODEX.cmake
@@ -0,0 +1,65 @@
+# -*- cmake -*-
+
+# - Find FMODEX
+# Find the FMODEX includes and library
+# This module defines
+#  FMODEX_INCLUDE_DIR, where to find fmod.h and fmod_errors.h
+#  FMODEX_LIBRARIES, the libraries needed to use FMODEX.
+#  FMODEX, If false, do not try to use FMODEX.
+# also defined, but not for general use are
+#  FMODEX_LIBRARY, where to find the FMODEX library.
+
+FIND_PATH(FMODEX_INCLUDE_DIR fmod.h PATH_SUFFIXES fmod)
+
+SET(FMODEX_NAMES ${FMODEX_NAMES} fmodex fmodvc fmodexL_vc)
+FIND_LIBRARY(FMODEX_LIBRARY
+  NAMES ${FMODEX_NAMES}
+  PATH_SUFFIXES fmodex
+  )
+
+IF (FMODEX_SDK_DIR OR WINDOWS)
+    if(WINDOWS)
+        set(FMODEX_SDK_DIR "$ENV{PROGRAMFILES}/FMOD SoundSystem/FMOD Programmers API Windows" CACHE PATH "Path to FMODEX")
+        STRING(REGEX REPLACE "\\\\" "/" FMODEX_SDK_DIR ${FMODEX_SDK_DIR}) 
+    endif(WINDOWS)
+    find_library(FMODEX_LIBRARY
+             fmodex_vc fmodexL_vc 
+             PATHS
+             ${FMODEX_SDK_DIR}/api/lib
+             ${FMODEX_SDK_DIR}/api
+             ${FMODEX_SDK_DIR}
+             )
+    find_path(FMODEX_INCLUDE_DIR fmod.h
+        ${FMODEX_SDK_DIR}/api/inc
+        ${FMODEX_SDK_DIR}/api
+        ${FMODEX_SDK_DIR}
+      )
+    find_path(FMODEX_INCLUDE_DIR fmod.h
+        ${FMODEX_SDK_DIR}/api/inc
+        ${FMODEX_SDK_DIR}/api
+        ${FMODEX_SDK_DIR}
+      )
+    IF (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
+      SET(FMODEX_LIBRARIES ${FMODEX_LIBRARY})
+      SET(FMODEX_FOUND "YES")
+    endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
+ENDIF (FMODEX_SDK_DIR OR WINDOWS)
+
+IF (FMODEX_FOUND)
+  IF (NOT FMODEX_FIND_QUIETLY)
+    MESSAGE(STATUS "Found FMODEX: ${FMODEX_LIBRARIES}")
+  ENDIF (NOT FMODEX_FIND_QUIETLY)
+ELSE (FMODEX_FOUND)
+  IF (FMODEX_FIND_REQUIRED)
+    MESSAGE(FATAL_ERROR "Could not find FMODEX library")
+  ENDIF (FMODEX_FIND_REQUIRED)
+ENDIF (FMODEX_FOUND)
+
+# Deprecated declarations.
+SET (NATIVE_FMODEX_INCLUDE_PATH ${FMODEX_INCLUDE_DIR} )
+GET_FILENAME_COMPONENT (NATIVE_FMODEX_LIB_PATH ${FMODEX_LIBRARY} PATH)
+
+MARK_AS_ADVANCED(
+  FMODEX_LIBRARY
+  FMODEX_INCLUDE_DIR
+  )
diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt
index 24d25311065c5db5772b21019d52390bd366a6cc..1b2bdb9888c7005beb56ef4f220c049cf2b892dc 100644
--- a/indra/llaudio/CMakeLists.txt
+++ b/indra/llaudio/CMakeLists.txt
@@ -5,7 +5,7 @@ project(llaudio)
 include(00-Common)
 include(Audio)
 include(LLAudio)
-include(FMOD)
+include(FMODEX)
 include(OPENAL)
 include(LLCommon)
 include(LLMath)
@@ -24,7 +24,6 @@ include_directories(
     ${VORBIS_INCLUDE_DIRS}
     ${OPENAL_LIB_INCLUDE_DIRS}
     ${FREEAULT_LIB_INCLUDE_DIRS}
-    ${FMOD_INCLUDE_DIR}
     )
 
 set(llaudio_SOURCE_FILES
@@ -44,29 +43,22 @@ set(llaudio_HEADER_FILES
     llwindgen.h
     )
 
-if (FMOD)
+if (FMODEX)
     include_directories(
-        ${FMOD_INCLUDE_DIR}
+        ${FMODEX_INCLUDE_DIR}
         )
-
     list(APPEND llaudio_SOURCE_FILES
-         llaudioengine_fmod.cpp
-         lllistener_fmod.cpp
-         llstreamingaudio_fmod.cpp
+         llaudioengine_fmodex.cpp
+         lllistener_fmodex.cpp
+         llstreamingaudio_fmodex.cpp
          )
 
     list(APPEND llaudio_HEADER_FILES
-         llaudioengine_fmod.h
-         lllistener_fmod.h
-         llstreamingaudio_fmod.h
+         llaudioengine_fmodex.h
+         lllistener_fmodex.h
+         llstreamingaudio_fmodex.h
          )
-
-    if (LINUX OR DARWIN)
-      set_source_files_properties(llaudioengine_fmod.cpp
-                                  llstreamingaudio_fmod.cpp
-                                  COMPILE_FLAGS -Wno-write-strings)
-    endif (LINUX OR DARWIN)
-endif (FMOD)
+endif (FMODEX)
 
 if (OPENAL)
   list(APPEND llaudio_SOURCE_FILES
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index 99b96c3c38b21d1df09462699d48dff17204a288..da1629a1db57a7c1fda86305a06e6ced52e90898 100644
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -42,7 +42,6 @@
 #include "lllistener.h"
 
 const F32 LL_WIND_UPDATE_INTERVAL = 0.1f;
-const F32 LL_ROLLOFF_MULTIPLIER_UNDER_WATER = 5.f;			//  How much sounds are weaker under water
 const F32 LL_WIND_UNDERWATER_CENTER_FREQ = 20.f;
 
 const F32 ATTACHED_OBJECT_TIMEOUT = 5.0f;
diff --git a/indra/llaudio/llaudioengine_fmod.cpp b/indra/llaudio/llaudioengine_fmod.cpp
deleted file mode 100644
index a40de9fa68b21afe656d862642d2b7992a33829f..0000000000000000000000000000000000000000
--- a/indra/llaudio/llaudioengine_fmod.cpp
+++ /dev/null
@@ -1,781 +0,0 @@
-/** 
- * @file audioengine_fmod.cpp
- * @brief Implementation of LLAudioEngine class abstracting the audio support as a FMOD 3D implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-
-#include "llstreamingaudio.h"
-#include "llstreamingaudio_fmod.h"
-
-#include "llaudioengine_fmod.h"
-#include "lllistener_fmod.h"
-
-#include "llerror.h"
-#include "llmath.h"
-#include "llrand.h"
-
-#include "fmod.h"
-#include "fmod_errors.h"
-#include "lldir.h"
-#include "llapr.h"
-
-#include "sound_ids.h"
-
-
-extern "C" {
-	void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata);
-}
-
-
-LLAudioEngine_FMOD::LLAudioEngine_FMOD()
-{
-	mInited = false;
-	mWindGen = NULL;
-	mWindDSP = NULL;
-}
-
-
-LLAudioEngine_FMOD::~LLAudioEngine_FMOD()
-{
-}
-
-
-bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
-{
-	LLAudioEngine::init(num_channels, userdata);
-
-	// Reserve one extra channel for the http stream.
-	if (!FSOUND_SetMinHardwareChannels(num_channels + 1))
-	{
-		LL_WARNS("AppInit") << "FMOD::init[0](), error: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
-	}
-
-	LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() initializing FMOD" << LL_ENDL;
-
-	F32 version = FSOUND_GetVersion();
-	if (version < FMOD_VERSION)
-	{
-		LL_WARNS("AppInit") << "Error : You are using the wrong FMOD version (" << version
-			<< ")!  You should be using FMOD " << FMOD_VERSION << LL_ENDL;
-		//return false;
-	}
-
-	U32 fmod_flags = 0x0;
-
-#if LL_WINDOWS
-	// Windows needs to know which window is frontmost.
-	// This must be called before FSOUND_Init() per the FMOD docs.
-	// This could be used to let FMOD handle muting when we lose focus,
-	// but we don't actually want to do that because we want to distinguish
-	// between minimized and not-focused states.
-	if (!FSOUND_SetHWND(userdata))
-	{
-		LL_WARNS("AppInit") << "Error setting FMOD window: "
-			<< FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
-		return false;
-	}
-	// Play audio when we don't have focus.
-	// (For example, IM client on top of us.)
-	// This means we also try to play audio when minimized,
-	// so we manually handle muting in that case. JC
-	fmod_flags |= FSOUND_INIT_GLOBALFOCUS;
-#endif
-
-#if LL_LINUX
-	// initialize the FMOD engine
-
-	// This is a hack to use only FMOD's basic FPU mixer
-	// when the LL_VALGRIND environmental variable is set,
-	// otherwise valgrind will fall over on FMOD's MMX detection
-	if (getenv("LL_VALGRIND"))		/*Flawfinder: ignore*/
-	{
-		LL_INFOS("AppInit") << "Pacifying valgrind in FMOD init." << LL_ENDL;
-		FSOUND_SetMixer(FSOUND_MIXER_QUALITY_FPU);
-	}
-
-	// If we don't set an output method, Linux FMOD always
-	// decides on OSS and fails otherwise.  So we'll manually
-	// try ESD, then OSS, then ALSA.
-	// Why this order?  See SL-13250, but in short, OSS emulated
-	// on top of ALSA is ironically more reliable than raw ALSA.
-	// Ack, and ESD has more reliable failure modes - but has worse
-	// latency - than all of them, so wins for now.
-	bool audio_ok = false;
-
-	if (!audio_ok)
-	{
-		if (NULL == getenv("LL_BAD_FMOD_ESD")) /*Flawfinder: ignore*/
-		{
-			LL_DEBUGS("AppInit") << "Trying ESD audio output..." << LL_ENDL;
-			if(FSOUND_SetOutput(FSOUND_OUTPUT_ESD) &&
-			   FSOUND_Init(44100, num_channels, fmod_flags))
-			{
-				LL_DEBUGS("AppInit") << "ESD audio output initialized OKAY"
-					<< LL_ENDL;
-				audio_ok = true;
-			} else {
-				LL_WARNS("AppInit") << "ESD audio output FAILED to initialize: "
-					<< FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
-			}
-		} else {
-			LL_DEBUGS("AppInit") << "ESD audio output SKIPPED" << LL_ENDL;
-		}
-	}
-	if (!audio_ok)
-	{
-		if (NULL == getenv("LL_BAD_FMOD_OSS")) 	 /*Flawfinder: ignore*/
-		{
-			LL_DEBUGS("AppInit") << "Trying OSS audio output..."	<< LL_ENDL;
-			if(FSOUND_SetOutput(FSOUND_OUTPUT_OSS) &&
-			   FSOUND_Init(44100, num_channels, fmod_flags))
-			{
-				LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL;
-				audio_ok = true;
-			} else {
-				LL_WARNS("AppInit") << "OSS audio output FAILED to initialize: "
-					<< FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
-			}
-		} else {
-			LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL;
-		}
-	}
-	if (!audio_ok)
-	{
-		if (NULL == getenv("LL_BAD_FMOD_ALSA"))		/*Flawfinder: ignore*/
-		{
-			LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL;
-			if(FSOUND_SetOutput(FSOUND_OUTPUT_ALSA) &&
-			   FSOUND_Init(44100, num_channels, fmod_flags))
-			{
-				LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
-				audio_ok = true;
-			} else {
-				LL_WARNS("AppInit") << "ALSA audio output FAILED to initialize: "
-					<< FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
-			}
-		} else {
-			LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL;
-		}
-	}
-	if (!audio_ok)
-	{
-		LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL;
-		return false;
-	}
-
-	// On Linux, FMOD causes a SIGPIPE for some netstream error
-	// conditions (an FMOD bug); ignore SIGPIPE so it doesn't crash us.
-	// NOW FIXED in FMOD 3.x since 2006-10-01.
-	//signal(SIGPIPE, SIG_IGN);
-
-	// We're interested in logging which output method we
-	// ended up with, for QA purposes.
-	switch (FSOUND_GetOutput())
-	{
-	case FSOUND_OUTPUT_NOSOUND: LL_DEBUGS("AppInit") << "Audio output: NoSound" << LL_ENDL; break;
-	case FSOUND_OUTPUT_OSS:	LL_DEBUGS("AppInit") << "Audio output: OSS" << LL_ENDL; break;
-	case FSOUND_OUTPUT_ESD:	LL_DEBUGS("AppInit") << "Audio output: ESD" << LL_ENDL; break;
-	case FSOUND_OUTPUT_ALSA: LL_DEBUGS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
-	default: LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
-	};
-
-#else // LL_LINUX
-
-	// initialize the FMOD engine
-	if (!FSOUND_Init(44100, num_channels, fmod_flags))
-	{
-		LL_WARNS("AppInit") << "Error initializing FMOD: "
-			<< FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
-		return false;
-	}
-	
-#endif
-
-	// set up our favourite FMOD-native streaming audio implementation if none has already been added
-	if (!getStreamingAudioImpl()) // no existing implementation added
-		setStreamingAudioImpl(new LLStreamingAudio_FMOD());
-
-	LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() FMOD initialized correctly" << LL_ENDL;
-
-	mInited = true;
-
-	return true;
-}
-
-
-std::string LLAudioEngine_FMOD::getDriverName(bool verbose)
-{
-	if (verbose)
-	{
-		F32 version = FSOUND_GetVersion();
-		return llformat("FMOD version %f", version);
-	}
-	else
-	{
-		return "FMOD";
-	}
-}
-
-
-void LLAudioEngine_FMOD::allocateListener(void)
-{	
-	mListenerp = (LLListener *) new LLListener_FMOD();
-	if (!mListenerp)
-	{
-		llwarns << "Listener creation failed" << llendl;
-	}
-}
-
-
-void LLAudioEngine_FMOD::shutdown()
-{
-	if (mWindDSP)
-	{
-		FSOUND_DSP_SetActive(mWindDSP,false);
-		FSOUND_DSP_Free(mWindDSP);
-	}
-
-	stopInternetStream();
-
-	LLAudioEngine::shutdown();
-	
-	llinfos << "LLAudioEngine_FMOD::shutdown() closing FMOD" << llendl;
-	FSOUND_Close();
-	llinfos << "LLAudioEngine_FMOD::shutdown() done closing FMOD" << llendl;
-
-	delete mListenerp;
-	mListenerp = NULL;
-}
-
-
-LLAudioBuffer * LLAudioEngine_FMOD::createBuffer()
-{
-	return new LLAudioBufferFMOD();
-}
-
-
-LLAudioChannel * LLAudioEngine_FMOD::createChannel()
-{
-	return new LLAudioChannelFMOD();
-}
-
-
-bool LLAudioEngine_FMOD::initWind()
-{
-	if (!mWindGen)
-	{
-		bool enable;
-		
-		switch (FSOUND_GetMixer())
-		{
-			case FSOUND_MIXER_MMXP5:
-			case FSOUND_MIXER_MMXP6:
-			case FSOUND_MIXER_QUALITY_MMXP5:
-			case FSOUND_MIXER_QUALITY_MMXP6:
-				enable = (typeid(MIXBUFFERFORMAT) == typeid(S16));
-				break;
-			case FSOUND_MIXER_BLENDMODE:
-				enable = (typeid(MIXBUFFERFORMAT) == typeid(S32));
-				break;
-			case FSOUND_MIXER_QUALITY_FPU:
-				enable = (typeid(MIXBUFFERFORMAT) == typeid(F32));
-				break;
-			default:
-				// FSOUND_GetMixer() does not return a valid mixer type on Darwin
-				LL_INFOS("AppInit") << "Unknown FMOD mixer type, assuming default" << LL_ENDL;
-				enable = true;
-				break;
-		}
-		
-		if (enable)
-		{
-			mWindGen = new LLWindGen<MIXBUFFERFORMAT>(FSOUND_GetOutputRate());
-		}
-		else
-		{
-			LL_WARNS("AppInit") << "Incompatible FMOD mixer type, wind noise disabled" << LL_ENDL;
-		}
-	}
-
-	mNextWindUpdate = 0.0;
-
-	if (mWindGen && !mWindDSP)
-	{
-		mWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, mWindGen);
-	}
-	if (mWindDSP)
-	{
-		FSOUND_DSP_SetActive(mWindDSP, true);
-		return true;
-	}
-	
-	return false;
-}
-
-
-void LLAudioEngine_FMOD::cleanupWind()
-{
-	if (mWindDSP)
-	{
-		FSOUND_DSP_SetActive(mWindDSP, false);
-		FSOUND_DSP_Free(mWindDSP);
-		mWindDSP = NULL;
-	}
-
-	delete mWindGen;
-	mWindGen = NULL;
-}
-
-
-//-----------------------------------------------------------------------
-void LLAudioEngine_FMOD::updateWind(LLVector3 wind_vec, F32 camera_height_above_water)
-{
-	LLVector3 wind_pos;
-	F64 pitch;
-	F64 center_freq;
-
-	if (!mEnableWind)
-	{
-		return;
-	}
-	
-	if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
-	{
-		
-		// wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
-		// need to convert this to the conventional orientation DS3D and OpenAL use
-		// where +X = right, +Y = up, +Z = backwards
-
-		wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
-
-		// cerr << "Wind update" << endl;
-
-		pitch = 1.0 + mapWindVecToPitch(wind_vec);
-		center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
-		
-		mWindGen->mTargetFreq = (F32)center_freq;
-		mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
-		mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
-  	}
-}
-
-/*
-//-----------------------------------------------------------------------
-void LLAudioEngine_FMOD::setSourceMinDistance(U16 source_num, F64 distance)
-{
-	if (!mInited)
-	{
-		return;
-	}
-	if (mBuffer[source_num])
-	{
-		mMinDistance[source_num] = (F32) distance;
-		if (!FSOUND_Sample_SetMinMaxDistance(mBuffer[source_num],mMinDistance[source_num], mMaxDistance[source_num]))
-		{
-			llwarns << "FMOD::setSourceMinDistance(" << source_num << "), error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
-		}
-	}
-}
-
-//-----------------------------------------------------------------------
-void LLAudioEngine_FMOD::setSourceMaxDistance(U16 source_num, F64 distance)
-{
-	if (!mInited)
-	{
-		return;
-	}
-	if (mBuffer[source_num])
-	{
-		mMaxDistance[source_num] = (F32) distance;
-		if (!FSOUND_Sample_SetMinMaxDistance(mBuffer[source_num],mMinDistance[source_num], mMaxDistance[source_num]))
-		{
-			llwarns << "FMOD::setSourceMaxDistance(" << source_num << "), error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
-		}
-	}
-}
-
-//-----------------------------------------------------------------------
-void LLAudioEngine_FMOD::get3DParams(S32 source_num, S32 *volume, S32 *freq, S32 *inside, S32 *outside, LLVector3 *orient, S32 *out_volume, F32 *min_dist, F32 *max_dist)
-{
-	*volume = 0;
-	*freq = 0;
-	*inside = 0;
-	*outside = 0;
-	*orient = LLVector3::zero;
-	*out_volume = 0;
-	*min_dist = 0.f;
-	*max_dist = 0.f;
-}
-
-*/
-
-
-//-----------------------------------------------------------------------
-void LLAudioEngine_FMOD::setInternalGain(F32 gain)
-{
-	if (!mInited)
-	{
-		return;
-	}
-
-	gain = llclamp( gain, 0.0f, 1.0f );
-	FSOUND_SetSFXMasterVolume( llround( 255.0f * gain ) );
-
-	LLStreamingAudioInterface *saimpl = getStreamingAudioImpl();
-	if ( saimpl )
-	{
-		// fmod likes its streaming audio channel gain re-asserted after
-		// master volume change.
-		saimpl->setGain(saimpl->getGain());
-	}
-}
-
-//
-// LLAudioChannelFMOD implementation
-//
-
-LLAudioChannelFMOD::LLAudioChannelFMOD() : LLAudioChannel(), mChannelID(0), mLastSamplePos(0)
-{
-}
-
-
-LLAudioChannelFMOD::~LLAudioChannelFMOD()
-{
-	cleanup();
-}
-
-
-bool LLAudioChannelFMOD::updateBuffer()
-{
-	if (LLAudioChannel::updateBuffer())
-	{
-		// Base class update returned true, which means that we need to actually
-		// set up the channel for a different buffer.
-
-		LLAudioBufferFMOD *bufferp = (LLAudioBufferFMOD *)mCurrentSourcep->getCurrentBuffer();
-
-		// Grab the FMOD sample associated with the buffer
-		FSOUND_SAMPLE *samplep = bufferp->getSample();
-		if (!samplep)
-		{
-			// This is bad, there should ALWAYS be a sample associated with a legit
-			// buffer.
-			llerrs << "No FMOD sample!" << llendl;
-			return false;
-		}
-
-
-		// Actually play the sound.  Start it off paused so we can do all the necessary
-		// setup.
-		mChannelID = FSOUND_PlaySoundEx(FSOUND_FREE, samplep, FSOUND_DSP_GetSFXUnit(), true);
-
-		//llinfos << "Setting up channel " << std::hex << mChannelID << std::dec << llendl;
-	}
-
-	// If we have a source for the channel, we need to update its gain.
-	if (mCurrentSourcep)
-	{
-		// SJB: warnings can spam and hurt framerate, disabling
-		if (!FSOUND_SetVolume(mChannelID, llround(getSecondaryGain() * mCurrentSourcep->getGain() * 255.0f)))
-		{
-// 			llwarns << "LLAudioChannelFMOD::updateBuffer error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
-		}
-		
-		if (!FSOUND_SetLoopMode(mChannelID, mCurrentSourcep->isLoop() ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF))
-		{
-// 			llwarns << "Channel " << mChannelID << "Source ID: " << mCurrentSourcep->getID()
-// 					<< " at " << mCurrentSourcep->getPositionGlobal() << llendl;
-// 			llwarns << "LLAudioChannelFMOD::updateBuffer error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
-		}
-	}
-
-	return true;
-}
-
-
-void LLAudioChannelFMOD::update3DPosition()
-{
-	if (!mChannelID)
-	{
-		// We're not actually a live channel (i.e., we're not playing back anything)
-		return;
-	}
-
-	LLAudioBufferFMOD *bufferp = (LLAudioBufferFMOD *)mCurrentBufferp;
-	if (!bufferp)
-	{
-		// We don't have a buffer associated with us (should really have been picked up
-		// by the above if.
-		return;
-	}
-
-	if (mCurrentSourcep->isAmbient())
-	{
-		// Ambient sound, don't need to do any positional updates.
-		bufferp->set3DMode(false);
-	}
-	else
-	{
-		// Localized sound.  Update the position and velocity of the sound.
-		bufferp->set3DMode(true);
-
-		LLVector3 float_pos;
-		float_pos.setVec(mCurrentSourcep->getPositionGlobal());
-		if (!FSOUND_3D_SetAttributes(mChannelID, float_pos.mV, mCurrentSourcep->getVelocity().mV))
-		{
-			LL_DEBUGS("FMOD") << "LLAudioChannelFMOD::update3DPosition error: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
-		}
-	}
-}
-
-
-void LLAudioChannelFMOD::updateLoop()
-{
-	if (!mChannelID)
-	{
-		// May want to clear up the loop/sample counters.
-		return;
-	}
-
-	//
-	// Hack:  We keep track of whether we looped or not by seeing when the
-	// sample position looks like it's going backwards.  Not reliable; may
-	// yield false negatives.
-	//
-	U32 cur_pos = FSOUND_GetCurrentPosition(mChannelID);
-	if (cur_pos < (U32)mLastSamplePos)
-	{
-		mLoopedThisFrame = true;
-	}
-	mLastSamplePos = cur_pos;
-}
-
-
-void LLAudioChannelFMOD::cleanup()
-{
-	if (!mChannelID)
-	{
-		//llinfos << "Aborting cleanup with no channelID." << llendl;
-		return;
-	}
-
-	//llinfos << "Cleaning up channel: " << mChannelID << llendl;
-	if (!FSOUND_StopSound(mChannelID))
-	{
-		LL_DEBUGS("FMOD") << "LLAudioChannelFMOD::cleanup error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
-	}
-
-	mCurrentBufferp = NULL;
-	mChannelID = 0;
-}
-
-
-void LLAudioChannelFMOD::play()
-{
-	if (!mChannelID)
-	{
-		llwarns << "Playing without a channelID, aborting" << llendl;
-		return;
-	}
-
-	if (!FSOUND_SetPaused(mChannelID, false))
-	{
-		llwarns << "LLAudioChannelFMOD::play error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
-	}
-	getSource()->setPlayedOnce(true);
-}
-
-
-void LLAudioChannelFMOD::playSynced(LLAudioChannel *channelp)
-{
-	LLAudioChannelFMOD *fmod_channelp = (LLAudioChannelFMOD*)channelp;
-	if (!(fmod_channelp->mChannelID && mChannelID))
-	{
-		// Don't have channels allocated to both the master and the slave
-		return;
-	}
-
-	U32 position = FSOUND_GetCurrentPosition(fmod_channelp->mChannelID) % mCurrentBufferp->getLength();
-	// Try to match the position of our sync master
-	if (!FSOUND_SetCurrentPosition(mChannelID, position))
-	{
-		llwarns << "LLAudioChannelFMOD::playSynced unable to set current position" << llendl;
-	}
-
-	// Start us playing
-	play();
-}
-
-
-bool LLAudioChannelFMOD::isPlaying()
-{
-	if (!mChannelID)
-	{
-		return false;
-	}
-
-	return FSOUND_IsPlaying(mChannelID) && (!FSOUND_GetPaused(mChannelID));
-}
-
-
-
-//
-// LLAudioBufferFMOD implementation
-//
-
-
-LLAudioBufferFMOD::LLAudioBufferFMOD()
-{
-	mSamplep = NULL;
-}
-
-
-LLAudioBufferFMOD::~LLAudioBufferFMOD()
-{
-	if (mSamplep)
-	{
-		// Clean up the associated FMOD sample if it exists.
-		FSOUND_Sample_Free(mSamplep);
-		mSamplep = NULL;
-	}
-}
-
-
-bool LLAudioBufferFMOD::loadWAV(const std::string& filename)
-{
-	// Try to open a wav file from disk.  This will eventually go away, as we don't
-	// really want to block doing this.
-	if (filename.empty())
-	{
-		// invalid filename, abort.
-		return false;
-	}
-
-	if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB))
-	{
-		// File not found, abort.
-		return false;
-	}
-	
-	if (mSamplep)
-	{
-		// If there's already something loaded in this buffer, clean it up.
-		FSOUND_Sample_Free(mSamplep);
-		mSamplep = NULL;
-	}
-
-	// Load up the wav file into an fmod sample
-#if LL_WINDOWS
-	// MikeS. - Loading the sound file manually and then handing it over to FMOD,
-	//	since FMOD uses posix IO internally,
-	// which doesn't work with unicode file paths.
-	LLFILE* sound_file = LLFile::fopen(filename,"rb");	/* Flawfinder: ignore */
-	if (sound_file)
-	{
-		fseek(sound_file,0,SEEK_END);
-		U32	file_length = ftell(sound_file);	//Find the length of the file by seeking to the end and getting the offset
-		size_t	read_count;
-		fseek(sound_file,0,SEEK_SET);	//Seek back to the beginning
-		char*	buffer = new char[file_length];
-		llassert(buffer);
-		read_count = fread((void*)buffer,file_length,1,sound_file);//Load it..
-		if(ferror(sound_file)==0 && (read_count == 1)){//No read error, and we got 1 chunk of our size...
-			unsigned int mode_flags = FSOUND_LOOP_NORMAL | FSOUND_LOADMEMORY;
-									//FSOUND_16BITS | FSOUND_MONO | FSOUND_LOADMEMORY | FSOUND_LOOP_NORMAL;
-			mSamplep = FSOUND_Sample_Load(FSOUND_UNMANAGED, buffer, mode_flags , 0, file_length);
-		}
-		delete[] buffer;
-		fclose(sound_file);
-	}
-#else
-	mSamplep = FSOUND_Sample_Load(FSOUND_UNMANAGED, filename.c_str(), FSOUND_LOOP_NORMAL, 0, 0);
-#endif
-
-	if (!mSamplep)
-	{
-		// We failed to load the file for some reason.
-		llwarns << "Could not load data '" << filename << "': "
-				<< FMOD_ErrorString(FSOUND_GetError()) << llendl;
-
-		//
-		// If we EVER want to load wav files provided by end users, we need
-		// to rethink this!
-		//
-		// file is probably corrupt - remove it.
-		LLFile::remove(filename);
-		return false;
-	}
-
-	// Everything went well, return true
-	return true;
-}
-
-
-U32 LLAudioBufferFMOD::getLength()
-{
-	if (!mSamplep)
-	{
-		return 0;
-	}
-
-	return FSOUND_Sample_GetLength(mSamplep);
-}
-
-
-void LLAudioBufferFMOD::set3DMode(bool use3d)
-{
-	U16 current_mode = FSOUND_Sample_GetMode(mSamplep);
-	
-	if (use3d)
-	{
-		if (!FSOUND_Sample_SetMode(mSamplep, (current_mode & (~FSOUND_2D))))
-		{
-			llwarns << "LLAudioBufferFMOD::set3DMode error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
-		}
-	}
-	else
-	{
-		if (!FSOUND_Sample_SetMode(mSamplep, current_mode | FSOUND_2D))
-		{
-			llwarns << "LLAudioBufferFMOD::set3DMode error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
-		}
-	}
-}
-
-
-void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata)
-{
-	// originalbuffer = fmod's original mixbuffer.
-	// newbuffer = the buffer passed from the previous DSP unit.
-	// length = length in samples at this mix time.
-	// userdata = user parameter passed through in FSOUND_DSP_Create.
-
-	LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *windgen =
-		(LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *)userdata;
-	
-	newbuffer = windgen->windGenerate((LLAudioEngine_FMOD::MIXBUFFERFORMAT *)newbuffer, length);
-
-	return newbuffer;
-}
diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5ec30c7d1d05f4397380455513d64e2cd7fefec8
--- /dev/null
+++ b/indra/llaudio/llaudioengine_fmodex.cpp
@@ -0,0 +1,746 @@
+/** 
+ * @file audioengine_fmodex.cpp
+ * @brief Implementation of LLAudioEngine class abstracting the audio 
+ * support as a FMODEX implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llstreamingaudio.h"
+#include "llstreamingaudio_fmodex.h"
+
+#include "llaudioengine_fmodex.h"
+#include "lllistener_fmodex.h"
+
+#include "llerror.h"
+#include "llmath.h"
+#include "llrand.h"
+
+#include "fmod.hpp"
+#include "fmod_errors.h"
+#include "lldir.h"
+#include "llapr.h"
+
+#include "sound_ids.h"
+
+FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels);
+
+FMOD::ChannelGroup *LLAudioEngine_FMODEX::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0};
+
+LLAudioEngine_FMODEX::LLAudioEngine_FMODEX(bool enable_profiler)
+{
+	mInited = false;
+	mWindGen = NULL;
+	mWindDSP = NULL;
+	mSystem = NULL;
+	mEnableProfiler = enable_profiler;
+}
+
+
+LLAudioEngine_FMODEX::~LLAudioEngine_FMODEX()
+{
+}
+
+
+inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string)
+{
+	if(result == FMOD_OK)
+		return false;
+	llwarns << string << " Error: " << FMOD_ErrorString(result) << llendl;
+	return true;
+}
+
+void* F_STDCALL decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr)
+{
+	if(type & FMOD_MEMORY_STREAM_DECODE)
+	{
+		llinfos << "Decode buffer size: " << size << llendl;
+	}
+	else if(type & FMOD_MEMORY_STREAM_FILE)
+	{
+		llinfos << "Strean buffer size: " << size << llendl;
+	}
+	return new char[size];
+}
+void* F_STDCALL decode_realloc(void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr)
+{
+	memset(ptr,0,size);
+	return ptr;
+}
+void F_STDCALL decode_dealloc(void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr)
+{
+	delete[] (char*)ptr;
+}
+
+bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
+{
+	U32 version;
+	FMOD_RESULT result;
+
+	LL_DEBUGS("AppInit") << "LLAudioEngine_FMODEX::init() initializing FMOD" << LL_ENDL;
+
+	//result = FMOD::Memory_Initialize(NULL, 0, &decode_alloc, &decode_realloc, &decode_dealloc, FMOD_MEMORY_STREAM_DECODE | FMOD_MEMORY_STREAM_FILE);
+	//if(Check_FMOD_Error(result, "FMOD::Memory_Initialize"))
+	//	return false;
+
+	result = FMOD::System_Create(&mSystem);
+	if(Check_FMOD_Error(result, "FMOD::System_Create"))
+		return false;
+
+	//will call LLAudioEngine_FMODEX::allocateListener, which needs a valid mSystem pointer.
+	LLAudioEngine::init(num_channels, userdata);	
+	
+	result = mSystem->getVersion(&version);
+	Check_FMOD_Error(result, "FMOD::System::getVersion");
+
+	if (version < FMOD_VERSION)
+	{
+		LL_WARNS("AppInit") << "Error : You are using the wrong FMOD Ex version (" << version
+			<< ")!  You should be using FMOD Ex" << FMOD_VERSION << LL_ENDL;
+	}
+
+	result = mSystem->setSoftwareFormat(44100, FMOD_SOUND_FORMAT_PCM16, 0, 0, FMOD_DSP_RESAMPLER_LINEAR);
+	Check_FMOD_Error(result,"FMOD::System::setSoftwareFormat");
+
+	// In this case, all sounds, PLUS wind and stream will be software.
+	result = mSystem->setSoftwareChannels(num_channels + 2);
+	Check_FMOD_Error(result,"FMOD::System::setSoftwareChannels");
+
+	U32 fmod_flags = FMOD_INIT_NORMAL;
+	if(mEnableProfiler)
+	{
+		fmod_flags |= FMOD_INIT_ENABLE_PROFILE;
+		mSystem->createChannelGroup("None", &mChannelGroups[AUDIO_TYPE_NONE]);
+		mSystem->createChannelGroup("SFX", &mChannelGroups[AUDIO_TYPE_SFX]);
+		mSystem->createChannelGroup("UI", &mChannelGroups[AUDIO_TYPE_UI]);
+		mSystem->createChannelGroup("Ambient", &mChannelGroups[AUDIO_TYPE_AMBIENT]);
+	}
+
+#if LL_LINUX
+	bool audio_ok = false;
+
+	if (!audio_ok)
+	{
+		if (NULL == getenv("LL_BAD_FMOD_PULSEAUDIO")) /*Flawfinder: ignore*/
+		{
+			LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL;
+			if(mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK &&
+				(result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
+			{
+				LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY"	<< LL_ENDL;
+				audio_ok = true;
+			}
+			else 
+			{
+				Check_FMOD_Error(result, "PulseAudio audio output FAILED to initialize");
+			}
+		} 
+		else 
+		{
+			LL_DEBUGS("AppInit") << "PulseAudio audio output SKIPPED" << LL_ENDL;
+		}	
+	}
+	if (!audio_ok)
+	{
+		if (NULL == getenv("LL_BAD_FMOD_ALSA"))		/*Flawfinder: ignore*/
+		{
+			LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL;
+			if(mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA) == FMOD_OK &&
+			    (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
+			{
+				LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
+				audio_ok = true;
+			} 
+			else 
+			{
+				Check_FMOD_Error(result, "ALSA audio output FAILED to initialize");
+			}
+		} 
+		else 
+		{
+			LL_DEBUGS("AppInit") << "ALSA audio output SKIPPED" << LL_ENDL;
+		}
+	}
+	if (!audio_ok)
+	{
+		if (NULL == getenv("LL_BAD_FMOD_OSS")) 	 /*Flawfinder: ignore*/
+		{
+			LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL;
+			if(mSystem->setOutput(FMOD_OUTPUTTYPE_OSS) == FMOD_OK &&
+			    (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
+			{
+				LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL;
+				audio_ok = true;
+			}
+			else
+			{
+				Check_FMOD_Error(result, "OSS audio output FAILED to initialize");
+			}
+		}
+		else 
+		{
+			LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL;
+		}
+	}
+	if (!audio_ok)
+	{
+		LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL;
+		return false;
+	}
+
+	// We're interested in logging which output method we
+	// ended up with, for QA purposes.
+	FMOD_OUTPUTTYPE output_type;
+	mSystem->getOutput(&output_type);
+	switch (output_type)
+	{
+		case FMOD_OUTPUTTYPE_NOSOUND: 
+			LL_INFOS("AppInit") << "Audio output: NoSound" << LL_ENDL; break;
+		case FMOD_OUTPUTTYPE_PULSEAUDIO:	
+			LL_INFOS("AppInit") << "Audio output: PulseAudio" << LL_ENDL; break;
+		case FMOD_OUTPUTTYPE_ALSA: 
+			LL_INFOS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
+		case FMOD_OUTPUTTYPE_OSS:	
+			LL_INFOS("AppInit") << "Audio output: OSS" << LL_ENDL; break;
+		default:
+			LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
+	};
+#else // LL_LINUX
+
+	// initialize the FMOD engine
+	result = mSystem->init( num_channels + 2, fmod_flags, 0);
+	if (result == FMOD_ERR_OUTPUT_CREATEBUFFER)
+	{
+		/*
+		Ok, the speaker mode selected isn't supported by this soundcard. Switch it
+		back to stereo...
+		*/
+		result = mSystem->setSpeakerMode(FMOD_SPEAKERMODE_STEREO);
+		Check_FMOD_Error(result,"Error falling back to stereo mode");
+		/*
+		... and re-init.
+		*/
+		result = mSystem->init( num_channels + 2, fmod_flags, 0);
+	}
+	if(Check_FMOD_Error(result, "Error initializing FMOD Ex"))
+		return false;
+#endif
+
+	// set up our favourite FMOD-native streaming audio implementation if none has already been added
+	if (!getStreamingAudioImpl()) // no existing implementation added
+		setStreamingAudioImpl(new LLStreamingAudio_FMODEX(mSystem));
+
+	LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init() FMOD Ex initialized correctly" << LL_ENDL;
+
+	int r_numbuffers, r_samplerate, r_channels, r_bits;
+	unsigned int r_bufferlength;
+	char r_name[256];
+	mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers);
+	mSystem->getSoftwareFormat(&r_samplerate, NULL, &r_channels, NULL, NULL, &r_bits);
+	mSystem->getDriverInfo(0, r_name, 255, 0);
+	r_name[255] = '\0';
+	int latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate);
+
+	LL_INFOS("AppInit") << "FMOD device: "<< r_name << "\n"
+		<< "FMOD Ex parameters: " << r_samplerate << " Hz * " << r_channels << " * " <<r_bits <<" bit\n"
+		<< "\tbuffer " << r_bufferlength << " * " << r_numbuffers << " (" << latency <<"ms)" << LL_ENDL;
+
+	mInited = true;
+
+	return true;
+}
+
+
+std::string LLAudioEngine_FMODEX::getDriverName(bool verbose)
+{
+	llassert_always(mSystem);
+	if (verbose)
+	{
+		U32 version;
+		if(!Check_FMOD_Error(mSystem->getVersion(&version), "FMOD::System::getVersion"))
+		{
+			return llformat("FMOD Ex %1x.%02x.%02x", version >> 16, version >> 8 & 0x000000FF, version & 0x000000FF);
+		}
+	}
+	return "FMODEx";
+}
+
+
+void LLAudioEngine_FMODEX::allocateListener(void)
+{	
+	mListenerp = (LLListener *) new LLListener_FMODEX(mSystem);
+	if (!mListenerp)
+	{
+		llwarns << "Listener creation failed" << llendl;
+	}
+}
+
+
+void LLAudioEngine_FMODEX::shutdown()
+{
+	stopInternetStream();
+
+	llinfos << "About to LLAudioEngine::shutdown()" << llendl;
+	LLAudioEngine::shutdown();
+	
+	llinfos << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << llendl;
+	mSystem->close();
+	mSystem->release();
+	llinfos << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << llendl;
+
+	delete mListenerp;
+	mListenerp = NULL;
+}
+
+
+LLAudioBuffer * LLAudioEngine_FMODEX::createBuffer()
+{
+	return new LLAudioBufferFMODEX(mSystem);
+}
+
+
+LLAudioChannel * LLAudioEngine_FMODEX::createChannel()
+{
+	return new LLAudioChannelFMODEX(mSystem);
+}
+
+bool LLAudioEngine_FMODEX::initWind()
+{
+	mNextWindUpdate = 0.0;
+
+	if (!mWindDSP)
+	{
+		FMOD_DSP_DESCRIPTION dspdesc;
+		memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION));	//Set everything to zero
+		strncpy(dspdesc.name,"Wind Unit", sizeof(dspdesc.name));	//Set name to "Wind Unit"
+		dspdesc.channels=2;
+		dspdesc.read = &windCallback; //Assign callback.
+		if(Check_FMOD_Error(mSystem->createDSP(&dspdesc, &mWindDSP), "FMOD::createDSP"))
+			return false;
+
+		if(mWindGen)
+			delete mWindGen;
+	
+		float frequency = 44100;
+		mWindDSP->getDefaults(&frequency,0,0,0);
+		mWindGen = new LLWindGen<MIXBUFFERFORMAT>((U32)frequency);
+		mWindDSP->setUserData((void*)mWindGen);
+	}
+
+	if (mWindDSP)
+	{
+		mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0);
+		return true;
+	}
+	return false;
+}
+
+
+void LLAudioEngine_FMODEX::cleanupWind()
+{
+	if (mWindDSP)
+	{
+		mWindDSP->remove();
+		mWindDSP->release();
+		mWindDSP = NULL;
+	}
+
+	delete mWindGen;
+	mWindGen = NULL;
+}
+
+
+//-----------------------------------------------------------------------
+void LLAudioEngine_FMODEX::updateWind(LLVector3 wind_vec, F32 camera_height_above_water)
+{
+	LLVector3 wind_pos;
+	F64 pitch;
+	F64 center_freq;
+
+	if (!mEnableWind)
+	{
+		return;
+	}
+	
+	if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
+	{
+		
+		// wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
+		// need to convert this to the conventional orientation DS3D and OpenAL use
+		// where +X = right, +Y = up, +Z = backwards
+
+		wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
+
+		// cerr << "Wind update" << endl;
+
+		pitch = 1.0 + mapWindVecToPitch(wind_vec);
+		center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
+		
+		mWindGen->mTargetFreq = (F32)center_freq;
+		mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
+		mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
+  	}
+}
+
+//-----------------------------------------------------------------------
+void LLAudioEngine_FMODEX::setInternalGain(F32 gain)
+{
+	if (!mInited)
+	{
+		return;
+	}
+
+	gain = llclamp( gain, 0.0f, 1.0f );
+
+	FMOD::ChannelGroup *master_group;
+	mSystem->getMasterChannelGroup(&master_group);
+
+	master_group->setVolume(gain);
+
+	LLStreamingAudioInterface *saimpl = getStreamingAudioImpl();
+	if ( saimpl )
+	{
+		// fmod likes its streaming audio channel gain re-asserted after
+		// master volume change.
+		saimpl->setGain(saimpl->getGain());
+	}
+}
+
+//
+// LLAudioChannelFMODEX implementation
+//
+
+LLAudioChannelFMODEX::LLAudioChannelFMODEX(FMOD::System *system) : LLAudioChannel(), mSystemp(system), mChannelp(NULL), mLastSamplePos(0)
+{
+}
+
+
+LLAudioChannelFMODEX::~LLAudioChannelFMODEX()
+{
+	cleanup();
+}
+
+bool LLAudioChannelFMODEX::updateBuffer()
+{
+	if (LLAudioChannel::updateBuffer())
+	{
+		// Base class update returned true, which means that we need to actually
+		// set up the channel for a different buffer.
+
+		LLAudioBufferFMODEX *bufferp = (LLAudioBufferFMODEX *)mCurrentSourcep->getCurrentBuffer();
+
+		// Grab the FMOD sample associated with the buffer
+		FMOD::Sound *soundp = bufferp->getSound();
+		if (!soundp)
+		{
+			// This is bad, there should ALWAYS be a sound associated with a legit
+			// buffer.
+			llerrs << "No FMOD sound!" << llendl;
+			return false;
+		}
+
+
+		// Actually play the sound.  Start it off paused so we can do all the necessary
+		// setup.
+		if(!mChannelp)
+		{
+			FMOD_RESULT result = getSystem()->playSound(FMOD_CHANNEL_FREE, soundp, true, &mChannelp);
+			Check_FMOD_Error(result, "FMOD::System::playSound");
+		}
+
+		//llinfos << "Setting up channel " << std::hex << mChannelID << std::dec << llendl;
+	}
+
+	// If we have a source for the channel, we need to update its gain.
+	if (mCurrentSourcep)
+	{
+		// SJB: warnings can spam and hurt framerate, disabling
+		//FMOD_RESULT result;
+
+		mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain());
+		//Check_FMOD_Error(result, "FMOD::Channel::setVolume");
+
+		mChannelp->setMode(mCurrentSourcep->isLoop() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
+		/*if(Check_FMOD_Error(result, "FMOD::Channel::setMode"))
+		{
+			S32 index;
+			mChannelp->getIndex(&index);
+ 			llwarns << "Channel " << index << "Source ID: " << mCurrentSourcep->getID()
+ 					<< " at " << mCurrentSourcep->getPositionGlobal() << llendl;		
+		}*/
+	}
+
+	return true;
+}
+
+
+void LLAudioChannelFMODEX::update3DPosition()
+{
+	if (!mChannelp)
+	{
+		// We're not actually a live channel (i.e., we're not playing back anything)
+		return;
+	}
+
+	LLAudioBufferFMODEX  *bufferp = (LLAudioBufferFMODEX  *)mCurrentBufferp;
+	if (!bufferp)
+	{
+		// We don't have a buffer associated with us (should really have been picked up
+		// by the above if.
+		return;
+	}
+
+	if (mCurrentSourcep->isAmbient())
+	{
+		// Ambient sound, don't need to do any positional updates.
+		set3DMode(false);
+	}
+	else
+	{
+		// Localized sound.  Update the position and velocity of the sound.
+		set3DMode(true);
+
+		LLVector3 float_pos;
+		float_pos.setVec(mCurrentSourcep->getPositionGlobal());
+		FMOD_RESULT result = mChannelp->set3DAttributes((FMOD_VECTOR*)float_pos.mV, (FMOD_VECTOR*)mCurrentSourcep->getVelocity().mV);
+		Check_FMOD_Error(result, "FMOD::Channel::set3DAttributes");
+	}
+}
+
+
+void LLAudioChannelFMODEX::updateLoop()
+{
+	if (!mChannelp)
+	{
+		// May want to clear up the loop/sample counters.
+		return;
+	}
+
+	//
+	// Hack:  We keep track of whether we looped or not by seeing when the
+	// sample position looks like it's going backwards.  Not reliable; may
+	// yield false negatives.
+	//
+	U32 cur_pos;
+	mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES);
+
+	if (cur_pos < (U32)mLastSamplePos)
+	{
+		mLoopedThisFrame = true;
+	}
+	mLastSamplePos = cur_pos;
+}
+
+
+void LLAudioChannelFMODEX::cleanup()
+{
+	if (!mChannelp)
+	{
+		//llinfos << "Aborting cleanup with no channel handle." << llendl;
+		return;
+	}
+
+	//llinfos << "Cleaning up channel: " << mChannelID << llendl;
+	Check_FMOD_Error(mChannelp->stop(),"FMOD::Channel::stop");
+
+	mCurrentBufferp = NULL;
+	mChannelp = NULL;
+}
+
+
+void LLAudioChannelFMODEX::play()
+{
+	if (!mChannelp)
+	{
+		llwarns << "Playing without a channel handle, aborting" << llendl;
+		return;
+	}
+
+	Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::pause");
+
+	getSource()->setPlayedOnce(true);
+
+	if(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()])
+		mChannelp->setChannelGroup(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()]);
+}
+
+
+void LLAudioChannelFMODEX::playSynced(LLAudioChannel *channelp)
+{
+	LLAudioChannelFMODEX *fmod_channelp = (LLAudioChannelFMODEX*)channelp;
+	if (!(fmod_channelp->mChannelp && mChannelp))
+	{
+		// Don't have channels allocated to both the master and the slave
+		return;
+	}
+
+	U32 cur_pos;
+	if(Check_FMOD_Error(mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES), "Unable to retrieve current position"))
+		return;
+
+	cur_pos %= mCurrentBufferp->getLength();
+	
+	// Try to match the position of our sync master
+	Check_FMOD_Error(mChannelp->setPosition(cur_pos,FMOD_TIMEUNIT_PCMBYTES),"Unable to set current position");
+
+	// Start us playing
+	play();
+}
+
+
+bool LLAudioChannelFMODEX::isPlaying()
+{
+	if (!mChannelp)
+	{
+		return false;
+	}
+
+	bool paused, playing;
+	mChannelp->getPaused(&paused);
+	mChannelp->isPlaying(&playing);
+	return !paused && playing;
+}
+
+
+//
+// LLAudioChannelFMODEX implementation
+//
+
+
+LLAudioBufferFMODEX::LLAudioBufferFMODEX(FMOD::System *system) : mSystemp(system), mSoundp(NULL)
+{
+}
+
+
+LLAudioBufferFMODEX::~LLAudioBufferFMODEX()
+{
+	if(mSoundp)
+	{
+		mSoundp->release();
+		mSoundp = NULL;
+	}
+}
+
+
+bool LLAudioBufferFMODEX::loadWAV(const std::string& filename)
+{
+	// Try to open a wav file from disk.  This will eventually go away, as we don't
+	// really want to block doing this.
+	if (filename.empty())
+	{
+		// invalid filename, abort.
+		return false;
+	}
+
+	if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB))
+	{
+		// File not found, abort.
+		return false;
+	}
+	
+	if (mSoundp)
+	{
+		// If there's already something loaded in this buffer, clean it up.
+		mSoundp->release();
+		mSoundp = NULL;
+	}
+
+	FMOD_MODE base_mode = FMOD_LOOP_NORMAL | FMOD_SOFTWARE;
+	FMOD_CREATESOUNDEXINFO exinfo;
+	memset(&exinfo,0,sizeof(exinfo));
+	exinfo.cbsize = sizeof(exinfo);
+	exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_WAV;	//Hint to speed up loading.
+	// Load up the wav file into an fmod sample
+#if LL_WINDOWS
+	FMOD_RESULT result = getSystem()->createSound((const char*)utf8str_to_utf16str(filename).c_str(), base_mode | FMOD_UNICODE, &exinfo, &mSoundp);
+#else
+	FMOD_RESULT result = getSystem()->createSound(filename.c_str(), base_mode, &exinfo, &mSoundp);
+#endif
+
+	if (result != FMOD_OK)
+	{
+		// We failed to load the file for some reason.
+		llwarns << "Could not load data '" << filename << "': " << FMOD_ErrorString(result) << llendl;
+
+		//
+		// If we EVER want to load wav files provided by end users, we need
+		// to rethink this!
+		//
+		// file is probably corrupt - remove it.
+		LLFile::remove(filename);
+		return false;
+	}
+
+	// Everything went well, return true
+	return true;
+}
+
+
+U32 LLAudioBufferFMODEX::getLength()
+{
+	if (!mSoundp)
+	{
+		return 0;
+	}
+
+	U32 length;
+	mSoundp->getLength(&length, FMOD_TIMEUNIT_PCMBYTES);
+	return length;
+}
+
+
+void LLAudioChannelFMODEX::set3DMode(bool use3d)
+{
+	FMOD_MODE current_mode;
+	if(mChannelp->getMode(&current_mode) != FMOD_OK)
+		return;
+	FMOD_MODE new_mode = current_mode;	
+	new_mode &= ~(use3d ? FMOD_2D : FMOD_3D);
+	new_mode |= use3d ? FMOD_3D : FMOD_2D;
+
+	if(current_mode != new_mode)
+	{
+		mChannelp->setMode(new_mode);
+	}
+}
+
+
+FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *originalbuffer, float *newbuffer, unsigned int length, int inchannels, int outchannels)
+{
+	// originalbuffer = fmod's original mixbuffer.
+	// newbuffer = the buffer passed from the previous DSP unit.
+	// length = length in samples at this mix time.
+	// userdata = user parameter passed through in FSOUND_DSP_Create.
+	
+	LLWindGen<LLAudioEngine_FMODEX::MIXBUFFERFORMAT> *windgen;
+	FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance;
+
+	thisdsp->getUserData((void **)&windgen);
+	S32 channels, configwidth, configheight;
+	thisdsp->getInfo(0, 0, &channels, &configwidth, &configheight);
+	
+	windgen->windGenerate((LLAudioEngine_FMODEX::MIXBUFFERFORMAT *)newbuffer, length);
+
+	return FMOD_OK;
+}
diff --git a/indra/llaudio/llaudioengine_fmod.h b/indra/llaudio/llaudioengine_fmodex.h
similarity index 62%
rename from indra/llaudio/llaudioengine_fmod.h
rename to indra/llaudio/llaudioengine_fmodex.h
index 4582a5d57e1cf83696e98481f3a78db0e1adb8ea..415a9ed0efb7d244bb2d6bcca6a179f9939156a8 100644
--- a/indra/llaudio/llaudioengine_fmod.h
+++ b/indra/llaudio/llaudioengine_fmodex.h
@@ -1,7 +1,7 @@
 /** 
- * @file audioengine_fmod.h
- * @brief Definition of LLAudioEngine class abstracting the audio
- * support as a FMOD 3D implementation
+ * @file audioengine_fmodex.h
+ * @brief Definition of LLAudioEngine class abstracting the audio 
+ * support as a FMODEX implementation
  *
  * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -25,26 +25,33 @@
  * $/LicenseInfo$
  */
 
-#ifndef LL_AUDIOENGINE_FMOD_H
-#define LL_AUDIOENGINE_FMOD_H
+#ifndef LL_AUDIOENGINE_FMODEX_H
+#define LL_AUDIOENGINE_FMODEX_H
 
 #include "llaudioengine.h"
-#include "lllistener_fmod.h"
 #include "llwindgen.h"
 
-#include "fmod.h"
-
-class LLAudioStreamManagerFMOD;
-
-class LLAudioEngine_FMOD : public LLAudioEngine 
+//Stubs
+class LLAudioStreamManagerFMODEX;
+namespace FMOD
+{
+	class System;
+	class Channel;
+	class ChannelGroup;
+	class Sound;
+	class DSP;
+}
+
+//Interfaces
+class LLAudioEngine_FMODEX : public LLAudioEngine 
 {
 public:
-	LLAudioEngine_FMOD();
-	virtual ~LLAudioEngine_FMOD();
+	LLAudioEngine_FMODEX(bool enable_profiler);
+	virtual ~LLAudioEngine_FMODEX();
 
 	// initialization/startup/shutdown
 	virtual bool init(const S32 num_channels, void *user_data);
-       	virtual std::string getDriverName(bool verbose);
+	virtual std::string getDriverName(bool verbose);
 	virtual void allocateListener();
 
 	virtual void shutdown();
@@ -54,38 +61,33 @@ class LLAudioEngine_FMOD : public LLAudioEngine
 
 	/*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water);
 
-#if LL_DARWIN
-	typedef S32 MIXBUFFERFORMAT;
-#else
-	typedef S16 MIXBUFFERFORMAT;
-#endif
+	typedef F32 MIXBUFFERFORMAT;
 
+	FMOD::System *getSystem()				const {return mSystem;}
 protected:
 	/*virtual*/ LLAudioBuffer *createBuffer(); // Get a free buffer, or flush an existing one if you have to.
 	/*virtual*/ LLAudioChannel *createChannel(); // Create a new audio channel.
 
 	/*virtual*/ void setInternalGain(F32 gain);
-protected:
-	static signed char F_CALLBACKAPI callbackMetaData(char* name, char* value, void* userdata);
-
-	//F32 mMinDistance[MAX_BUFFERS];
-	//F32 mMaxDistance[MAX_BUFFERS];
 
 	bool mInited;
 
-	// On Windows, userdata is the HWND of the application window.
-	void* mUserData;
-
 	LLWindGen<MIXBUFFERFORMAT> *mWindGen;
-	FSOUND_DSPUNIT *mWindDSP;
+
+	FMOD::DSP *mWindDSP;
+	FMOD::System *mSystem;
+	bool mEnableProfiler;
+
+public:
+	static FMOD::ChannelGroup *mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT];
 };
 
 
-class LLAudioChannelFMOD : public LLAudioChannel
+class LLAudioChannelFMODEX : public LLAudioChannel
 {
 public:
-	LLAudioChannelFMOD();
-	virtual ~LLAudioChannelFMOD();
+	LLAudioChannelFMODEX(FMOD::System *audioengine);
+	virtual ~LLAudioChannelFMODEX();
 
 protected:
 	/*virtual*/ void play();
@@ -97,28 +99,30 @@ class LLAudioChannelFMOD : public LLAudioChannel
 	/*virtual*/ void update3DPosition();
 	/*virtual*/ void updateLoop();
 
+	void set3DMode(bool use3d);
 protected:
-	int mChannelID;
+	FMOD::System *getSystem()	const {return mSystemp;}
+	FMOD::System *mSystemp;
+	FMOD::Channel *mChannelp;
 	S32 mLastSamplePos;
 };
 
 
-class LLAudioBufferFMOD : public LLAudioBuffer
+class LLAudioBufferFMODEX : public LLAudioBuffer
 {
 public:
-	LLAudioBufferFMOD();
-	virtual ~LLAudioBufferFMOD();
+	LLAudioBufferFMODEX(FMOD::System *audioengine);
+	virtual ~LLAudioBufferFMODEX();
 
 	/*virtual*/ bool loadWAV(const std::string& filename);
 	/*virtual*/ U32 getLength();
-	friend class LLAudioChannelFMOD;
-
-	void set3DMode(bool use3d);
-protected:
-	FSOUND_SAMPLE *getSample()	{ return mSamplep; }
+	friend class LLAudioChannelFMODEX;
 protected:
-	FSOUND_SAMPLE *mSamplep;
+	FMOD::System *getSystem()	const {return mSystemp;}
+	FMOD::System *mSystemp;
+	FMOD::Sound *getSound()		const{ return mSoundp; }
+	FMOD::Sound *mSoundp;
 };
 
 
-#endif // LL_AUDIOENGINE_FMOD_H
+#endif // LL_AUDIOENGINE_FMODEX_H
diff --git a/indra/llaudio/lllistener_fmod.cpp b/indra/llaudio/lllistener_fmodex.cpp
similarity index 53%
rename from indra/llaudio/lllistener_fmod.cpp
rename to indra/llaudio/lllistener_fmodex.cpp
index 0138f4345e3f683e522e505aedd6a5fc71d2495b..2509a7aebc9c67bb4e016549377017c1a10dd424 100644
--- a/indra/llaudio/lllistener_fmod.cpp
+++ b/indra/llaudio/lllistener_fmodex.cpp
@@ -1,7 +1,7 @@
 /** 
- * @file listener_fmod.cpp
- * @brief implementation of LISTENER class abstracting the audio
- * support as a FMOD 3D implementation (windows only)
+ * @file listener_fmodex.cpp
+ * @brief Implementation of LISTENER class abstracting the audio
+ * support as a FMODEX implementation
  *
  * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -27,24 +27,25 @@
 
 #include "linden_common.h"
 #include "llaudioengine.h"
-#include "lllistener_fmod.h"
-#include "fmod.h"
+#include "lllistener_fmodex.h"
+#include "fmod.hpp"
 
 //-----------------------------------------------------------------------
 // constructor
 //-----------------------------------------------------------------------
-LLListener_FMOD::LLListener_FMOD()
+LLListener_FMODEX::LLListener_FMODEX(FMOD::System *system)
 {
+	mSystem = system;
 	init();
 }
 
 //-----------------------------------------------------------------------
-LLListener_FMOD::~LLListener_FMOD()
+LLListener_FMODEX::~LLListener_FMODEX()
 {
 }
 
 //-----------------------------------------------------------------------
-void LLListener_FMOD::init(void)
+void LLListener_FMODEX::init(void)
 {
 	// do inherited
 	LLListener::init();
@@ -53,31 +54,31 @@ void LLListener_FMOD::init(void)
 }
 
 //-----------------------------------------------------------------------
-void LLListener_FMOD::translate(LLVector3 offset)
+void LLListener_FMODEX::translate(LLVector3 offset)
 {
 	LLListener::translate(offset);
 
-	FSOUND_3D_Listener_SetAttributes(mPosition.mV, NULL, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]);
+	mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
 }
 
 //-----------------------------------------------------------------------
-void LLListener_FMOD::setPosition(LLVector3 pos)
+void LLListener_FMODEX::setPosition(LLVector3 pos)
 {
 	LLListener::setPosition(pos);
 
-	FSOUND_3D_Listener_SetAttributes(pos.mV, NULL, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]);
+	mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
 }
 
 //-----------------------------------------------------------------------
-void LLListener_FMOD::setVelocity(LLVector3 vel)
+void LLListener_FMODEX::setVelocity(LLVector3 vel)
 {
 	LLListener::setVelocity(vel);
 
-	FSOUND_3D_Listener_SetAttributes(NULL, vel.mV, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]);
+	mSystem->set3DListenerAttributes(0, NULL, (FMOD_VECTOR*)mVelocity.mV, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
 }
 
 //-----------------------------------------------------------------------
-void LLListener_FMOD::orient(LLVector3 up, LLVector3 at)
+void LLListener_FMODEX::orient(LLVector3 up, LLVector3 at)
 {
 	LLListener::orient(up, at);
 
@@ -87,37 +88,46 @@ void LLListener_FMOD::orient(LLVector3 up, LLVector3 at)
 	// since DX is left-handed and we (LL, OpenGL, OpenAL) are right-handed
 	at = -at;
 
-	FSOUND_3D_Listener_SetAttributes(NULL, NULL, at.mV[0],at.mV[1],at.mV[2], up.mV[0],up.mV[1],up.mV[2]);
+	mSystem->set3DListenerAttributes(0, NULL, NULL, (FMOD_VECTOR*)at.mV, (FMOD_VECTOR*)up.mV);
 }
 
 //-----------------------------------------------------------------------
-void LLListener_FMOD::commitDeferredChanges()
+void LLListener_FMODEX::commitDeferredChanges()
 {
-	FSOUND_Update();
+	mSystem->update();
 }
 
 
-void LLListener_FMOD::setRolloffFactor(F32 factor)
+void LLListener_FMODEX::setRolloffFactor(F32 factor)
 {
+	//An internal FMODEx optimization skips 3D updates if there have not been changes to the 3D sound environment.
+	//Sadly, a change in rolloff is not accounted for, thus we must touch the listener properties as well.
+	//In short: Changing the position ticks a dirtyflag inside fmodex, which makes it not skip 3D processing next update call.
+	if(mRolloffFactor != factor)
+	{
+		LLVector3 pos = mVelocity - LLVector3(0.f,0.f,.1f);
+		mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)pos.mV, NULL, NULL, NULL);
+		mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mVelocity.mV, NULL, NULL, NULL);
+	}
 	mRolloffFactor = factor;
-	FSOUND_3D_SetRolloffFactor(factor);
+	mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor);
 }
 
 
-F32 LLListener_FMOD::getRolloffFactor()
+F32 LLListener_FMODEX::getRolloffFactor()
 {
 	return mRolloffFactor;
 }
 
 
-void LLListener_FMOD::setDopplerFactor(F32 factor)
+void LLListener_FMODEX::setDopplerFactor(F32 factor)
 {
 	mDopplerFactor = factor;
-	FSOUND_3D_SetDopplerFactor(factor);
+	mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor);
 }
 
 
-F32 LLListener_FMOD::getDopplerFactor()
+F32 LLListener_FMODEX::getDopplerFactor()
 {
 	return mDopplerFactor;
 }
diff --git a/indra/llaudio/lllistener_fmod.h b/indra/llaudio/lllistener_fmodex.h
similarity index 84%
rename from indra/llaudio/lllistener_fmod.h
rename to indra/llaudio/lllistener_fmodex.h
index 818da05d51678041cf92c514bf7f885fb0ffe442..073b65d53adc5c68f5f486f3e2d3bc68cbdea5b0 100644
--- a/indra/llaudio/lllistener_fmod.h
+++ b/indra/llaudio/lllistener_fmodex.h
@@ -1,5 +1,5 @@
 /** 
- * @file listener_fmod.h
+ * @file listener_fmodex.h
  * @brief Description of LISTENER class abstracting the audio support
  * as an FMOD 3D implementation (windows and Linux)
  *
@@ -25,16 +25,23 @@
  * $/LicenseInfo$
  */
 
-#ifndef LL_LISTENER_FMOD_H
-#define LL_LISTENER_FMOD_H
+#ifndef LL_LISTENER_FMODEX_H
+#define LL_LISTENER_FMODEX_H
 
 #include "lllistener.h"
 
-class LLListener_FMOD : public LLListener
+//Stubs
+namespace FMOD
+{
+	class System;
+}
+
+//Interfaces
+class LLListener_FMODEX : public LLListener
 {
  public:  
-	LLListener_FMOD();
-	virtual ~LLListener_FMOD();
+	LLListener_FMODEX(FMOD::System *system);
+	virtual ~LLListener_FMODEX();
 	virtual void init();  
 
 	virtual void translate(LLVector3 offset);
@@ -47,8 +54,8 @@ class LLListener_FMOD : public LLListener
 	virtual F32 getDopplerFactor();
 	virtual void setRolloffFactor(F32 factor);
 	virtual F32 getRolloffFactor();
-
  protected:
+	 FMOD::System *mSystem;
 	 F32 mDopplerFactor;
 	 F32 mRolloffFactor;
 };
diff --git a/indra/llaudio/llstreamingaudio.h b/indra/llaudio/llstreamingaudio.h
index 20104af744ad58bcafaa37b461102ae2100bfb6a..93479f9d598e2c6e7576e0ffbff3b3873095bd96 100644
--- a/indra/llaudio/llstreamingaudio.h
+++ b/indra/llaudio/llstreamingaudio.h
@@ -45,6 +45,8 @@ class LLStreamingAudioInterface
 	virtual void setGain(F32 vol) = 0;
 	virtual F32 getGain() = 0;
 	virtual std::string getURL() = 0;
+	virtual bool supportsAdjustableBufferSizes(){return false;}
+	virtual void setBufferSizes(U32 streambuffertime, U32 decodebuffertime){};
 };
 
 #endif // LL_STREAMINGAUDIO_H
diff --git a/indra/llaudio/llstreamingaudio_fmod.cpp b/indra/llaudio/llstreamingaudio_fmodex.cpp
similarity index 50%
rename from indra/llaudio/llstreamingaudio_fmod.cpp
rename to indra/llaudio/llstreamingaudio_fmodex.cpp
index bcdea771a76e58213798992ca255cadac726065b..4a74267650bcc30b95476cb2901b2b233d214f3c 100644
--- a/indra/llaudio/llstreamingaudio_fmod.cpp
+++ b/indra/llaudio/llstreamingaudio_fmodex.cpp
@@ -1,8 +1,8 @@
 /** 
- * @file streamingaudio_fmod.cpp
- * @brief LLStreamingAudio_FMOD implementation
+ * @file streamingaudio_fmodex.cpp
+ * @brief LLStreamingAudio_FMODEX implementation
  *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2010, Linden Research, Inc.
  * 
@@ -28,25 +28,27 @@
 
 #include "llmath.h"
 
-#include "fmod.h"
+#include "fmod.hpp"
 #include "fmod_errors.h"
 
-#include "llstreamingaudio_fmod.h"
+#include "llstreamingaudio_fmodex.h"
 
 
-class LLAudioStreamManagerFMOD
+class LLAudioStreamManagerFMODEX
 {
 public:
-	LLAudioStreamManagerFMOD(const std::string& url);
-	int	startStream();
+	LLAudioStreamManagerFMODEX(FMOD::System *system, const std::string& url);
+	FMOD::Channel* startStream();
 	bool stopStream(); // Returns true if the stream was successfully stopped.
 	bool ready();
 
 	const std::string& getURL() 	{ return mInternetStreamURL; }
 
-	int getOpenState();
+	FMOD_OPENSTATE getOpenState(unsigned int* percentbuffered=NULL, bool* starving=NULL, bool* diskbusy=NULL);
 protected:
-	FSOUND_STREAM* mInternetStream;
+	FMOD::System* mSystem;
+	FMOD::Channel* mStreamChannel;
+	FMOD::Sound* mInternetStream;
 	bool mReady;
 
 	std::string mInternetStreamURL;
@@ -57,14 +59,17 @@ class LLAudioStreamManagerFMOD
 //---------------------------------------------------------------------------
 // Internet Streaming
 //---------------------------------------------------------------------------
-LLStreamingAudio_FMOD::LLStreamingAudio_FMOD() :
+LLStreamingAudio_FMODEX::LLStreamingAudio_FMODEX(FMOD::System *system) :
+	mSystem(system),
 	mCurrentInternetStreamp(NULL),
-	mFMODInternetStreamChannel(-1),
+	mFMODInternetStreamChannelp(NULL),
 	mGain(1.0f)
 {
 	// Number of milliseconds of audio to buffer for the audio card.
 	// Must be larger than the usual Second Life frame stutter time.
-	FSOUND_Stream_SetBufferSize(200);
+	const U32 buffer_seconds = 10;		//sec
+	const U32 estimated_bitrate = 128;	//kbit/sec
+	mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
 
 	// Here's where we set the size of the network buffer and some buffering 
 	// parameters.  In this case we want a network buffer of 16k, we want it 
@@ -76,13 +81,13 @@ LLStreamingAudio_FMOD::LLStreamingAudio_FMOD() :
 }
 
 
-LLStreamingAudio_FMOD::~LLStreamingAudio_FMOD()
+LLStreamingAudio_FMODEX::~LLStreamingAudio_FMODEX()
 {
 	// nothing interesting/safe to do.
 }
 
 
-void LLStreamingAudio_FMOD::start(const std::string& url)
+void LLStreamingAudio_FMODEX::start(const std::string& url)
 {
 	//if (!mInited)
 	//{
@@ -96,7 +101,7 @@ void LLStreamingAudio_FMOD::start(const std::string& url)
 	if (!url.empty())
 	{
 		llinfos << "Starting internet stream: " << url << llendl;
-		mCurrentInternetStreamp = new LLAudioStreamManagerFMOD(url);
+		mCurrentInternetStreamp = new LLAudioStreamManagerFMODEX(mSystem,url);
 		mURL = url;
 	}
 	else
@@ -107,13 +112,13 @@ void LLStreamingAudio_FMOD::start(const std::string& url)
 }
 
 
-void LLStreamingAudio_FMOD::update()
+void LLStreamingAudio_FMODEX::update()
 {
 	// Kill dead internet streams, if possible
-	std::list<LLAudioStreamManagerFMOD *>::iterator iter;
+	std::list<LLAudioStreamManagerFMODEX *>::iterator iter;
 	for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();)
 	{
-		LLAudioStreamManagerFMOD *streamp = *iter;
+		LLAudioStreamManagerFMODEX *streamp = *iter;
 		if (streamp->stopStream())
 		{
 			llinfos << "Closed dead stream" << llendl;
@@ -132,62 +137,66 @@ void LLStreamingAudio_FMOD::update()
 		return;
 	}
 
-	int open_state = mCurrentInternetStreamp->getOpenState();
+	unsigned int progress;
+	bool starving;
+	bool diskbusy;
+	FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy);
 
-	if (!open_state)
+	if (open_state == FMOD_OPENSTATE_READY)
 	{
 		// Stream is live
 
 		// start the stream if it's ready
-		if (mFMODInternetStreamChannel < 0)
+		if (!mFMODInternetStreamChannelp &&
+			(mFMODInternetStreamChannelp = mCurrentInternetStreamp->startStream()))
 		{
-			mFMODInternetStreamChannel = mCurrentInternetStreamp->startStream();
-
-			if (mFMODInternetStreamChannel != -1)
-			{
-				// Reset volume to previously set volume
-				setGain(getGain());
-				FSOUND_SetPaused(mFMODInternetStreamChannel, false);
-			}
+			// Reset volume to previously set volume
+			setGain(getGain());
+			mFMODInternetStreamChannelp->setPaused(false);
+			mLastStarved.stop();
 		}
 	}
-		
-	switch(open_state)
+	else if(open_state == FMOD_OPENSTATE_ERROR)
 	{
-	default:
-	case 0:
-		// success
-		break;
-	case -1:
-		// stream handle is invalid
-		llwarns << "InternetStream - invalid handle" << llendl;
 		stop();
 		return;
-	case -2:
-		// opening
-		break;
-	case -3:
-		// failed to open, file not found, perhaps
-		llwarns << "InternetStream - failed to open" << llendl;
-		stop();
-		return;
-	case -4:
-		// connecting
-		break;
-	case -5:
-		// buffering
-		break;
 	}
 
+	if(mFMODInternetStreamChannelp)
+	{
+		FMOD::Sound *sound = NULL;
+
+		if(mFMODInternetStreamChannelp->getCurrentSound(&sound) == FMOD_OK && sound)
+		{
+			if(starving)
+			{
+				if(!mLastStarved.getStarted())
+				{
+					llinfos << "Stream starvation detected! Muting stream audio until it clears." << llendl;
+					llinfos << "  (diskbusy="<<diskbusy<<")" << llendl;
+					llinfos << "  (progress="<<progress<<")" << llendl;
+					mFMODInternetStreamChannelp->setMute(true);
+				}
+				mLastStarved.start();
+			}
+			else if(mLastStarved.getStarted() && mLastStarved.getElapsedTimeF32() > 1.f)
+			{
+				mLastStarved.stop();
+				mFMODInternetStreamChannelp->setMute(false);
+			}
+		}
+	}
 }
 
-void LLStreamingAudio_FMOD::stop()
+void LLStreamingAudio_FMODEX::stop()
 {
-	if (mFMODInternetStreamChannel != -1)
+	mLastStarved.stop();
+
+	if (mFMODInternetStreamChannelp)
 	{
-		FSOUND_SetPaused(mFMODInternetStreamChannel, true);
-		FSOUND_SetPriority(mFMODInternetStreamChannel, 0);
-		mFMODInternetStreamChannel = -1;
+		mFMODInternetStreamChannelp->setPaused(true);
+		mFMODInternetStreamChannelp->setPriority(0);
+		mFMODInternetStreamChannelp = NULL;
 	}
 
 	if (mCurrentInternetStreamp)
@@ -207,7 +216,7 @@ void LLStreamingAudio_FMOD::stop()
 	}
 }
 
-void LLStreamingAudio_FMOD::pause(int pauseopt)
+void LLStreamingAudio_FMODEX::pause(int pauseopt)
 {
 	if (pauseopt < 0)
 	{
@@ -230,7 +239,7 @@ void LLStreamingAudio_FMOD::pause(int pauseopt)
 
 // A stream is "playing" if it has been requested to start.  That
 // doesn't necessarily mean audio is coming out of the speakers.
-int LLStreamingAudio_FMOD::isPlaying()
+int LLStreamingAudio_FMODEX::isPlaying()
 {
 	if (mCurrentInternetStreamp)
 	{
@@ -247,44 +256,47 @@ int LLStreamingAudio_FMOD::isPlaying()
 }
 
 
-F32 LLStreamingAudio_FMOD::getGain()
+F32 LLStreamingAudio_FMODEX::getGain()
 {
 	return mGain;
 }
 
 
-std::string LLStreamingAudio_FMOD::getURL()
+std::string LLStreamingAudio_FMODEX::getURL()
 {
 	return mURL;
 }
 
 
-void LLStreamingAudio_FMOD::setGain(F32 vol)
+void LLStreamingAudio_FMODEX::setGain(F32 vol)
 {
 	mGain = vol;
 
-	if (mFMODInternetStreamChannel != -1)
+	if (mFMODInternetStreamChannelp)
 	{
-		vol = llclamp(vol * vol, 0.f, 1.f);
-		int vol_int = llround(vol * 255.f);
-		FSOUND_SetVolumeAbsolute(mFMODInternetStreamChannel, vol_int);
+		vol = llclamp(vol * vol, 0.f, 1.f);	//should vol be squared here?
+
+		mFMODInternetStreamChannelp->setVolume(vol);
 	}
 }
 
-
 ///////////////////////////////////////////////////////
 // manager of possibly-multiple internet audio streams
 
-LLAudioStreamManagerFMOD::LLAudioStreamManagerFMOD(const std::string& url) :
+LLAudioStreamManagerFMODEX::LLAudioStreamManagerFMODEX(FMOD::System *system, const std::string& url) :
+	mSystem(system),
+	mStreamChannel(NULL),
 	mInternetStream(NULL),
 	mReady(false)
 {
 	mInternetStreamURL = url;
-	mInternetStream = FSOUND_Stream_Open(url.c_str(), FSOUND_NORMAL | FSOUND_NONBLOCKING, 0, 0);
-	if (!mInternetStream)
+
+	FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_MPEGSEARCH | FMOD_IGNORETAGS, 0, &mInternetStream);
+
+	if (result!= FMOD_OK)
 	{
 		llwarns << "Couldn't open fmod stream, error "
-			<< FMOD_ErrorString(FSOUND_GetError())
+			<< FMOD_ErrorString(result)
 			<< llendl;
 		mReady = false;
 		return;
@@ -293,48 +305,42 @@ LLAudioStreamManagerFMOD::LLAudioStreamManagerFMOD(const std::string& url) :
 	mReady = true;
 }
 
-int LLAudioStreamManagerFMOD::startStream()
+FMOD::Channel *LLAudioStreamManagerFMODEX::startStream()
 {
 	// We need a live and opened stream before we try and play it.
-	if (!mInternetStream || getOpenState())
+	if (!mInternetStream || getOpenState() != FMOD_OPENSTATE_READY)
 	{
 		llwarns << "No internet stream to start playing!" << llendl;
-		return -1;
+		return NULL;
 	}
 
-	// Make sure the stream is set to 2D mode.
-	FSOUND_Stream_SetMode(mInternetStream, FSOUND_2D);
+	if(mStreamChannel)
+		return mStreamChannel;	//Already have a channel for this stream.
 
-	return FSOUND_Stream_PlayEx(FSOUND_FREE, mInternetStream, NULL, true);
+	mSystem->playSound(FMOD_CHANNEL_FREE, mInternetStream, true, &mStreamChannel);
+	return mStreamChannel;
 }
 
-bool LLAudioStreamManagerFMOD::stopStream()
+bool LLAudioStreamManagerFMODEX::stopStream()
 {
 	if (mInternetStream)
 	{
-		int read_percent = 0;
-		int status = 0;
-		int bitrate = 0;
-		unsigned int flags = 0x0;
-		FSOUND_Stream_Net_GetStatus(mInternetStream, &status, &read_percent, &bitrate, &flags);
+
 
 		bool close = true;
-		switch (status)
+		switch (getOpenState())
 		{
-		case FSOUND_STREAM_NET_CONNECTING:
+		case FMOD_OPENSTATE_CONNECTING:
 			close = false;
 			break;
-		case FSOUND_STREAM_NET_NOTCONNECTED:
-		case FSOUND_STREAM_NET_BUFFERING:
-		case FSOUND_STREAM_NET_READY:
-		case FSOUND_STREAM_NET_ERROR:
 		default:
 			close = true;
 		}
 
 		if (close)
 		{
-			FSOUND_Stream_Close(mInternetStream);
+			mInternetStream->release();
+			mStreamChannel = NULL;
 			mInternetStream = NULL;
 			return true;
 		}
@@ -349,8 +355,19 @@ bool LLAudioStreamManagerFMOD::stopStream()
 	}
 }
 
-int LLAudioStreamManagerFMOD::getOpenState()
+FMOD_OPENSTATE LLAudioStreamManagerFMODEX::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy)
+{
+	FMOD_OPENSTATE state;
+	mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
+	return state;
+}
+
+void LLStreamingAudio_FMODEX::setBufferSizes(U32 streambuffertime, U32 decodebuffertime)
 {
-	int open_state = FSOUND_Stream_GetOpenState(mInternetStream);
-	return open_state;
+	mSystem->setStreamBufferSize(streambuffertime/1000*128*128, FMOD_TIMEUNIT_RAWBYTES);
+	FMOD_ADVANCEDSETTINGS settings;
+	memset(&settings,0,sizeof(settings));
+	settings.cbsize=sizeof(settings);
+	settings.defaultDecodeBufferSize = decodebuffertime;//ms
+	mSystem->setAdvancedSettings(&settings);
 }
diff --git a/indra/llaudio/llstreamingaudio_fmod.h b/indra/llaudio/llstreamingaudio_fmodex.h
similarity index 59%
rename from indra/llaudio/llstreamingaudio_fmod.h
rename to indra/llaudio/llstreamingaudio_fmodex.h
index 9970f0d03bc39af1ac4976ee60915f97cf687c5c..42b6b3aaa8ffa4e43265ea9b9de7f1c16471d7b0 100644
--- a/indra/llaudio/llstreamingaudio_fmod.h
+++ b/indra/llaudio/llstreamingaudio_fmodex.h
@@ -1,9 +1,8 @@
 /** 
- * @file streamingaudio_fmod.h
- * @author Tofu Linden
- * @brief Definition of LLStreamingAudio_FMOD implementation
+ * @file streamingaudio_fmodex.h
+ * @brief Definition of LLStreamingAudio_FMODEX implementation
  *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2010, Linden Research, Inc.
  * 
@@ -25,20 +24,28 @@
  * $/LicenseInfo$
  */
 
-#ifndef LL_STREAMINGAUDIO_FMOD_H
-#define LL_STREAMINGAUDIO_FMOD_H
+#ifndef LL_STREAMINGAUDIO_FMODEX_H
+#define LL_STREAMINGAUDIO_FMODEX_H
 
 #include "stdtypes.h" // from llcommon
 
 #include "llstreamingaudio.h"
+#include "lltimer.h"
 
-class LLAudioStreamManagerFMOD;
+//Stubs
+class LLAudioStreamManagerFMODEX;
+namespace FMOD
+{
+	class System;
+	class Channel;
+}
 
-class LLStreamingAudio_FMOD : public LLStreamingAudioInterface
+//Interfaces
+class LLStreamingAudio_FMODEX : public LLStreamingAudioInterface
 {
  public:
-	LLStreamingAudio_FMOD();
-	/*virtual*/ ~LLStreamingAudio_FMOD();
+	LLStreamingAudio_FMODEX(FMOD::System *system);
+	/*virtual*/ ~LLStreamingAudio_FMODEX();
 
 	/*virtual*/ void start(const std::string& url);
 	/*virtual*/ void stop();
@@ -49,14 +56,20 @@ class LLStreamingAudio_FMOD : public LLStreamingAudioInterface
 	/*virtual*/ F32 getGain();
 	/*virtual*/ std::string getURL();
 
+	/*virtual*/ bool supportsAdjustableBufferSizes(){return true;}
+	/*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime);
 private:
-	LLAudioStreamManagerFMOD *mCurrentInternetStreamp;
-	int mFMODInternetStreamChannel;
-	std::list<LLAudioStreamManagerFMOD *> mDeadStreams;
+	FMOD::System *mSystem;
+
+	LLAudioStreamManagerFMODEX *mCurrentInternetStreamp;
+	FMOD::Channel *mFMODInternetStreamChannelp;
+	std::list<LLAudioStreamManagerFMODEX *> mDeadStreams;
 
 	std::string mURL;
 	F32 mGain;
+
+	LLTimer mLastStarved;
 };
 
 
-#endif // LL_STREAMINGAUDIO_FMOD_H
+#endif // LL_STREAMINGAUDIO_FMODEX_H
diff --git a/indra/llaudio/llvorbisencode.cpp b/indra/llaudio/llvorbisencode.cpp
index 0e0c80a45675b6aad361fb49fd563645cf3409d8..dfd5da12b3fa4f700c8f1acd4c95e1d8f2b673a2 100644
--- a/indra/llaudio/llvorbisencode.cpp
+++ b/indra/llaudio/llvorbisencode.cpp
@@ -35,7 +35,7 @@
 #include "llapr.h"
 
 //#if LL_DARWIN
-// MBW -- XXX -- Getting rid of SecondLifeVorbis for now -- no fmod means no name collisions.
+// MBW -- XXX -- Getting rid of SecondLifeVorbis for now
 #if 0
 #include "VorbisFramework.h"
 
diff --git a/indra/llaudio/llwindgen.h b/indra/llaudio/llwindgen.h
index b9cecb60a1edc1835feae36a5092c0dd191339e3..719b0ecbf24a42a1ebd9e7c2889d598fc7743a63 100644
--- a/indra/llaudio/llwindgen.h
+++ b/indra/llaudio/llwindgen.h
@@ -27,6 +27,7 @@
 #define WINDGEN_H
 
 #include "llcommon.h"
+#include "llrand.h"
 
 template <class MIXBUFFERFORMAT_T>
 class LLWindGen
@@ -54,7 +55,9 @@ class LLWindGen
 	}
 
 	const U32 getInputSamplingRate() { return mInputSamplingRate; }
-	
+	const F32 getNextSample();
+	const F32 getClampedSample(bool clamp, F32 sample);
+
 	// newbuffer = the buffer passed from the previous DSP unit.
 	// numsamples = length in samples-per-channel at this mix time.
 	// NOTE: generates L/R interleaved stereo
@@ -89,7 +92,7 @@ class LLWindGen
 			
 			// Start with white noise
 			// This expression is fragile, rearrange it and it will break!
-			next_sample = (F32)rand() * (1.0f / (F32)(RAND_MAX / (U16_MAX / 8))) + (F32)(S16_MIN / 8);
+			next_sample = getNextSample();
 			
 			// Apply a pinking filter
 			// Magic numbers taken from PKE method at http://www.firstpr.com.au/dsp/pink-noise/
@@ -126,23 +129,13 @@ class LLWindGen
 			for (U8 i=mSubSamples; i && numsamples; --i, --numsamples) 
 			{
 				mLastSample = mLastSample + delta;
-				S32	sample_right = (S32)(mLastSample * mCurrentPanGainR);
-				S32	sample_left = (S32)mLastSample - sample_right;
+				MIXBUFFERFORMAT_T	sample_right = (MIXBUFFERFORMAT_T)getClampedSample(clip, mLastSample * mCurrentPanGainR);
+				MIXBUFFERFORMAT_T	sample_left = (MIXBUFFERFORMAT_T)getClampedSample(clip, mLastSample - (F32)sample_right);
 				
-				if (!clip)
-				{
-					*cursamplep = (MIXBUFFERFORMAT_T)sample_left;
-					++cursamplep;
-					*cursamplep = (MIXBUFFERFORMAT_T)sample_right;
-					++cursamplep;
-				}
-				else
-				{
-					*cursamplep = (MIXBUFFERFORMAT_T)llclamp(sample_left, (S32)S16_MIN, (S32)S16_MAX);
-					++cursamplep;
-					*cursamplep = (MIXBUFFERFORMAT_T)llclamp(sample_right, (S32)S16_MIN, (S32)S16_MAX);
-					++cursamplep;
-				}
+				*cursamplep = sample_left;
+				++cursamplep;
+				*cursamplep = sample_right;
+				++cursamplep;
 			}
 		}
 		
@@ -173,4 +166,9 @@ class LLWindGen
 	F32 mLastSample;
 };
 
+template<class T> inline const F32 LLWindGen<T>::getNextSample() { return (F32)rand() * (1.0f / (F32)(RAND_MAX / (U16_MAX / 8))) + (F32)(S16_MIN / 8); }
+template<> inline const F32 LLWindGen<F32>::getNextSample() { return ll_frand()-.5f; }
+template<class T> inline const F32 LLWindGen<T>::getClampedSample(bool clamp, F32 sample) { return clamp ? (F32)llclamp((S32)sample,(S32)S16_MIN,(S32)S16_MAX) : sample; }
+template<> inline const F32 LLWindGen<F32>::getClampedSample(bool clamp, F32 sample) { return sample; }
+
 #endif
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 4f7ce88165902737774ce1ca86872c13a30e671c..fae02c0b30187cdcb58665dfc8344da6d2b293dc 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -10,7 +10,7 @@ include(DirectX)
 include(OpenSSL)
 include(DragDrop)
 include(EXPAT)
-include(FMOD)
+include(FMODEX)
 include(OPENAL)
 include(OpenGL)
 include(Hunspell)
@@ -53,6 +53,10 @@ if (NOT HAVOK_TPV)
    add_subdirectory(${LLPHYSICSEXTENSIONS_SRC_DIR} llphysicsextensions)
 endif (NOT HAVOK_TPV)
 
+if(FMODEX)
+  include_directories(${FMODEX_INCLUDE_DIR})
+endif(FMODEX)
+
 include_directories(
     ${DBUSGLIB_INCLUDE_DIRS}
     ${JSONCPP_INCLUDE_DIR}
@@ -62,7 +66,6 @@ include_directories(
     ${LLCOMMON_INCLUDE_DIRS}
     ${LLCOREHTTP_INCLUDE_DIRS}
     ${LLPHYSICS_INCLUDE_DIRS}
-    ${FMOD_INCLUDE_DIR}
     ${LLIMAGE_INCLUDE_DIRS}
     ${LLKDU_INCLUDE_DIRS}
     ${LLINVENTORY_INCLUDE_DIRS}
@@ -1533,29 +1536,12 @@ endif (WINDOWS)
 
 if (OPENAL)
   set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL")
-endif (OPENAL)
-
-if (FMOD)
-  set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMOD")
+endif (OPENAL)          
 
-  if (DARWIN)
-    set(fmodwrapper_SOURCE_FILES fmodwrapper.cpp)
-    add_library(fmodwrapper SHARED ${fmodwrapper_SOURCE_FILES})
-    set(fmodwrapper_needed_LIBRARIES ${FMOD_LIBRARY} ${CARBON_LIBRARY})
-    set_target_properties(
-      fmodwrapper
-      PROPERTIES
-      BUILD_WITH_INSTALL_RPATH 1
-      INSTALL_NAME_DIR "@executable_path/../Resources"
-      LINK_FLAGS "-unexported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/fmod_hidden_symbols.exp"
-      )
-    set(FMODWRAPPER_LIBRARY fmodwrapper)
-    target_link_libraries(fmodwrapper ${fmodwrapper_needed_LIBRARIES})
-  else (DARWIN)
-    # fmodwrapper unnecessary on linux or windows
-    set(FMODWRAPPER_LIBRARY ${FMOD_LIBRARY})
-  endif (DARWIN)
-endif (FMOD)
+if (FMODEX)
+  set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX")
+  set(FMODWRAPPER_LIBRARY ${FMODEX_LIBRARY})
+endif (FMODEX)
 
 set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
 
@@ -1636,9 +1622,6 @@ if (WINDOWS)
       ${SHARED_LIB_STAGING_DIR}/Release/openjpeg.dll
       ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/openjpeg.dll
       ${SHARED_LIB_STAGING_DIR}/Debug/openjpegd.dll
-      ${SHARED_LIB_STAGING_DIR}/Release/fmod.dll
-      ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmod.dll
-      ${SHARED_LIB_STAGING_DIR}/Debug/fmod.dll
       ${SHARED_LIB_STAGING_DIR}/Release/msvcr100.dll
       ${SHARED_LIB_STAGING_DIR}/Release/msvcp100.dll
       ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/msvcr100.dll
@@ -1703,6 +1686,14 @@ if (WINDOWS)
       windows-updater
       )
 
+    if (FMODEX)
+      list(APPEND COPY_INPUT_DEPENDENCIES
+           ${SHARED_LIB_STAGING_DIR}/Release/fmodex.dll
+           ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmodex.dll
+           ${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll
+          )
+    endif (FMODEX)
+    
     add_custom_command(
       OUTPUT  ${CMAKE_CFG_INTDIR}/copy_touched.bat
       COMMAND ${PYTHON_EXECUTABLE}
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f66d8fca5b5a67bf9ef9e281b0bd2ae8f00c2b0d..3281d347a7028f8ccccf11c95f8ac1ea6c4c1afb 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -291,6 +291,17 @@
       <key>Value</key>
       <real>1.0</real>
     </map>
+    <key>AudioLevelUnderwaterRolloff</key>
+    <map>
+      <key>Comment</key>
+      <string>Controls the distance-based dropoff of audio volume underwater(fraction or multiple of default audio rolloff)</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>5.0</real>
+    </map>
     <key>AudioLevelSFX</key>
     <map>
       <key>Comment</key>
@@ -14446,7 +14457,50 @@
     <key>Value</key>
     <integer>0</integer>
   </map>
-
+  <key>DisablePrecacheDelayAfterTeleporting</key>
+  <map>
+    <key>Comment</key>
+    <string>Disables the artificial delay in the viewer that precaches some incoming assets</string>
+    <key>Persist</key>
+    <integer>0</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
+  <key>FMODExProfilerEnable</key>
+  <map>
+    <key>Comment</key>
+    <string>Enable profiler tool if using FMOD Ex</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+    </map>
+  <key>FMODExDecodeBufferSize</key>
+  <map>
+    <key>Comment</key>
+    <string>Sets the streaming decode buffer size (in milliseconds)</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>1000</integer>
+    </map>
+  <key>FMODExStreamBufferSize</key>
+  <map>
+    <key>Comment</key>
+    <string>Sets the streaming buffer size (in milliseconds)</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>7000</integer>
+  </map>
   <key>DisablePrecacheDelayAfterTeleporting</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/fmod_hidden_symbols.exp b/indra/newview/fmod_hidden_symbols.exp
deleted file mode 100644
index 1e790255bc65f0a58eba47152a17532bbf50eab6..0000000000000000000000000000000000000000
--- a/indra/newview/fmod_hidden_symbols.exp
+++ /dev/null
@@ -1,240 +0,0 @@
-_CarbonSndPlayDoubleBuffer
-_ConvertFromIeeeExtended
-__book_maptype1_quantvals
-__book_unquantize
-__float32_pack
-__float32_unpack
-__ilog
-__make_words
-_lpc_clear
-_lpc_init
-__vorbis_block_alloc
-__vorbis_block_ripcord
-__vorbis_apply_window
-__vorbis_window_get
-_vorbis_analysis_blockout
-_vorbis_analysis_buffer
-_vorbis_analysis_wrote
-_vorbis_block_clear
-_vorbis_block_init
-_vorbis_dsp_clear
-_vorbis_synthesis_blockin
-_vorbis_synthesis_init
-_vorbis_synthesis_pcmout
-_vorbis_synthesis_read
-_vorbis_packet_blocksize
-_vorbis_synthesis
-_vorbis_book_clear
-_vorbis_book_decode
-_vorbis_book_decodev_add
-_vorbis_book_decodev_set
-_vorbis_book_decodevs_add
-_vorbis_book_decodevv_add
-_vorbis_book_init_decode
-_vorbis_comment_add
-_vorbis_comment_add_tag
-_vorbis_comment_clear
-_vorbis_comment_init
-_vorbis_comment_query
-_vorbis_comment_query_count
-_vorbis_coslook
-_vorbis_fromdBlook
-_vorbis_info_blocksize
-_vorbis_info_clear
-_vorbis_info_init
-_vorbis_invsq2explook
-_vorbis_invsqlook
-_vorbis_lpc_from_curve
-_vorbis_lpc_from_data
-_vorbis_lpc_predict
-_vorbis_lsp_to_curve
-_vorbis_staticbook_clear
-_vorbis_staticbook_destroy
-_vorbis_staticbook_unpack
-_vorbis_synthesis_headerin
-_vorbis_synthesis_lapout
-_vorbis_synthesis_restart
-_vorbis_synthesis_trackonly
-_vorbis_window
-_ogg_packet_clear
-_ogg_page_bos
-_ogg_page_checksum_set
-_ogg_page_continued
-_ogg_page_eos
-_ogg_page_granulepos
-_ogg_page_packets
-_ogg_page_pageno
-_ogg_page_serialno
-_ogg_page_version
-_ogg_stream_reset_serialno
-_ogg_stream_clear
-_ogg_stream_destroy
-_ogg_stream_eos
-_ogg_stream_flush
-_ogg_stream_init
-_ogg_stream_packetout
-_ogg_stream_packetpeek
-_ogg_stream_pagein
-_ogg_stream_pageout
-_ogg_stream_reset
-_ogg_sync_buffer
-_ogg_sync_clear
-_ogg_sync_destroy
-_ogg_sync_init
-_ogg_sync_pageout
-_ogg_sync_pageseek
-_ogg_sync_reset
-_ogg_sync_wrote
-_ov_bitrate
-_ov_bitrate_instant
-_ov_clear
-_ov_comment
-_ov_info
-_ov_open
-_ov_open_callbacks
-_ov_pcm_seek
-_ov_pcm_seek_page
-_ov_pcm_tell
-_ov_pcm_total
-_ov_raw_seek
-_ov_raw_tell
-_ov_raw_total
-_ov_read
-_ov_read_float
-_ov_seekable
-_ov_serialnumber
-_ov_streams
-_ov_test
-_ov_test_callbacks
-_ov_test_open
-_ov_time_seek
-_ov_time_seek_page
-_ov_time_tell
-_ov_time_total
-_ogg_toupper
-_oggpackB_adv
-_oggpackB_adv1
-_oggpackB_bits
-_oggpackB_bytes
-_oggpackB_get_buffer
-_oggpackB_look
-_oggpackB_look1
-_oggpackB_read
-_oggpackB_read1
-_oggpackB_readinit
-_oggpackB_reset
-_oggpack_adv
-_oggpack_adv1
-_oggpack_bits
-_oggpack_bytes
-_oggpack_get_buffer
-_oggpack_look
-_oggpack_look1
-_oggpack_read
-_oggpack_read1
-_oggpack_readinit
-_oggpack_reset
-_ov_crosslap
-_ov_pcm_seek_lap
-_ov_pcm_seek_page_lap
-_ov_raw_seek_lap
-_ov_time_seek_lap
-_ov_time_seek_page_lap
-_II_step_one
-_II_step_two
-_MyRecComp
-_SampleRates
-_Sinfo
-_ValidStepIndex
-__Z11fmodwrapperv
-__Z11fmodwrapperv.eh
-__floor_P
-__mapping_P
-__residue_P
-__ve_envelope_clear
-__ve_envelope_init
-__ve_envelope_mark
-__ve_envelope_search
-__ve_envelope_shift
-__vi_gpsy_free
-__vi_psy_free
-__vorbis_window_init
-__vp_ampmax_decay
-__vp_couple
-__vp_global_free
-__vp_global_look
-__vp_noise_normalize
-__vp_noise_normalize_sort
-__vp_noisemask
-__vp_offset_and_mix
-__vp_psy_clear
-__vp_psy_init
-__vp_quantize_couple_memo
-__vp_quantize_couple_sort
-__vp_remove_floor
-__vp_tonemask
-_alloc_0
-_alloc_1
-_alloc_2
-_alloc_3
-_alloc_4
-_bandInfo
-_cdcallback
-_cdchannel
-_cdmode
-_cdnumtracks
-_cdstream
-_cdtrack
-_drft_backward
-_drft_clear
-_drft_forward
-_drft_init
-_eatwhite
-_floor0_exportbundle
-_floor1_exportbundle
-_gFreeList
-_gNMRecBusy
-_gNMRecPtr
-_gSilenceOnes
-_gSilenceTwos
-_longLimit
-_mapping0_exportbundle
-_mdct_backward
-_mdct_clear
-_mdct_forward
-_mdct_init
-_muls
-_mystrdup
-_res0_free_info
-_res0_free_look
-_res0_inverse
-_res0_look
-_res0_unpack
-_res1_class
-_res1_inverse
-_res2_inverse
-_residue0_exportbundle
-_residue1_exportbundle
-_residue2_exportbundle
-_scale
-_shortLimit
-_tabsel_123
-_F_Free
-_F_Malloc
-_F_ReAlloc
-_F_memcmp
-_F_memmove
-_F_strcat
-_F_strchr
-_F_strcmp
-_F_strcpy
-_F_stricmp
-_F_strlen
-_F_strncat
-_F_strncmp
-_F_strncpy
-_F_strnicmp
-_F_strstr
-_F_strupr
-_F_tolower
-_F_toupper
diff --git a/indra/newview/fmodwrapper.cpp b/indra/newview/fmodwrapper.cpp
deleted file mode 100644
index 16f1d19a7864beb0b5eb807d1bb83383166a2973..0000000000000000000000000000000000000000
--- a/indra/newview/fmodwrapper.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/** 
- * @file fmodwrapper.cpp
- * @brief dummy source file for building a shared library to wrap libfmod.a
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-extern "C"
-{
-	void FSOUND_Init(void);
-}
-
-void* fmodwrapper(void)
-{
-	// When building the fmodwrapper library, the linker doesn't seem to want to bring in libfmod.a unless I explicitly
-	// reference at least one symbol in the library.  This seemed like the simplest way.
-	return (void*)&FSOUND_Init;
-}
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index 1381e49c62bb34f45a9f374b1da6ec57608fc3cb..48b883e99957774ed753165696c8abc0f560df97 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -4,17 +4,17 @@
 ## These options are for self-assisted troubleshooting during this beta
 ## testing phase; you should not usually need to touch them.
 
+## - Avoids using any FMOD Ex audio driver.
+#export LL_BAD_FMODEX_DRIVER=x
 ## - Avoids using any OpenAL audio driver.
 #export LL_BAD_OPENAL_DRIVER=x
-## - Avoids using any FMOD audio driver.
-#export LL_BAD_FMOD_DRIVER=x
 
-## - Avoids using the FMOD ESD audio driver.
-#export LL_BAD_FMOD_ESD=x
-## - Avoids using the FMOD OSS audio driver.
-#export LL_BAD_FMOD_OSS=x
-## - Avoids using the FMOD ALSA audio driver.
+## - Avoids using the FMOD Ex PulseAudio audio driver.
+#export LL_BAD_FMOD_PULSEAUDIO=x
+## - Avoids using the FMOD or FMOD Ex ALSA audio driver.
 #export LL_BAD_FMOD_ALSA=x
+## - Avoids using the FMOD or FMOD Ex OSS audio driver.
+#export LL_BAD_FMOD_OSS=x
 
 ## - Avoids the optional OpenGL extensions which have proven most problematic
 ##   on some hardware.  Disabling this option may cause BETTER PERFORMANCE but
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 3adf956ae3ab33f897ca169eae7f0521296e3afe..97962b87053414811c6a7f194328fb0706a8a90a 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1707,19 +1707,7 @@ bool LLAppViewer::cleanup()
 		gAudiop->setStreamingAudioImpl(NULL);
 
 		// shut down the audio subsystem
-
-		bool want_longname = false;
-		if (gAudiop->getDriverName(want_longname) == "FMOD")
-		{
-			// This hack exists because fmod likes to occasionally
-			// crash or hang forever when shutting down, for no
-			// apparent reason.
-			llwarns << "Hack, skipping FMOD audio engine cleanup" << llendflush;
-		}
-		else
-		{
-			gAudiop->shutdown();
-		}
+        gAudiop->shutdown();
 
 		delete gAudiop;
 		gAudiop = NULL;
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 8b71f1067fe03be6013517b7457a5dce9b71dd1f..9d5fd46a1d3310a47040444b86bd996bce8d44bf 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -37,8 +37,8 @@
 #include "llviewermedia_streamingaudio.h"
 #include "llaudioengine.h"
 
-#ifdef LL_FMOD
-# include "llaudioengine_fmod.h"
+#ifdef LL_FMODEX
+# include "llaudioengine_fmodex.h"
 #endif
 
 #ifdef LL_OPENAL
@@ -623,32 +623,32 @@ bool idle_startup()
 		{
 			gAudiop = NULL;
 
-#ifdef LL_OPENAL
+#ifdef LL_FMODEX		
 			if (!gAudiop
 #if !LL_WINDOWS
-			    && NULL == getenv("LL_BAD_OPENAL_DRIVER")
+			    && NULL == getenv("LL_BAD_FMODEX_DRIVER")
 #endif // !LL_WINDOWS
 			    )
 			{
-				gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();
+				gAudiop = (LLAudioEngine *) new LLAudioEngine_FMODEX(gSavedSettings.getBOOL("FMODExProfilerEnable"));
 			}
 #endif
 
-#ifdef LL_FMOD			
+#ifdef LL_OPENAL
 			if (!gAudiop
 #if !LL_WINDOWS
-			    && NULL == getenv("LL_BAD_FMOD_DRIVER")
+			    && NULL == getenv("LL_BAD_OPENAL_DRIVER")
 #endif // !LL_WINDOWS
 			    )
 			{
-				gAudiop = (LLAudioEngine *) new LLAudioEngine_FMOD();
+				gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();
 			}
 #endif
-
+            
 			if (gAudiop)
 			{
 #if LL_WINDOWS
-				// FMOD on Windows needs the window handle to stop playing audio
+				// FMOD Ex on Windows needs the window handle to stop playing audio
 				// when window is minimized. JC
 				void* window_handle = (HWND)gViewerWindow->getPlatformWindow();
 #else
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index 564bf7997af99bff88eb4736b613f4df273c3759..094694dc06164737928f2d762adc23d46b68aacd 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -44,6 +44,8 @@
 #include "llparcel.h"
 #include "llviewermessage.h"
 
+#include "llstreamingaudio.h"
+
 /////////////////////////////////////////////////////////
 
 LLViewerAudio::LLViewerAudio() :
@@ -102,6 +104,11 @@ void LLViewerAudio::startInternetStreamWithAutoFade(std::string streamURI)
 		else
 		{
 			mFadeState = FADE_IN;
+
+			LLStreamingAudioInterface *stream = gAudiop->getStreamingAudioImpl();
+			if(stream && stream->supportsAdjustableBufferSizes())
+				stream->setBufferSizes(gSavedSettings.getU32("FMODExStreamBufferSize"),gSavedSettings.getU32("FMODExDecodeBufferSize"));
+
 			gAudiop->startInternetStream(mNextStreamURI);
 			startFading();
 			registerIdleListener();
@@ -157,6 +164,11 @@ bool LLViewerAudio::onIdleUpdate()
 			if (!mNextStreamURI.empty())
 			{
 				mFadeState = FADE_IN;
+
+				LLStreamingAudioInterface *stream = gAudiop->getStreamingAudioImpl();
+				if(stream && stream->supportsAdjustableBufferSizes())
+					stream->setBufferSizes(gSavedSettings.getU32("FMODExStreamBufferSize"),gSavedSettings.getU32("FMODExDecodeBufferSize"));
+
 				gAudiop->startInternetStream(mNextStreamURI);
 				startFading();
 			}
@@ -386,7 +398,12 @@ void audio_update_volume(bool force_update)
 		gAudiop->setMasterGain ( master_volume );
 
 		gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler"));
-		gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
+
+		if(!LLViewerCamera::getInstance()->cameraUnderWater())
+			gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
+		else
+			gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelUnderwaterRolloff"));
+
 		gAudiop->setMuted(mute_audio || progress_view_visible);
 		
 		//Play any deferred sounds when unmuted
@@ -473,44 +490,22 @@ void audio_update_listener()
 void audio_update_wind(bool force_update)
 {
 #ifdef kAUDIO_ENABLE_WIND
-	//
-	//  Extract height above water to modulate filter by whether above/below water 
-	// 
+
 	LLViewerRegion* region = gAgent.getRegion();
 	if (region)
 	{
-		static F32 last_camera_water_height = -1000.f;
-		LLVector3 camera_pos = gAgentCamera.getCameraPositionAgent();
-		F32 camera_water_height = camera_pos.mV[VZ] - region->getWaterHeight();
-		
-		//
-		//  Don't update rolloff factor unless water surface has been crossed
-		//
-		if (force_update || (last_camera_water_height * camera_water_height) < 0.f)
-		{
-            static LLUICachedControl<F32> rolloff("AudioLevelRolloff", 1.0f);
-			if (camera_water_height < 0.f)
-			{
-				gAudiop->setRolloffFactor(rolloff * LL_ROLLOFF_MULTIPLIER_UNDER_WATER);
-			}
-			else 
-			{
-				gAudiop->setRolloffFactor(rolloff);
-			}
-		}
-        
-        // Scale down the contribution of weather-simulation wind to the
-        // ambient wind noise.  Wind velocity averages 3.5 m/s, with gusts to 7 m/s
-        // whereas steady-state avatar walk velocity is only 3.2 m/s.
-        // Without this the world feels desolate on first login when you are
-        // standing still.
-        static LLUICachedControl<F32> wind_level("AudioLevelWind", 0.5f);
-        LLVector3 scaled_wind_vec = gWindVec * wind_level;
-        
-        // Mix in the avatar's motion, subtract because when you walk north,
-        // the apparent wind moves south.
-        LLVector3 final_wind_vec = scaled_wind_vec - gAgent.getVelocity();
-        
+		// Scale down the contribution of weather-simulation wind to the
+		// ambient wind noise.  Wind velocity averages 3.5 m/s, with gusts to 7 m/s
+		// whereas steady-state avatar walk velocity is only 3.2 m/s.
+		// Without this the world feels desolate on first login when you are
+		// standing still.
+		static LLUICachedControl<F32> wind_level("AudioLevelWind", 0.5f);
+		LLVector3 scaled_wind_vec = gWindVec * wind_level;
+
+		// Mix in the avatar's motion, subtract because when you walk north,
+		// the apparent wind moves south.
+		LLVector3 final_wind_vec = scaled_wind_vec - gAgent.getVelocity();
+
 		// rotate the wind vector to be listener (agent) relative
 		gRelativeWindVec = gAgent.getFrameAgent().rotateToLocal( final_wind_vec );
 
@@ -543,8 +538,7 @@ void audio_update_wind(bool force_update)
 			gAudiop->mMaxWindGain = llmax(gAudiop->mMaxWindGain - volume_delta, 0.f);
 		}
 		
-		last_camera_water_height = camera_water_height;
-		gAudiop->updateWind(gRelativeWindVec, camera_water_height);
+		gAudiop->updateWind(gRelativeWindVec, gAgentCamera.getCameraPositionAgent()[VZ] - gAgent.getRegion()->getWaterHeight());
 	}
 #endif
 }
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 051f5f44853240d6fd397b0eca9d83ea31e5452a..a62f73deef0e2b373f14efb8a682473ab8f6fd3d 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -655,6 +655,7 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("AudioLevelVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
 	gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
 	gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+	gSavedSettings.getControl("AudioLevelUnderwaterRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
 	gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
 	gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
 	gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 69248e26bcbc4a663cc29573f1d3e52cf62729b5..e2b914aae806ceaf905695dd02101b379046984c 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -367,10 +367,14 @@ def construct(self):
                 print err.message
                 print "Skipping COLLADA and GLOD libraries (assumming linked statically)"
 
-
-            # Get fmod dll, continue if missing
-            if not self.path("fmod.dll"):
-                print "Skipping fmod.dll"
+            # Get fmodex dll, continue if missing
+            try:
+                if self.args['configuration'].lower() == 'debug':
+                    self.path("fmodexL.dll")
+                else:
+                    self.path("fmodex.dll")
+            except:
+                print "Skipping fmodex audio library(assuming other audio engine)"
 
             # For textures
             if self.args['configuration'].lower() == 'debug':
@@ -743,6 +747,7 @@ def path_optional(src, dst):
                                 "libcollada14dom.dylib",
                                 "libexpat.1.5.2.dylib",
                                 "libexception_handler.dylib",
+                                "libfmodex.dylib",
                                 "libGLOD.dylib",
                                 ):
                     dylibs += path_optional(os.path.join(libdir, libfile), libfile)
@@ -757,11 +762,7 @@ def path_optional(src, dst):
                                 'SLVoice',
                                 ):
                      self.path2basename(libdir, libfile)
-                
-                # FMOD for sound
-                libfile = "libfmodwrapper.dylib"
-                path_optional(os.path.join(self.args['configuration'], libfile), libfile)
-                
+
                 # our apps
                 for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),
                                          ("mac_updater", "mac-updater.app"),
@@ -1122,11 +1123,13 @@ def construct(self):
                 pass
 
             try:
-                    self.path("libfmod-3.75.so")
+                    self.path("libfmodex-*.so")
+                    self.path("libfmodex.so")
                     pass
             except:
-                    print "Skipping libfmod-3.75.so - not found"
+                    print "Skipping libfmodex.so - not found"
                     pass
+
             self.end_prefix("lib")
 
             # Vivox runtimes