From 0fe5b66dce1dad64a929ec085e5a366e424c73e2 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Fri, 30 Aug 2019 17:58:38 -0600 Subject: [PATCH 01/19] Use latest version of Rodio instead of custom branch --- Cargo.lock | 106 ++++++++++++++++++++++++++++++++++----------- voxygen/Cargo.toml | 2 +- 2 files changed, 81 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 52343f4904..aa4f6a9b76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,10 +21,21 @@ dependencies = [ "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "alga" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "alsa-sys" -version = "0.1.1" -source = "git+https://github.com/desttinghim/cpal?rev=e7c086d0afc368a888ad133c3b1d928b16986130#e7c086d0afc368a888ad133c3b1d928b16986130" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", @@ -311,16 +322,6 @@ dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "cgmath" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "chashmap" version = "2.2.2" @@ -378,7 +379,7 @@ dependencies = [ [[package]] name = "claxon" -version = "0.3.3" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -535,9 +536,9 @@ dependencies = [ [[package]] name = "cpal" version = "0.8.2" -source = "git+https://github.com/desttinghim/cpal?rev=e7c086d0afc368a888ad133c3b1d928b16986130#e7c086d0afc368a888ad133c3b1d928b16986130" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "alsa-sys 0.1.1 (git+https://github.com/desttinghim/cpal?rev=e7c086d0afc368a888ad133c3b1d928b16986130)", + "alsa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "coreaudio-rs 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1023,6 +1024,14 @@ dependencies = [ "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "getrandom" version = "0.1.11" @@ -1512,6 +1521,11 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "libm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "line_drawing" version = "0.7.0" @@ -1596,6 +1610,14 @@ dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "matrixmultiply" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rawpointer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "maybe-uninit" version = "2.0.0" @@ -1722,6 +1744,22 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "nalgebra" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "alga 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "matrixmultiply 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "net2" version = "0.2.33" @@ -2439,6 +2477,11 @@ dependencies = [ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rawpointer" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rayon" version = "1.1.0" @@ -2524,16 +2567,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rodio" -version = "0.8.1" -source = "git+https://github.com/desttinghim/rodio.git?rev=dd93f905c1afefaac03c496a666ecab27d3e391b#dd93f905c1afefaac03c496a666ecab27d3e391b" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cgmath 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "claxon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cpal 0.8.2 (git+https://github.com/desttinghim/cpal?rev=e7c086d0afc368a888ad133c3b1d928b16986130)", + "claxon 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cpal 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "hound 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lewton 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)", "minimp3 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "nalgebra 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3000,6 +3043,11 @@ name = "tuple_utils" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "typenum" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ucd-util" version = "0.1.5" @@ -3181,7 +3229,7 @@ dependencies = [ "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "portpicker 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rodio 0.8.1 (git+https://github.com/desttinghim/rodio.git?rev=dd93f905c1afefaac03c496a666ecab27d3e391b)", + "rodio 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3419,7 +3467,8 @@ dependencies = [ "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" "checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5" "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" -"checksum alsa-sys 0.1.1 (git+https://github.com/desttinghim/cpal?rev=e7c086d0afc368a888ad133c3b1d928b16986130)" = "" +"checksum alga 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d708cb68c7106ed1844de68f50f0157a7788c2909a6926fad5a87546ef6a4ff8" +"checksum alsa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b0edcbbf9ef68f15ae1b620f722180b82a98b6f0628d30baa6b8d2a5abc87d58" "checksum andrew 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b7f09f89872c2b6b29e319377b1fbe91c6f5947df19a25596e121cf19a7b35e" "checksum android_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" @@ -3455,13 +3504,12 @@ dependencies = [ "checksum cexpr 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42aac45e9567d97474a834efdee3081b3c942b2205be932092f53354ce503d6c" "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" "checksum cgl 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "55e7ec0b74fe5897894cbc207092c577e87c52f8a59e8ca8d97ef37551f60a49" -"checksum cgmath 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "87f025a17ad3f30d49015c787903976d5f9cd6115ece1eb7f4d6ffe06b8c4080" "checksum chashmap 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff41a3c2c1e39921b9003de14bf0439c7b63a9039637c291e1a64925d8ddfa45" "checksum chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "77d81f58b7301084de3b958691458a53c3f7e0b1d702f77e550b6a88e3a88abe" "checksum clang-sys 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "611ec2e3a7623afd8a8c0d027887b6b55759d894abbf5fe11b9dc11b50d5b49a" "checksum clang-sys 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e414af9726e1d11660801e73ccc7fb81803fb5f49e5903a25b348b2b3b480d2e" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" -"checksum claxon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "35193597ff846c905e135b66b7a88876a8b684d269a24fa0f6086988fc2197c8" +"checksum claxon 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f86c952727a495bda7abaf09bafdee1a939194dd793d9a8e26281df55ac43b00" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cmake 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "3c84c596dcf125d6781f58e3f4254677ec2a6d8aa56e8501ac277100990b3229" "checksum cocoa 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0c23085dde1ef4429df6e5896b89356d35cdd321fb43afe3e378d010bb5adc6" @@ -3479,7 +3527,7 @@ dependencies = [ "checksum core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)" = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9" "checksum coreaudio-rs 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f229761965dad3e9b11081668a6ea00f1def7aa46062321b5ec245b834f6e491" "checksum coreaudio-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "78fdbabf58d5b1f461e31b94a571c109284f384cec619a3d96e66ec55b4de82b" -"checksum cpal 0.8.2 (git+https://github.com/desttinghim/cpal?rev=e7c086d0afc368a888ad133c3b1d928b16986130)" = "" +"checksum cpal 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d58ae1ed6536b1b233f5e3aeb6997a046ddb4d05e3f61701b58a92eb254a829e" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum crossbeam 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7408247b1b87f480890f28b670c5f8d9a8a4274833433fe74dc0dfd46d33650" "checksum crossbeam 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2d818a4990769aac0c7ff1360e233ef3a41adcb009ebb2036bf6915eb0f6b23c" @@ -3532,6 +3580,7 @@ dependencies = [ "checksum gdk-pixbuf 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c2d2199eba47ebcb9977ce28179649bdd59305ef465c4e6f9b65aaa41c24e6b5" "checksum gdk-pixbuf-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df6a3b73e04fafc07f5ebc083f1096a773412e627828e1103a55e921f81187d8" "checksum gdk-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3162ff940526ddff71bf1f630facee6b5e05d282d125ba0c4c803842819b80c3" +"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" "checksum getrandom 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fc344b02d3868feb131e8b5fe2b9b0a1cc42942679af493061fc13b853243872" "checksum gfx 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "619e38a31e275efaf92c6a94f977db8aac396e3cb6998c176cfde32ce3239b69" "checksum gfx_core 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e1127b02a9d4fcc880091d8a0f4419efd598de4f1649edcd005c76e5792176f" @@ -3583,6 +3632,7 @@ dependencies = [ "checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" "checksum libloading 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fd38073de8f7965d0c17d30546d4bb6da311ab428d1c7a3fc71dff7f9d4979b9" "checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" +"checksum libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" "checksum line_drawing 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5cc7ad3d82c845bdb5dde34ffdcc7a5fb4d2996e1e1ee0f19c33bc80e15196b9" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" @@ -3594,6 +3644,7 @@ dependencies = [ "checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" "checksum mach 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1" "checksum malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +"checksum matrixmultiply 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfed72d871629daa12b25af198f110e8095d7650f5f4c61c5bac28364604f9b" "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" @@ -3608,6 +3659,7 @@ dependencies = [ "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum mopa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a785740271256c230f57462d3b83e52f998433a7062fc18f96d5999474a9f915" "checksum msgbox 0.1.1 (git+https://github.com/bekker/msgbox-rs.git)" = "" +"checksum nalgebra 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aaa9fddbc34c8c35dd2108515587b8ce0cab396f17977b8c738568e4edb521a2" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" @@ -3685,6 +3737,7 @@ dependencies = [ "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +"checksum rawpointer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebac11a9d2e11f2af219b8b8d833b76b1ea0e054aa0e8d8e9e4cbde353bdf019" "checksum rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4" "checksum rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" @@ -3694,7 +3747,7 @@ dependencies = [ "checksum regex 1.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d9d8297cc20bbb6184f8b45ff61c8ee6a9ac56c156cec8e38c3e5084773c44ad" "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" "checksum regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b143cceb2ca5e56d5671988ef8b15615733e7ee16cd348e064333b251b89343f" -"checksum rodio 0.8.1 (git+https://github.com/desttinghim/rodio.git?rev=dd93f905c1afefaac03c496a666ecab27d3e391b)" = "" +"checksum rodio 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d0f961b254e66d147a7b550c78b01308934c97d807a34b417fd0f5a0a0f3a2d" "checksum ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ece421e0c4129b90e4a35b6f625e472e96c552136f5093a2f4fa2bbb75a62d5" "checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" @@ -3749,6 +3802,7 @@ dependencies = [ "checksum tiff 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b7c2cfc4742bd8a32f2e614339dd8ce30dbcf676bb262bd63a2327bc5df57d" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum tuple_utils 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cbfecd7bb8f0a3e96b3b31c46af2677a55a588767c0091f484601424fcb20e7e" +"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" "checksum ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b3b49edd3468c0e6565d85783f51af95212b6fa3986a5500954f00b460874" "checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml index 555a6181c4..324c4ab18d 100644 --- a/voxygen/Cargo.toml +++ b/voxygen/Cargo.toml @@ -54,7 +54,7 @@ num = "0.2.0" backtrace = "0.3.33" rand = "0.7.0" frustum_query = "0.1.2" -rodio = { git = "https://github.com/desttinghim/rodio.git", rev = "dd93f905c1afefaac03c496a666ecab27d3e391b" } +rodio = "0.9.0" crossbeam = "0.7.2" heaptrack = "0.3.0" hashbrown = { version = "0.5.0", features = ["serde", "nightly"] } From 9dc1f8f549c66c032d1a8af3da97acb9e4c00cdb Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Sat, 31 Aug 2019 00:37:09 -0600 Subject: [PATCH 02/19] Revamp AudioFrontend audio::base had a lot of unnescessary abstractions and constructs. The current code simplifies the API in a way that makes sense and that will allow sound effects and fading to be added in an incremental way. --- voxygen/src/audio/mod.rs | 184 +++++++++++++++++++++++++---- voxygen/src/hud/settings_window.rs | 50 +++----- voxygen/src/main.rs | 56 ++++----- voxygen/src/menu/main/mod.rs | 2 + voxygen/src/session.rs | 4 +- 5 files changed, 200 insertions(+), 96 deletions(-) diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index 7de8428049..b4c6c6c6ed 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -1,41 +1,173 @@ -pub mod base; -use base::{Genre, Jukebox}; +use common::assets; +use rodio::{Decoder, Device, Sink, SpatialSink}; + +const LEFT_EAR : [f32; 3] = [1.0, 0.0, 0.0]; +const RIGHT_EAR : [f32; 3] = [-1.0, 0.0, 0.0]; + +#[derive(PartialEq)] +enum AudioType { + Sfx, + Music, +} + +struct Channel { + id: usize, + sink: SpatialSink, + audio_type: AudioType, +} pub struct AudioFrontend { - pub(crate) model: Jukebox, - pub(crate) default_device: String, - pub(crate) device_list: Vec, + pub device: String, + pub device_list: Vec, + audio_device: Option, + + channels: Vec, + next_channel_id: usize, + + sfx_volume: f32, + music_volume: f32, } impl AudioFrontend { - pub(crate) fn new() -> Self { + /// Construct with given device + pub fn new(device: String) -> Self { Self { - model: Jukebox::new(Genre::Bgm), - default_device: base::get_default_device(), - device_list: base::list_devices(), + device: device.clone(), + device_list: list_devices(), + audio_device: get_device_raw(device), + channels: Vec::new(), + next_channel_id: 0, + sfx_volume: 1.0, + music_volume: 1.0, } } - /// Play audio. - pub(crate) fn play(&mut self) { - let path = base::select_random_music(&Genre::Bgm); - - match self.model.player.is_paused() { - true => match self.model.get_genre() { - Genre::Bgm => self.model.player.resume(), - Genre::Sfx => unimplemented!(), // TODO: add support for sound effects. - Genre::None => (), - }, - false => self.model.player.load(&path), + /// Construct in `no-audio` mode for debugging + pub fn no_audio() -> Self { + Self { + device: "none".to_string(), + device_list: list_devices(), + audio_device: None, + channels: Vec::new(), + next_channel_id: 0, + sfx_volume: 1.0, + music_volume: 1.0, } } - /// Construct in `no-audio` mode for debugging. - pub(crate) fn no_audio() -> Self { - Self { - model: Jukebox::new(Genre::None), - default_device: "None".to_owned(), - device_list: Vec::new(), + /// Maintain audio + pub fn maintain(&mut self) { + let mut stopped_channels = Vec::::new(); + for (i, channel) in self.channels.iter().enumerate() { + if channel.sink.empty() { + stopped_channels.push(i); + } } + for i in stopped_channels.iter().rev() { + self.channels.remove(*i); + } + } + + /// Play specfied sound file. + ///```ignore + ///audio.play_sound("voxygen.audio.sfx.step"); + ///``` + pub fn play_sound(&mut self, sound: String) -> usize { + let id = self.next_channel_id; + self.next_channel_id += 1; + + if let Some(device) = &self.audio_device { + let sink = SpatialSink::new(device, [0.0, 0.0, 0.0], LEFT_EAR, RIGHT_EAR); + + let file = assets::load_file(&sound, &["wav", "ogg"]).unwrap(); + let sound = rodio::Decoder::new(file).unwrap(); + + sink.append(sound); + + self.channels.push(Channel { + id, + sink, + audio_type: AudioType::Music, + }); + } + + id + } + + pub fn get_sfx_volume(&self) -> f32 { + self.sfx_volume + } + + pub fn get_music_volume(&self) -> f32 { + self.music_volume + } + + pub fn set_sfx_volume(&mut self, volume: f32) { + self.sfx_volume = volume; + + for channel in self.channels.iter() { + if channel.audio_type == AudioType::Sfx { + channel.sink.set_volume(volume); + } + } + } + + pub fn set_music_volume(&mut self, volume: f32) { + self.music_volume = volume; + + for channel in self.channels.iter() { + if channel.audio_type == AudioType::Music { + channel.sink.set_volume(volume); + } + } + } + + pub fn set_device(&mut self, name: String) { + self.device = name.clone(); + self.audio_device = get_device_raw(name); } } + +pub fn select_random_music() -> String { + let soundtracks = load_soundtracks(); + let index = rand::random::() % soundtracks.len(); + soundtracks[index].clone() +} + +/// Returns the default audio device. +/// Does not return rodio Device struct in case our audio backend changes. +pub fn get_default_device() -> String { + rodio::default_output_device() + .expect("No audio output devices detected.") + .name() +} + +/// Load the audio file directory selected by genre. +pub fn load_soundtracks() -> Vec { + let assets = assets::read_dir("voxygen.audio.soundtrack").unwrap(); + let soundtracks = assets + .filter_map(|entry| { + entry.ok().map(|f| { + let path = f.path(); + path.to_string_lossy().into_owned() + }) + }) + .collect::>(); + + soundtracks +} + +/// Returns a vec of the audio devices available. +/// Does not return rodio Device struct in case our audio backend changes. +pub fn list_devices() -> Vec { + list_devices_raw().iter().map(|x| x.name()).collect() +} + +/// Returns vec of devices +fn list_devices_raw() -> Vec { + rodio::output_devices().collect() +} + +fn get_device_raw(device: String) -> Option { + rodio::output_devices().find(|d| d.name() == device) +} diff --git a/voxygen/src/hud/settings_window.rs b/voxygen/src/hud/settings_window.rs index fbb64e05b2..682eb3dfd9 100644 --- a/voxygen/src/hud/settings_window.rs +++ b/voxygen/src/hud/settings_window.rs @@ -2,7 +2,6 @@ use super::{ img_ids::Imgs, BarNumbers, CrosshairType, Fonts, ShortcutNumbers, Show, XpBar, TEXT_COLOR, }; use crate::{ - audio::base::Genre, ui::{ImageSlider, ScaleMode, ToggleButton}, GlobalState, }; @@ -1251,39 +1250,26 @@ impl<'a> Widget for SettingsWindow<'a> { } // Audio Device Selector -------------------------------------------- - match self.global_state.audio.model.get_genre() { - Genre::Bgm => { - let device = &self.global_state.audio.default_device; - let device_list = &self.global_state.audio.device_list; - Text::new("Volume") - .down_from(state.ids.audio_volume_slider, 10.0) - .font_size(14) - .font_id(self.fonts.opensans) - .color(TEXT_COLOR) - .set(state.ids.audio_device_text, ui); + let device = &self.global_state.audio.device; + let device_list = &self.global_state.audio.device_list; + Text::new("Volume") + .down_from(state.ids.audio_volume_slider, 10.0) + .font_size(14) + .font_id(self.fonts.opensans) + .color(TEXT_COLOR) + .set(state.ids.audio_device_text, ui); - // Get which device is currently selected - let selected = device_list.iter().position(|x| x.contains(device)); + // Get which device is currently selected + let selected = device_list.iter().position(|x| x.contains(device)); - if let Some(clicked) = DropDownList::new(&device_list, selected) - .w_h(400.0, 22.0) - .down_from(state.ids.audio_device_text, 10.0) - .label_font_id(self.fonts.opensans) - .set(state.ids.audio_device_list, ui) - { - let new_val = device_list[clicked].clone(); - events.push(Event::ChangeAudioDevice(new_val)); - } - } - Genre::Sfx => unimplemented!(), - Genre::None => { - Text::new("Volume") - .down_from(state.ids.audio_volume_slider, 10.0) - .font_size(14) - .font_id(self.fonts.opensans) - .color(TEXT_COLOR) - .set(state.ids.audio_device_text, ui); - } + if let Some(clicked) = DropDownList::new(&device_list, selected) + .w_h(400.0, 22.0) + .down_from(state.ids.audio_device_text, 10.0) + .label_font_id(self.fonts.opensans) + .set(state.ids.audio_device_list, ui) + { + let new_val = device_list[clicked].clone(); + events.push(Event::ChangeAudioDevice(new_val)); } } diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs index 4afeda5723..949f1d91d2 100644 --- a/voxygen/src/main.rs +++ b/voxygen/src/main.rs @@ -32,7 +32,7 @@ pub mod window; pub use crate::error::Error; use crate::{ - audio::base::Genre, audio::AudioFrontend, menu::main::MainMenuState, settings::Settings, + audio::AudioFrontend, menu::main::MainMenuState, settings::Settings, window::Window, }; use heaptrack::track_mem; @@ -59,8 +59,7 @@ impl GlobalState { } pub fn maintain(&mut self) { - // TODO: Maintain both `Bgm` and `Sfx` audio threads. - self.audio.play(); + self.audio.maintain(); } } @@ -104,10 +103,28 @@ lazy_static! { fn main() { // Load the settings let settings = Settings::load(); +<<<<<<< HEAD // Save settings to add new fields or create the file if it is not already there if let Err(err) = settings.save_to_file() { panic!("Failed to save settings: {:?}", err); } +======= + let audio_device = match &settings.audio.audio_device { + Some(d) => d.to_string(), + None => audio::get_default_device(), + }; + let audio = if settings.audio.audio_on { + AudioFrontend::new(audio_device) + } else { + AudioFrontend::no_audio() + }; + + let mut global_state = GlobalState { + audio, + window: Window::new(&settings).expect("Failed to create window!"), + settings, + }; +>>>>>>> Revamp AudioFrontend // Initialize logging. let term_log_level = std::env::var_os("VOXYGEN_LOG") @@ -186,39 +203,6 @@ fn main() { default_hook(panic_info); })); - // Set up the global state. - let audio = if settings.audio.audio_on { - AudioFrontend::new() - } else { - AudioFrontend::no_audio() - }; - - let mut global_state = GlobalState { - audio, - window: Window::new(&settings).expect("Failed to create window!"), - settings, - }; - - // Initialize discord. (lazy_static initalise lazily...) - #[cfg(feature = "discord")] - { - match DISCORD_INSTANCE.lock() { - Ok(_disc) => { - //great - } - Err(e) => log::error!("Couldn't init discord: {}", e), - } - } - - match global_state.audio.model.get_genre() { - Genre::Bgm => { - global_state.settings.audio.audio_device = - Some(crate::audio::base::get_default_device()) - } - Genre::Sfx => unimplemented!(), - Genre::None => global_state.settings.audio.audio_device = None, - } - // Set up the initial play state. let mut states: Vec> = vec![Box::new(MainMenuState::new(&mut global_state))]; states diff --git a/voxygen/src/menu/main/mod.rs b/voxygen/src/menu/main/mod.rs index eb2ce26018..facfae1020 100644 --- a/voxygen/src/menu/main/mod.rs +++ b/voxygen/src/menu/main/mod.rs @@ -34,6 +34,8 @@ impl PlayState for MainMenuState { // Used for client creation. let mut client_init: Option = None; + global_state.audio.play_sound("voxygen.audio.soundtrack.veloren_title_tune-3".to_string()); + loop { // Handle window events. for event in global_state.window.fetch_events() { diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 7555b8efc7..e60550cc7f 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -357,13 +357,13 @@ impl PlayState for SessionState { } HudEvent::AdjustVolume(volume) => { - global_state.audio.model.player.set_volume(volume); + global_state.audio.set_music_volume(volume); global_state.settings.audio.music_volume = volume; global_state.settings.save_to_file_warn(); } HudEvent::ChangeAudioDevice(name) => { - global_state.audio.model.player.set_device(&name.clone()); + global_state.audio.set_device(name.clone()); global_state.settings.audio.audio_device = Some(name); global_state.settings.save_to_file_warn(); From 447cfec19fa4fd5267f82eb50700d2ab68510b66 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Sat, 31 Aug 2019 02:30:23 -0600 Subject: [PATCH 03/19] Add support for fading sounds --- voxygen/src/audio/fader.rs | 68 ++++++++++++++++++++++ voxygen/src/audio/mod.rs | 79 +++++++++++++++++++++++--- voxygen/src/main.rs | 4 +- voxygen/src/menu/char_selection/mod.rs | 2 +- voxygen/src/menu/main/mod.rs | 7 ++- voxygen/src/session.rs | 2 +- 6 files changed, 146 insertions(+), 16 deletions(-) create mode 100644 voxygen/src/audio/fader.rs diff --git a/voxygen/src/audio/fader.rs b/voxygen/src/audio/fader.rs new file mode 100644 index 0000000000..25c064365d --- /dev/null +++ b/voxygen/src/audio/fader.rs @@ -0,0 +1,68 @@ + +#[derive(PartialEq, Clone, Copy)] +pub struct Fader { + length: f32, + running_time: f32, + volume_from: f32, + volume_to: f32, + is_running: bool +} + +fn lerp(t: f32, a: f32, b: f32) -> f32 { + (1.0 - t) * a + t * b +} + +impl Fader { + pub fn fade(time: f32, volume_from: f32, volume_to: f32) -> Self { + Self { + length: time, + running_time: 0.0, + volume_from, + volume_to, + is_running: true, + } + } + + pub fn fade_in(time: f32) -> Self { + Self { + length: time, + running_time: 0.0, + volume_from: 0.0, + volume_to: 1.0, + is_running: true, + } + } + + pub fn fade_out(time: f32) -> Self { + Self { + length: time, + running_time: 0.0, + volume_from: 1.0, + volume_to: 0.0, + is_running: true, + } + } + + pub fn update(&mut self, dt: f32) { + if self.is_running { + self.running_time = self.running_time + dt; + if self.running_time >= self.length { + self.running_time = self.length; + self.is_running = false; + } + } + } + + pub fn get_volume(&self) -> f32 { + lerp(self.running_time / self.length, self.volume_from, self.volume_to) + } + + // TODO: Remove + pub fn get_running_time(&self) -> f32 { + self.running_time + } + + pub fn is_finished(&self) -> bool { + self.running_time >= self.length || !self.is_running + } +} diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index b4c6c6c6ed..947954146c 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -1,3 +1,6 @@ +pub mod fader; +use fader::Fader; + use common::assets; use rodio::{Decoder, Device, Sink, SpatialSink}; @@ -10,10 +13,64 @@ enum AudioType { Music, } +#[derive(PartialEq, Clone, Copy)] +enum ChannelState { + Playing, + Stopping, + Stopped, +} + struct Channel { id: usize, sink: SpatialSink, audio_type: AudioType, + state: ChannelState, + fader: Fader, +} + +impl Channel { + pub fn music(id: usize, sink: SpatialSink) -> Self { + Self { + id, + sink, + audio_type: AudioType::Music, + state: ChannelState::Playing, + fader: Fader::fade_in(0.25), + } + } + + pub fn sfx(id: usize, sink: SpatialSink) -> Self { + Self { + id, + sink, + audio_type: AudioType::Sfx, + state: ChannelState::Playing, + fader: Fader::fade_in(0.0), + } + } + + pub fn stop(&mut self, fader: Fader) { + self.state = ChannelState::Stopping; + self.fader = fader; + } + + pub fn get_state(&self) -> ChannelState { + self.state + } + + pub fn update(&mut self, dt: f32) { + match self.state { + ChannelState::Playing => {}, + ChannelState::Stopping => { + self.fader.update(dt); + self.sink.set_volume(self.fader.get_volume()); + if self.fader.is_finished() { + self.state = ChannelState::Stopped; + } + }, + ChannelState::Stopped => {}, + } + } } pub struct AudioFrontend { @@ -56,10 +113,11 @@ impl AudioFrontend { } /// Maintain audio - pub fn maintain(&mut self) { + pub fn maintain(&mut self, dt: f32) { let mut stopped_channels = Vec::::new(); - for (i, channel) in self.channels.iter().enumerate() { - if channel.sink.empty() { + for (i, channel) in self.channels.iter_mut().enumerate() { + channel.update(dt); + if channel.sink.empty() || channel.get_state() == ChannelState::Stopped { stopped_channels.push(i); } } @@ -80,20 +138,23 @@ impl AudioFrontend { let sink = SpatialSink::new(device, [0.0, 0.0, 0.0], LEFT_EAR, RIGHT_EAR); let file = assets::load_file(&sound, &["wav", "ogg"]).unwrap(); - let sound = rodio::Decoder::new(file).unwrap(); + let sound = Decoder::new(file).unwrap(); sink.append(sound); - self.channels.push(Channel { - id, - sink, - audio_type: AudioType::Music, - }); + self.channels.push(Channel::music(id, sink)); } id } + pub fn stop_channel(&mut self, channel_id: usize, fader: Fader) { + let index = self.channels.iter().position(|c| c.id == channel_id); + if let Some(index) = index { + self.channels[index].stop(fader); + } + } + pub fn get_sfx_volume(&self) -> f32 { self.sfx_volume } diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs index 949f1d91d2..49d6c7ac7d 100644 --- a/voxygen/src/main.rs +++ b/voxygen/src/main.rs @@ -58,8 +58,8 @@ impl GlobalState { self.window.needs_refresh_resize(); } - pub fn maintain(&mut self) { - self.audio.maintain(); + pub fn maintain(&mut self, dt: f32) { + self.audio.maintain(dt); } } diff --git a/voxygen/src/menu/char_selection/mod.rs b/voxygen/src/menu/char_selection/mod.rs index 5ddfb528ec..ac5010747f 100644 --- a/voxygen/src/menu/char_selection/mod.rs +++ b/voxygen/src/menu/char_selection/mod.rs @@ -78,7 +78,7 @@ impl PlayState for CharSelectionState { } // Maintain global state. - global_state.maintain(); + global_state.maintain(clock.get_last_delta().as_secs_f32()); // Maintain the scene. self.scene.maintain( diff --git a/voxygen/src/menu/main/mod.rs b/voxygen/src/menu/main/mod.rs index facfae1020..68f503fa9d 100644 --- a/voxygen/src/menu/main/mod.rs +++ b/voxygen/src/menu/main/mod.rs @@ -3,7 +3,7 @@ mod start_singleplayer; mod ui; use super::char_selection::CharSelectionState; -use crate::{window::Event, Direction, GlobalState, PlayState, PlayStateResult}; +use crate::{audio::fader::Fader, window::Event, Direction, GlobalState, PlayState, PlayStateResult}; use client_init::{ClientInit, Error as InitError}; use common::{clock::Clock, comp}; use log::warn; @@ -34,7 +34,8 @@ impl PlayState for MainMenuState { // Used for client creation. let mut client_init: Option = None; - global_state.audio.play_sound("voxygen.audio.soundtrack.veloren_title_tune-3".to_string()); + let music = global_state.audio.play_sound("voxygen.audio.soundtrack.veloren_title_tune-3".to_string()); + global_state.audio.stop_channel(music, Fader::fade_out(10.0)); loop { // Handle window events. @@ -78,7 +79,7 @@ impl PlayState for MainMenuState { } // Maintain global_state - global_state.maintain(); + global_state.maintain(clock.get_last_delta().as_secs_f32()); // Maintain the UI. for event in self.main_menu_ui.maintain(global_state) { diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index e60550cc7f..a3192f51b3 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -271,7 +271,7 @@ impl PlayState for SessionState { } // Maintain global state. - global_state.maintain(); + global_state.maintain(clock.get_last_delta().as_secs_f32()); // Extract HUD events ensuring the client borrow gets dropped. let hud_events = self.hud.maintain( From 132d1080862d96011152a5745c8cbdfead144051 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Sat, 31 Aug 2019 03:06:24 -0600 Subject: [PATCH 04/19] Remove audio/base.rs --- voxygen/src/audio/base.rs | 424 ----------------------------------- voxygen/src/audio/channel.rs | 80 +++++++ voxygen/src/audio/fader.rs | 5 - voxygen/src/audio/mod.rs | 83 +------ 4 files changed, 90 insertions(+), 502 deletions(-) delete mode 100644 voxygen/src/audio/base.rs create mode 100644 voxygen/src/audio/channel.rs diff --git a/voxygen/src/audio/base.rs b/voxygen/src/audio/base.rs deleted file mode 100644 index 72365e6063..0000000000 --- a/voxygen/src/audio/base.rs +++ /dev/null @@ -1,424 +0,0 @@ -use crate::settings::{AudioSettings, Settings}; -use common::assets::read_dir; -use crossbeam::{ - atomic::AtomicCell, - channel::{unbounded, Sender}, - queue::SegQueue, - sync::ShardedLock, -}; -use parking_lot::{Condvar, Mutex}; -use rodio::{Decoder, Device, Sink}; -use std::fs::File; -use std::io::BufReader; -use std::sync::Arc; -use std::thread; - -trait AudioConfig { - fn set_volume(&mut self, volume: f32); - fn set_device(&mut self, name: String); -} - -trait MonoMode { - fn set_mono(tx: Sender) -> Self; -} - -trait StereoMode { - fn set_stereo(tx: Sender) -> Self; -} - -trait DebugMode { - fn set_no_audio(tx: Sender) -> Self; -} - -#[derive(Debug)] -pub enum SinkError { - SinkNotMatch, -} - -#[derive(Clone, Copy, PartialEq, Debug)] -pub enum Genre { - Bgm, - Sfx, - None, -} - -#[derive(Debug)] -pub enum AudioPlayerMsg { - AudioPlay, - AudioStop, - AudioTime(f64), -} - -#[derive(Debug)] -pub enum Action { - Load(String), - Stop, - AdjustVolume(f32), - ChangeDevice(String), -} - -#[derive(Clone)] -struct EventLoop { - condvar: Arc<(Mutex, Condvar)>, - queue: Arc>, - playing: Arc>, -} - -impl EventLoop { - fn new() -> Self { - Self { - condvar: Arc::new((Mutex::new(false), Condvar::new())), - queue: Arc::new(SegQueue::new()), - playing: Arc::new(ShardedLock::new(false)), - } - } -} - -/// The `AudioPlayer` handles exactly what player does by playing audio from emitter. -pub struct AudioPlayer { - event_loop: EventLoop, - paused: AtomicCell, - tx: Sender, -} - -impl AudioPlayer { - pub(crate) fn new(genre: Genre, tx: Sender) -> Self { - match genre { - Genre::Bgm => AudioPlayer::set_mono(tx), - Genre::Sfx => unimplemented!(), - Genre::None => AudioPlayer::set_no_audio(tx), - } - } - - pub(crate) fn load(&self, path: &str) { - self.emit(Action::Load(path.to_string())); - self.set_playing(true); - } - - // pub(crate) fn pause(&mut self) { - // self.paused.store(true); - // self.send(AudioPlayerMsg::AudioStop); - // self.set_playing(false); - // } - - pub(crate) fn resume(&mut self) { - self.paused.store(false); - self.send(AudioPlayerMsg::AudioPlay); - self.set_playing(true); - } - - // pub(crate) fn stop(&mut self) { - // self.paused.store(false); - // self.send(AudioPlayerMsg::AudioStop); - // self.emit(Action::Stop); - // self.set_playing(false); - // } - - pub(crate) fn is_paused(&self) -> bool { - self.paused.load() - } - - pub(crate) fn set_volume(&self, value: f32) { - self.emit(Action::AdjustVolume(value)); - } - - pub(crate) fn set_device(&self, device: &str) { - self.emit(Action::ChangeDevice(device.to_string())); - } - - fn emit(&self, action: Action) { - self.event_loop.queue.push(action); - } - - fn send(&mut self, msg: AudioPlayerMsg) { - send_msg(&mut self.tx, msg); - } - - fn set_playing(&self, playing: bool) { - *self.event_loop.playing.write().unwrap() = playing; - let &(ref lock, ref condvar) = &*self.event_loop.condvar; - let mut started = lock.lock(); - *started = playing; - if playing { - condvar.notify_one(); - } - } -} - -impl MonoMode for AudioPlayer { - /// Playing audio until a receive operation appears on the other side. - fn set_mono(tx: Sender) -> Self { - let event_loop = EventLoop::new(); - - { - //let mut tx = tx.clone(); - let event_loop = event_loop.clone(); - let condition = event_loop.condvar.clone(); - - thread::spawn(move || { - let block = || { - let (ref lock, ref condvar) = *condition; - let mut started = lock.lock(); - *started = false; - while !*started { - condvar.wait(&mut started); - } - }; - let mut playback = MonoEmitter::new(&Settings::load().audio); - - // Start the thread if set_playing(true). - loop { - if let Ok(action) = event_loop.queue.pop() { - match action { - Action::Load(path) => { - if playback.stream.empty() { - playback.play_from(&path); - //send_msg(&mut tx, AudioPlayerMsg::AudioPlay); - } - } - Action::Stop => playback.stream.stop(), - Action::AdjustVolume(value) => playback.set_volume(value), - Action::ChangeDevice(device) => playback.set_device(device), - } - } else { - block(); - } - } - }); - } - - Self { - event_loop, - paused: AtomicCell::new(false), - tx, - } - } -} - -impl DebugMode for AudioPlayer { - /// Don't load `rodio` for `no-audio` feature. - fn set_no_audio(tx: Sender) -> Self { - Self { - event_loop: EventLoop::new(), - paused: AtomicCell::new(true), - tx, - } - } -} - -/// TODO: Implement treeview and modellist widgets for GUI design. -pub struct Jukebox { - genre: AtomicCell, - pub(crate) player: AudioPlayer, -} - -impl Jukebox { - pub(crate) fn new(genre: Genre) -> Self { - let (tx, _rx) = unbounded(); - Self { - genre: AtomicCell::new(genre), - player: AudioPlayer::new(genre, tx), - } - } - - // TODO: The `update` function should associate with `conrod` to visualise the audio playlist - // and settings. - // pub(crate) fn update(&mut self, _msg: AudioPlayerMsg) { - // unimplemented!() - // } - - /// Display the current genre. - pub(crate) fn get_genre(&self) -> Genre { - self.genre.load() - } -} - -struct MonoEmitter { - device: Device, - stream: Sink, -} - -// struct StereoEmitter { -// device: Device, -// stream: SpatialSink, -// } - -impl MonoEmitter { - fn new(settings: &AudioSettings) -> Self { - let device = match &settings.audio_device { - Some(dev) => rodio::output_devices() - .find(|x| &x.name() == dev) - .or_else(rodio::default_output_device) - .expect("No Audio devices found!"), - None => rodio::default_output_device().expect("No Audio devices found!"), - }; - let sink = Sink::new(&device); - sink.set_volume(settings.music_volume); - - Self { - device, - stream: sink, - } - } - - // /// Returns the name of the current audio device. - // /// Does not return rodio Device struct in case our audio backend changes. - // fn get_device(&self) -> String { - // self.device.name() - // } - - fn play_from(&mut self, path: &str) { - let bufreader = BufReader::new(File::open(path).unwrap()); - let src = Decoder::new(bufreader).unwrap(); - self.stream.append(src); - } -} - -impl AudioConfig for MonoEmitter { - fn set_volume(&mut self, volume: f32) { - self.stream.set_volume(volume.min(1.0).max(0.0)) - } - - /// Sets the current audio device from a string. - /// Does not use the rodio Device struct in case that detail changes. - /// If the string is an invalid audio device, then no change is made. - fn set_device(&mut self, name: String) { - if let Some(dev) = rodio::output_devices().find(|x| x.name() == name) { - self.device = dev; - self.stream = Sink::new(&self.device); - } - } -} - -// impl StereoEmitter { -// fn new(settings: &AudioSettings) -> Self { -// let device = match &settings.audio_device { -// Some(dev) => rodio::output_devices() -// .find(|x| &x.name() == dev) -// .or_else(rodio::default_output_device) -// .expect("No Audio devices found!"), -// None => rodio::default_output_device().expect("No Audio devices found!"), -// }; -// let sink = SpatialSink::new( -// &device.device, -// [0.0, 0.0, 0.0], -// [1.0, 0.0, 0.0], -// [-1.0, 0.0, 0.0], -// ); -// sink.set_volume(settings.music_volume); - -// Self { -// device, -// stream: sink, -// } -// } - -// fn play_from(&mut self, path: &str) { -// let bufreader = load_from_path(path).unwrap(); -// let src = Decoder::new(bufreader).unwrap(); -// self.stream.append(src); -// } -// } - -// impl AudioConfig for StereoEmitter { -// fn set_volume(&mut self, volume: f32) { -// self.stream.set_volume(volume.min(1.0).max(0.0)) -// } - -// /// Sets the current audio device from a string. -// /// Does not use the rodio Device struct in case that detail changes. -// /// If the string is an invalid audio device, then no change is made. -// fn set_device(&mut self, name: String) { -// if let Some(dev) = rodio::output_devices().find(|x| x.name() == name) { -// self.device = dev; -// self.stream = SpatialSink::new( -// &self.device, -// [0.0, 0.0, 0.0], -// [1.0, 0.0, 0.0], -// [-1.0, 0.0, 0.0], -// ); -// } -// } -// } - -/// Returns the default audio device. -/// Does not return rodio Device struct in case our audio backend changes. -pub(crate) fn get_default_device() -> String { - rodio::default_output_device() - .expect("No audio output devices detected.") - .name() -} - -/// Load the audio file directory selected by genre. -pub(crate) fn load_soundtracks(genre: &Genre) -> Vec { - match *genre { - Genre::Bgm => { - let assets = read_dir("voxygen.audio.soundtrack").unwrap(); - let soundtracks = assets - .filter_map(|entry| { - entry.ok().map(|f| { - let path = f.path(); - path.to_string_lossy().into_owned() - }) - }) - .collect::>(); - - soundtracks - } - Genre::Sfx => { - let assets = read_dir("voxygen.audio.soundtrack").unwrap(); - let soundtracks = assets - //.filter_map(|entry| { - // entry.ok().and_then(|f| { - // f.path() - // .file_name() - // .and_then(|n| n.to_str().map(|s| String::from(s))) - // }) - //}) - //.collect::>(); - .filter_map(|entry| { - entry.ok().map(|f| { - let path = f.path(); - (*path.into_os_string().to_string_lossy()).to_owned() - }) - }) - .collect::>(); - - soundtracks - } - Genre::None => { - let empty_list = Vec::new(); - empty_list - } - } -} - -pub(crate) fn select_random_music(genre: &Genre) -> String { - let soundtracks = load_soundtracks(genre); - let index = rand::random::() % soundtracks.len(); - soundtracks[index].clone() -} - -/// Returns a vec of the audio devices available. -/// Does not return rodio Device struct in case our audio backend changes. -pub(crate) fn list_devices() -> Vec { - list_devices_raw().iter().map(|x| x.name()).collect() -} - -/// Returns vec of devices -fn list_devices_raw() -> Vec { - rodio::output_devices().collect() -} - -fn send_msg(tx: &mut Sender, msg: AudioPlayerMsg) { - tx.send(msg) - .expect("Failed on attempting to send a message into audio channel."); -} - -#[test] -fn test_load_soundtracks() { - use crate::audio::base::{load_soundtracks, Genre}; - for entry in load_soundtracks(&Genre::Bgm).iter() { - println!("{}", entry) - } -} diff --git a/voxygen/src/audio/channel.rs b/voxygen/src/audio/channel.rs new file mode 100644 index 0000000000..82e82ae882 --- /dev/null +++ b/voxygen/src/audio/channel.rs @@ -0,0 +1,80 @@ +use rodio::SpatialSink; +use crate::audio::fader::Fader; + +#[derive(PartialEq, Clone, Copy)] +pub enum AudioType { + Sfx, + Music, +} + +#[derive(PartialEq, Clone, Copy)] +enum ChannelState { + Playing, + Stopping, + Stopped, +} + +pub struct Channel { + id: usize, + sink: SpatialSink, + audio_type: AudioType, + state: ChannelState, + fader: Fader, +} + +impl Channel { + pub fn music(id: usize, sink: SpatialSink) -> Self { + Self { + id, + sink, + audio_type: AudioType::Music, + state: ChannelState::Playing, + fader: Fader::fade_in(0.25), + } + } + + pub fn sfx(id: usize, sink: SpatialSink) -> Self { + Self { + id, + sink, + audio_type: AudioType::Sfx, + state: ChannelState::Playing, + fader: Fader::fade_in(0.0), + } + } + + pub fn is_done(&self) -> bool { + self.sink.empty() || self.state == ChannelState::Stopped + } + + pub fn stop(&mut self, fader: Fader) { + self.state = ChannelState::Stopping; + self.fader = fader; + } + + pub fn get_id(&self) -> usize { + self.id + } + + pub fn get_audio_type(&self) -> AudioType { + self.audio_type + } + + pub fn set_volume(&mut self, volume: f32) { + self.sink.set_volume(volume); + } + + pub fn update(&mut self, dt: f32) { + match self.state { + ChannelState::Playing => {}, + ChannelState::Stopping => { + self.fader.update(dt); + self.sink.set_volume(self.fader.get_volume()); + if self.fader.is_finished() { + self.state = ChannelState::Stopped; + } + }, + ChannelState::Stopped => {}, + } + } +} diff --git a/voxygen/src/audio/fader.rs b/voxygen/src/audio/fader.rs index 25c064365d..b0e7fe9709 100644 --- a/voxygen/src/audio/fader.rs +++ b/voxygen/src/audio/fader.rs @@ -57,11 +57,6 @@ impl Fader { lerp(self.running_time / self.length, self.volume_from, self.volume_to) } - // TODO: Remove - pub fn get_running_time(&self) -> f32 { - self.running_time - } - pub fn is_finished(&self) -> bool { self.running_time >= self.length || !self.is_running } diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index 947954146c..db6490d544 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -1,5 +1,7 @@ pub mod fader; +pub mod channel; use fader::Fader; +use channel::{AudioType, Channel}; use common::assets; use rodio::{Decoder, Device, Sink, SpatialSink}; @@ -7,71 +9,6 @@ use rodio::{Decoder, Device, Sink, SpatialSink}; const LEFT_EAR : [f32; 3] = [1.0, 0.0, 0.0]; const RIGHT_EAR : [f32; 3] = [-1.0, 0.0, 0.0]; -#[derive(PartialEq)] -enum AudioType { - Sfx, - Music, -} - -#[derive(PartialEq, Clone, Copy)] -enum ChannelState { - Playing, - Stopping, - Stopped, -} - -struct Channel { - id: usize, - sink: SpatialSink, - audio_type: AudioType, - state: ChannelState, - fader: Fader, -} - -impl Channel { - pub fn music(id: usize, sink: SpatialSink) -> Self { - Self { - id, - sink, - audio_type: AudioType::Music, - state: ChannelState::Playing, - fader: Fader::fade_in(0.25), - } - } - - pub fn sfx(id: usize, sink: SpatialSink) -> Self { - Self { - id, - sink, - audio_type: AudioType::Sfx, - state: ChannelState::Playing, - fader: Fader::fade_in(0.0), - } - } - - pub fn stop(&mut self, fader: Fader) { - self.state = ChannelState::Stopping; - self.fader = fader; - } - - pub fn get_state(&self) -> ChannelState { - self.state - } - - pub fn update(&mut self, dt: f32) { - match self.state { - ChannelState::Playing => {}, - ChannelState::Stopping => { - self.fader.update(dt); - self.sink.set_volume(self.fader.get_volume()); - if self.fader.is_finished() { - self.state = ChannelState::Stopped; - } - }, - ChannelState::Stopped => {}, - } - } -} pub struct AudioFrontend { pub device: String, @@ -117,7 +54,7 @@ impl AudioFrontend { let mut stopped_channels = Vec::::new(); for (i, channel) in self.channels.iter_mut().enumerate() { channel.update(dt); - if channel.sink.empty() || channel.get_state() == ChannelState::Stopped { + if channel.is_done() { stopped_channels.push(i); } } @@ -149,7 +86,7 @@ impl AudioFrontend { } pub fn stop_channel(&mut self, channel_id: usize, fader: Fader) { - let index = self.channels.iter().position(|c| c.id == channel_id); + let index = self.channels.iter().position(|c| c.get_id() == channel_id); if let Some(index) = index { self.channels[index].stop(fader); } @@ -166,9 +103,9 @@ impl AudioFrontend { pub fn set_sfx_volume(&mut self, volume: f32) { self.sfx_volume = volume; - for channel in self.channels.iter() { - if channel.audio_type == AudioType::Sfx { - channel.sink.set_volume(volume); + for channel in self.channels.iter_mut() { + if channel.get_audio_type() == AudioType::Sfx { + channel.set_volume(volume); } } } @@ -176,9 +113,9 @@ impl AudioFrontend { pub fn set_music_volume(&mut self, volume: f32) { self.music_volume = volume; - for channel in self.channels.iter() { - if channel.audio_type == AudioType::Music { - channel.sink.set_volume(volume); + for channel in self.channels.iter_mut() { + if channel.get_audio_type() == AudioType::Music { + channel.set_volume(volume); } } } From 41cd20aaf83bd773df561ac0b69e85e3aa88054a Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Sat, 31 Aug 2019 15:39:40 -0600 Subject: [PATCH 05/19] Add play_music call to audiofrontend --- voxygen/src/audio/channel.rs | 2 +- voxygen/src/audio/mod.rs | 20 +++++++++++++++++++- voxygen/src/menu/main/mod.rs | 2 +- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/voxygen/src/audio/channel.rs b/voxygen/src/audio/channel.rs index 82e82ae882..1c4a509496 100644 --- a/voxygen/src/audio/channel.rs +++ b/voxygen/src/audio/channel.rs @@ -29,7 +29,7 @@ impl Channel { sink, audio_type: AudioType::Music, state: ChannelState::Playing, - fader: Fader::fade_in(0.25), + fader: Fader::fade_in(0.0), } } diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index db6490d544..7a5cfe1fbe 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -74,7 +74,25 @@ impl AudioFrontend { if let Some(device) = &self.audio_device { let sink = SpatialSink::new(device, [0.0, 0.0, 0.0], LEFT_EAR, RIGHT_EAR); - let file = assets::load_file(&sound, &["wav", "ogg"]).unwrap(); + let file = assets::load_file(&sound, &["wav"]).unwrap(); + let sound = Decoder::new(file).unwrap(); + + sink.append(sound); + + self.channels.push(Channel::sfx(id, sink)); + } + + id + } + + pub fn play_music(&mut self, sound: String) -> usize { + let id = self.next_channel_id; + self.next_channel_id += 1; + + if let Some(device) = &self.audio_device { + let sink = SpatialSink::new(device, [0.0, 0.0, 0.0], LEFT_EAR, RIGHT_EAR); + + let file = assets::load_file(&sound, &["ogg"]).unwrap(); let sound = Decoder::new(file).unwrap(); sink.append(sound); diff --git a/voxygen/src/menu/main/mod.rs b/voxygen/src/menu/main/mod.rs index 68f503fa9d..a688a753aa 100644 --- a/voxygen/src/menu/main/mod.rs +++ b/voxygen/src/menu/main/mod.rs @@ -34,7 +34,7 @@ impl PlayState for MainMenuState { // Used for client creation. let mut client_init: Option = None; - let music = global_state.audio.play_sound("voxygen.audio.soundtrack.veloren_title_tune-3".to_string()); + let music = global_state.audio.play_music("voxygen.audio.soundtrack.veloren_title_tune-3".to_string()); global_state.audio.stop_channel(music, Fader::fade_out(10.0)); loop { From ad3bd0b2ce462179bb1836139fc35dfb0c6552e9 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Sat, 31 Aug 2019 19:32:39 -0600 Subject: [PATCH 06/19] Add footstep sounds, implement crude footstep sounding Sounds are played every tick, which is not good. --- assets/voxygen/audio/footsteps/stepdirt_1.wav | 3 ++ assets/voxygen/audio/footsteps/stepdirt_2.wav | 3 ++ assets/voxygen/audio/footsteps/stepdirt_3.wav | 3 ++ assets/voxygen/audio/footsteps/stepdirt_4.wav | 3 ++ assets/voxygen/audio/footsteps/stepdirt_5.wav | 3 ++ assets/voxygen/audio/footsteps/stepdirt_6.wav | 3 ++ assets/voxygen/audio/footsteps/stepdirt_7.wav | 3 ++ assets/voxygen/audio/footsteps/stepdirt_8.wav | 3 ++ assets/voxygen/audio/footsteps/stepsnow_1.wav | 3 ++ assets/voxygen/audio/footsteps/stepsnow_2.wav | 3 ++ .../voxygen/audio/footsteps/stepstone_1.wav | 3 ++ .../voxygen/audio/footsteps/stepstone_2.wav | 3 ++ .../voxygen/audio/footsteps/stepstone_3.wav | 3 ++ .../voxygen/audio/footsteps/stepstone_4.wav | 3 ++ .../voxygen/audio/footsteps/stepstone_5.wav | 3 ++ .../voxygen/audio/footsteps/stepstone_6.wav | 3 ++ .../voxygen/audio/footsteps/stepstone_7.wav | 3 ++ .../voxygen/audio/footsteps/stepstone_8.wav | 3 ++ .../voxygen/audio/footsteps/stepwater_1.wav | 3 ++ .../voxygen/audio/footsteps/stepwater_2.wav | 3 ++ assets/voxygen/audio/footsteps/stepwood_1.wav | 3 ++ assets/voxygen/audio/footsteps/stepwood_2.wav | 3 ++ voxygen/src/audio/mod.rs | 2 +- voxygen/src/menu/main/mod.rs | 1 - voxygen/src/scene/mod.rs | 10 +++- voxygen/src/scene/sound.rs | 53 +++++++++++++++++++ voxygen/src/session.rs | 2 +- 27 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 assets/voxygen/audio/footsteps/stepdirt_1.wav create mode 100644 assets/voxygen/audio/footsteps/stepdirt_2.wav create mode 100644 assets/voxygen/audio/footsteps/stepdirt_3.wav create mode 100644 assets/voxygen/audio/footsteps/stepdirt_4.wav create mode 100644 assets/voxygen/audio/footsteps/stepdirt_5.wav create mode 100644 assets/voxygen/audio/footsteps/stepdirt_6.wav create mode 100644 assets/voxygen/audio/footsteps/stepdirt_7.wav create mode 100644 assets/voxygen/audio/footsteps/stepdirt_8.wav create mode 100644 assets/voxygen/audio/footsteps/stepsnow_1.wav create mode 100644 assets/voxygen/audio/footsteps/stepsnow_2.wav create mode 100644 assets/voxygen/audio/footsteps/stepstone_1.wav create mode 100644 assets/voxygen/audio/footsteps/stepstone_2.wav create mode 100644 assets/voxygen/audio/footsteps/stepstone_3.wav create mode 100644 assets/voxygen/audio/footsteps/stepstone_4.wav create mode 100644 assets/voxygen/audio/footsteps/stepstone_5.wav create mode 100644 assets/voxygen/audio/footsteps/stepstone_6.wav create mode 100644 assets/voxygen/audio/footsteps/stepstone_7.wav create mode 100644 assets/voxygen/audio/footsteps/stepstone_8.wav create mode 100644 assets/voxygen/audio/footsteps/stepwater_1.wav create mode 100644 assets/voxygen/audio/footsteps/stepwater_2.wav create mode 100644 assets/voxygen/audio/footsteps/stepwood_1.wav create mode 100644 assets/voxygen/audio/footsteps/stepwood_2.wav create mode 100644 voxygen/src/scene/sound.rs diff --git a/assets/voxygen/audio/footsteps/stepdirt_1.wav b/assets/voxygen/audio/footsteps/stepdirt_1.wav new file mode 100644 index 0000000000..dc4c7f75be --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepdirt_1.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8887df14b8eb7be26cbaf27f4546427cc8c88e69a872812e3e60b096eb5acd98 +size 94334 diff --git a/assets/voxygen/audio/footsteps/stepdirt_2.wav b/assets/voxygen/audio/footsteps/stepdirt_2.wav new file mode 100644 index 0000000000..0d5b2bbe8e --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepdirt_2.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b86d824478f049cb594af8743ccad624bbc9777ebfeb5fcb3662387d873b156 +size 94334 diff --git a/assets/voxygen/audio/footsteps/stepdirt_3.wav b/assets/voxygen/audio/footsteps/stepdirt_3.wav new file mode 100644 index 0000000000..0f72e8e9c9 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepdirt_3.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4330304f401b5e392f53c92ff5d25b3badb6f40364e176d3337e770614803e0b +size 115890 diff --git a/assets/voxygen/audio/footsteps/stepdirt_4.wav b/assets/voxygen/audio/footsteps/stepdirt_4.wav new file mode 100644 index 0000000000..e9181d1ec1 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepdirt_4.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7425cd32c55e7ded6a191ac1fdf8ff0db8dd8e36910bc84d331ef2d138457808 +size 132426 diff --git a/assets/voxygen/audio/footsteps/stepdirt_5.wav b/assets/voxygen/audio/footsteps/stepdirt_5.wav new file mode 100644 index 0000000000..53e13e2f67 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepdirt_5.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8be0a6928a9e4516d518b92cc922ba7f4c691214b00bb3f09a4a9ccf682bd2db +size 132426 diff --git a/assets/voxygen/audio/footsteps/stepdirt_6.wav b/assets/voxygen/audio/footsteps/stepdirt_6.wav new file mode 100644 index 0000000000..60ce837fe2 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepdirt_6.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02b35836fbbf2366d6d04c4895c77e89cd92a0ff80d69ea622389ae35df615a8 +size 132426 diff --git a/assets/voxygen/audio/footsteps/stepdirt_7.wav b/assets/voxygen/audio/footsteps/stepdirt_7.wav new file mode 100644 index 0000000000..cc43af0c3d --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepdirt_7.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e2181e677fda51a0aa51eabd88efbc2cffe89b43fd65f2dd3ccaeecaddd3dc6 +size 132426 diff --git a/assets/voxygen/audio/footsteps/stepdirt_8.wav b/assets/voxygen/audio/footsteps/stepdirt_8.wav new file mode 100644 index 0000000000..985f4c5bde --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepdirt_8.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0eaa8b697b6ba583b7f34844b9497d1654d2dd6a3eaf3fb98c19c58c9d49669d +size 132426 diff --git a/assets/voxygen/audio/footsteps/stepsnow_1.wav b/assets/voxygen/audio/footsteps/stepsnow_1.wav new file mode 100644 index 0000000000..326f9f6b39 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepsnow_1.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6807671167bd3c4e670b16c2df1ba637ce6e2c3b1ba71dfdfb64d50f0694316 +size 94334 diff --git a/assets/voxygen/audio/footsteps/stepsnow_2.wav b/assets/voxygen/audio/footsteps/stepsnow_2.wav new file mode 100644 index 0000000000..7939739411 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepsnow_2.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d78b771b2364abf5207fcb0abfb66af7b9b3011a28e7dfc05579f0266f4292d +size 74866 diff --git a/assets/voxygen/audio/footsteps/stepstone_1.wav b/assets/voxygen/audio/footsteps/stepstone_1.wav new file mode 100644 index 0000000000..d063b32f89 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepstone_1.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acc063c76b7fb7237b22b0c276fe515c26013d9d62e19421f4b05d6e41a03e3d +size 74866 diff --git a/assets/voxygen/audio/footsteps/stepstone_2.wav b/assets/voxygen/audio/footsteps/stepstone_2.wav new file mode 100644 index 0000000000..cb44231a89 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepstone_2.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05aea43667a4cdbb2f964888cf4b91c6361e9b7e7a8aaf157a4954f3e89c62e2 +size 74866 diff --git a/assets/voxygen/audio/footsteps/stepstone_3.wav b/assets/voxygen/audio/footsteps/stepstone_3.wav new file mode 100644 index 0000000000..b48ee93153 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepstone_3.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe5e1cab24a0f3d3177bd35b7184b1549d1486d6323b5f998375cabcb16ce51e +size 99354 diff --git a/assets/voxygen/audio/footsteps/stepstone_4.wav b/assets/voxygen/audio/footsteps/stepstone_4.wav new file mode 100644 index 0000000000..e00b3a4872 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepstone_4.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9713007299db5277d6344d43819bb7c107fc0c1cd845f0df28c1e7877d758ae4 +size 99354 diff --git a/assets/voxygen/audio/footsteps/stepstone_5.wav b/assets/voxygen/audio/footsteps/stepstone_5.wav new file mode 100644 index 0000000000..c4fc9fca79 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepstone_5.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7c41b17589753dd01c96c9b1cb08d29d184e54c13cf9dda389e063166361651 +size 99354 diff --git a/assets/voxygen/audio/footsteps/stepstone_6.wav b/assets/voxygen/audio/footsteps/stepstone_6.wav new file mode 100644 index 0000000000..58c3351eb1 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepstone_6.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d698fb1ef14cd1c77fdd6bbbe422d067c0d189ba54681019ac7d5d409771466 +size 99354 diff --git a/assets/voxygen/audio/footsteps/stepstone_7.wav b/assets/voxygen/audio/footsteps/stepstone_7.wav new file mode 100644 index 0000000000..855660a9d7 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepstone_7.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9da9d99ebc22f571cd7b9cd2f338596904f50d02f700de95c2cd92d15106c25e +size 99354 diff --git a/assets/voxygen/audio/footsteps/stepstone_8.wav b/assets/voxygen/audio/footsteps/stepstone_8.wav new file mode 100644 index 0000000000..30b384ebd0 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepstone_8.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c9d45c7d701edab0910eb04c0b9f0ba8e1aad60afe876f54dbc5ee4f80ab99fd +size 99354 diff --git a/assets/voxygen/audio/footsteps/stepwater_1.wav b/assets/voxygen/audio/footsteps/stepwater_1.wav new file mode 100644 index 0000000000..d803e6b857 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepwater_1.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:89029ec15d493acc15ff4713b2b6421ae697bc7d04f0d3437e1033554069cf7f +size 191106 diff --git a/assets/voxygen/audio/footsteps/stepwater_2.wav b/assets/voxygen/audio/footsteps/stepwater_2.wav new file mode 100644 index 0000000000..6e4a990b11 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepwater_2.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32b682ba987e7bbfec3e287f44329f01c87fff298a00178659768091e2c9eca8 +size 158846 diff --git a/assets/voxygen/audio/footsteps/stepwood_1.wav b/assets/voxygen/audio/footsteps/stepwood_1.wav new file mode 100644 index 0000000000..8852250ce3 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepwood_1.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:908ddfda1c15bed8b46c5cff6b13203cffa957f79274ad9b260d598961c9873f +size 94334 diff --git a/assets/voxygen/audio/footsteps/stepwood_2.wav b/assets/voxygen/audio/footsteps/stepwood_2.wav new file mode 100644 index 0000000000..45ff7d0c56 --- /dev/null +++ b/assets/voxygen/audio/footsteps/stepwood_2.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f07a24d1e2593e37f5504a314a240650f2cd0c16df2bd45b62138bbf43d197cf +size 74866 diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index 7a5cfe1fbe..3d4fa2c12b 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -4,7 +4,7 @@ use fader::Fader; use channel::{AudioType, Channel}; use common::assets; -use rodio::{Decoder, Device, Sink, SpatialSink}; +use rodio::{Decoder, Device, SpatialSink}; const LEFT_EAR : [f32; 3] = [1.0, 0.0, 0.0]; const RIGHT_EAR : [f32; 3] = [-1.0, 0.0, 0.0]; diff --git a/voxygen/src/menu/main/mod.rs b/voxygen/src/menu/main/mod.rs index a688a753aa..04f7c2a111 100644 --- a/voxygen/src/menu/main/mod.rs +++ b/voxygen/src/menu/main/mod.rs @@ -35,7 +35,6 @@ impl PlayState for MainMenuState { let mut client_init: Option = None; let music = global_state.audio.play_music("voxygen.audio.soundtrack.veloren_title_tune-3".to_string()); - global_state.audio.stop_channel(music, Fader::fade_out(10.0)); loop { // Handle window events. diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index 96518f516b..6936b66f9e 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -1,11 +1,13 @@ pub mod camera; pub mod figure; pub mod terrain; +pub mod sound; use self::{ camera::{Camera, CameraMode}, figure::FigureMgr, terrain::Terrain, + sound::SoundMgr, }; use crate::{ render::{ @@ -13,6 +15,7 @@ use crate::{ PostProcessPipeline, Renderer, SkyboxLocals, SkyboxPipeline, }, window::Event, + audio::AudioFrontend, }; use client::Client; use common::{comp, terrain::BlockKind, vol::ReadVol}; @@ -46,6 +49,7 @@ pub struct Scene { loaded_distance: f32, figure_mgr: FigureMgr, + sound_mgr: SoundMgr, } impl Scene { @@ -71,6 +75,7 @@ impl Scene { terrain: Terrain::new(renderer), loaded_distance: 0.0, figure_mgr: FigureMgr::new(), + sound_mgr: SoundMgr::new(), } } @@ -115,7 +120,7 @@ impl Scene { } /// Maintain data such as GPU constant buffers, models, etc. To be called once per tick. - pub fn maintain(&mut self, renderer: &mut Renderer, client: &Client) { + pub fn maintain(&mut self, renderer: &mut Renderer, audio: &mut AudioFrontend, client: &Client) { // Get player position. let player_pos = client .state() @@ -219,6 +224,9 @@ impl Scene { // Remove unused figures. self.figure_mgr.clean(client.get_tick()); + + // Maintain audio + self.sound_mgr.maintain(audio, client); } /// Render the scene using the provided `Renderer`. diff --git a/voxygen/src/scene/sound.rs b/voxygen/src/scene/sound.rs new file mode 100644 index 0000000000..117ac4317e --- /dev/null +++ b/voxygen/src/scene/sound.rs @@ -0,0 +1,53 @@ +use crate::{ + audio::AudioFrontend, +}; +use common::comp::{ + Pos, + Body, + CharacterState, + MovementState::*, +}; +use client::Client; +use vek::*; +use specs::{Entity as EcsEntity, Join}; + +pub struct SoundMgr { +} + +impl SoundMgr { + pub fn new() -> Self { + Self {} + } + + pub fn maintain(&mut self, audio: &mut AudioFrontend, client: &Client) { + let time = client.state().get_time(); + let tick = client.get_tick(); + let ecs = client.state().ecs(); + let dt = client.state().get_delta_time(); + // Get player position. + let player_pos = ecs + .read_storage::() + .get(client.entity()) + .map_or(Vec3::zero(), |pos| pos.0); + + for (entity, pos, body, character) in ( + &ecs.entities(), + &ecs.read_storage::(), + &ecs.read_storage::(), + ecs.read_storage::().maybe(), + ) + .join() + { + if let Body::Humanoid(_) = body { + let character = match character { + Some(c) => c, + _ => continue, + }; + if let Run = &character.movement { + let rand_step = (rand::random::() % 7) + 1; + audio.play_sound(format!("voxygen.audio.footsteps.stepdirt_{}", rand_step)); + } + } + } + } +} diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index a3192f51b3..53b889f669 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -389,7 +389,7 @@ impl PlayState for SessionState { // Maintain the scene. self.scene - .maintain(global_state.window.renderer_mut(), &self.client.borrow()); + .maintain(global_state.window.renderer_mut(), &mut global_state.audio, &self.client.borrow()); // Render the session. self.render(global_state.window.renderer_mut()); From fcb141a1604158495a3e8f51433cc12843a7a307 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Sat, 31 Aug 2019 20:24:35 -0600 Subject: [PATCH 07/19] Add delay to walking sounds --- voxygen/src/scene/sound.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/voxygen/src/scene/sound.rs b/voxygen/src/scene/sound.rs index 117ac4317e..927cfde9a3 100644 --- a/voxygen/src/scene/sound.rs +++ b/voxygen/src/scene/sound.rs @@ -10,13 +10,22 @@ use common::comp::{ use client::Client; use vek::*; use specs::{Entity as EcsEntity, Join}; +use hashbrown::HashMap; +use std::{f32, time::Instant}; + +pub struct AnimState { + last_step_sound: Instant, +} pub struct SoundMgr { + character_states: HashMap } impl SoundMgr { pub fn new() -> Self { - Self {} + Self { + character_states: HashMap::new(), + } } pub fn maintain(&mut self, audio: &mut AudioFrontend, client: &Client) { @@ -43,9 +52,17 @@ impl SoundMgr { Some(c) => c, _ => continue, }; + let state = self + .character_states + .entry(entity) + .or_insert_with(|| AnimState {last_step_sound: Instant::now()}); + if let Run = &character.movement { - let rand_step = (rand::random::() % 7) + 1; - audio.play_sound(format!("voxygen.audio.footsteps.stepdirt_{}", rand_step)); + if state.last_step_sound.elapsed().as_secs_f64() > 0.5 { + let rand_step = (rand::random::() % 7) + 1; + audio.play_sound(format!("voxygen.audio.footsteps.stepdirt_{}", rand_step)); + state.last_step_sound = Instant::now(); + } } } } From 00830108e9217adb18f2098b3ad11b46b712db79 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Sat, 31 Aug 2019 21:18:03 -0600 Subject: [PATCH 08/19] Add positional audio Orientation needs to be set now --- voxygen/src/audio/channel.rs | 8 ++++++++ voxygen/src/audio/mod.rs | 35 +++++++++++++++++++++++++++++++++-- voxygen/src/scene/sound.rs | 4 +++- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/voxygen/src/audio/channel.rs b/voxygen/src/audio/channel.rs index 1c4a509496..3726592dfd 100644 --- a/voxygen/src/audio/channel.rs +++ b/voxygen/src/audio/channel.rs @@ -64,6 +64,14 @@ impl Channel { self.sink.set_volume(volume); } + pub fn set_left_ear_position(&mut self, pos: [f32; 3]) { + self.sink.set_left_ear_position(pos); + } + + pub fn set_right_ear_position(&mut self, pos: [f32; 3]) { + self.sink.set_right_ear_position(pos); + } + pub fn update(&mut self, dt: f32) { match self.state { ChannelState::Playing => {}, diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index 3d4fa2c12b..2a2a040930 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -5,10 +5,16 @@ use channel::{AudioType, Channel}; use common::assets; use rodio::{Decoder, Device, SpatialSink}; +use vek::*; const LEFT_EAR : [f32; 3] = [1.0, 0.0, 0.0]; const RIGHT_EAR : [f32; 3] = [-1.0, 0.0, 0.0]; +const EAR_LEFT : Vec3 = Vec3::new(1.0, 0.0, 0.0); +const EAR_RIGHT : Vec3 = Vec3::new(-1.0, 0.0, 0.0); + +const LISTEN_DISTANCE : f32 = 25.0; + pub struct AudioFrontend { pub device: String, @@ -20,6 +26,8 @@ pub struct AudioFrontend { sfx_volume: f32, music_volume: f32, + listener_pos_left: Vec3::, + listener_pos_right: Vec3::, } impl AudioFrontend { @@ -33,6 +41,8 @@ impl AudioFrontend { next_channel_id: 0, sfx_volume: 1.0, music_volume: 1.0, + listener_pos_left: Vec3::from_slice(&LEFT_EAR), + listener_pos_right: Vec3::from_slice(&RIGHT_EAR), } } @@ -46,6 +56,8 @@ impl AudioFrontend { next_channel_id: 0, sfx_volume: 1.0, music_volume: 1.0, + listener_pos_left: Vec3::from_slice(&LEFT_EAR), + listener_pos_right: Vec3::from_slice(&RIGHT_EAR), } } @@ -67,12 +79,15 @@ impl AudioFrontend { ///```ignore ///audio.play_sound("voxygen.audio.sfx.step"); ///``` - pub fn play_sound(&mut self, sound: String) -> usize { + pub fn play_sound(&mut self, sound: String, pos: Vec3::) -> usize { let id = self.next_channel_id; self.next_channel_id += 1; if let Some(device) = &self.audio_device { - let sink = SpatialSink::new(device, [0.0, 0.0, 0.0], LEFT_EAR, RIGHT_EAR); + let pos = pos / LISTEN_DISTANCE; + let sink = SpatialSink::new(device, pos.into_array(), + self.listener_pos_left.into_array(), + self.listener_pos_right.into_array()); let file = assets::load_file(&sound, &["wav"]).unwrap(); let sound = Decoder::new(file).unwrap(); @@ -85,6 +100,21 @@ impl AudioFrontend { id } + pub fn set_listener_pos(&mut self, pos: &Vec3::) { + let pos_left = (pos.clone() + EAR_LEFT) / LISTEN_DISTANCE; + let pos_right = (pos.clone() + EAR_RIGHT) / LISTEN_DISTANCE; + + self.listener_pos_left = pos_left.clone(); + self.listener_pos_right = pos_right.clone(); + + for channel in self.channels.iter_mut() { + if channel.get_audio_type() == AudioType::Sfx { + channel.set_left_ear_position(pos_left.into_array()); + channel.set_right_ear_position(pos_right.into_array()); + } + } + } + pub fn play_music(&mut self, sound: String) -> usize { let id = self.next_channel_id; self.next_channel_id += 1; @@ -138,6 +168,7 @@ impl AudioFrontend { } } + // TODO: figure out how badly this will break things when it is called pub fn set_device(&mut self, name: String) { self.device = name.clone(); self.audio_device = get_device_raw(name); diff --git a/voxygen/src/scene/sound.rs b/voxygen/src/scene/sound.rs index 927cfde9a3..b72ae6c4c6 100644 --- a/voxygen/src/scene/sound.rs +++ b/voxygen/src/scene/sound.rs @@ -39,6 +39,8 @@ impl SoundMgr { .get(client.entity()) .map_or(Vec3::zero(), |pos| pos.0); + audio.set_listener_pos(&player_pos); + for (entity, pos, body, character) in ( &ecs.entities(), &ecs.read_storage::(), @@ -60,7 +62,7 @@ impl SoundMgr { if let Run = &character.movement { if state.last_step_sound.elapsed().as_secs_f64() > 0.5 { let rand_step = (rand::random::() % 7) + 1; - audio.play_sound(format!("voxygen.audio.footsteps.stepdirt_{}", rand_step)); + audio.play_sound(format!("voxygen.audio.footsteps.stepdirt_{}", rand_step), pos.0); state.last_step_sound = Instant::now(); } } From b5a979c82ed480b7b74a0b558594b1902dbb2d9e Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Sat, 31 Aug 2019 21:24:47 -0600 Subject: [PATCH 09/19] Change footstep rate --- voxygen/src/scene/sound.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voxygen/src/scene/sound.rs b/voxygen/src/scene/sound.rs index b72ae6c4c6..02016dc15f 100644 --- a/voxygen/src/scene/sound.rs +++ b/voxygen/src/scene/sound.rs @@ -60,7 +60,7 @@ impl SoundMgr { .or_insert_with(|| AnimState {last_step_sound: Instant::now()}); if let Run = &character.movement { - if state.last_step_sound.elapsed().as_secs_f64() > 0.5 { + if state.last_step_sound.elapsed().as_secs_f64() > 0.25 { let rand_step = (rand::random::() % 7) + 1; audio.play_sound(format!("voxygen.audio.footsteps.stepdirt_{}", rand_step), pos.0); state.last_step_sound = Instant::now(); From 65008f7d547f4a170dfe3843c0451fa82a598c85 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Sun, 1 Sep 2019 15:40:54 -0600 Subject: [PATCH 10/19] Adds proper 3d sound? Looks like loading the footstep files every time a sound is played becomes a problem rather quickly. --- voxygen/src/audio/channel.rs | 10 ++++++- voxygen/src/audio/mod.rs | 58 +++++++++++++++++++++++++----------- voxygen/src/scene/sound.rs | 11 ++++--- 3 files changed, 57 insertions(+), 22 deletions(-) diff --git a/voxygen/src/audio/channel.rs b/voxygen/src/audio/channel.rs index 3726592dfd..8517a2f326 100644 --- a/voxygen/src/audio/channel.rs +++ b/voxygen/src/audio/channel.rs @@ -1,5 +1,6 @@ use rodio::SpatialSink; use crate::audio::fader::Fader; +use vek::*; #[derive(PartialEq, Clone, Copy)] pub enum AudioType { @@ -20,6 +21,7 @@ pub struct Channel { audio_type: AudioType, state: ChannelState, fader: Fader, + pub pos: Vec3::, } impl Channel { @@ -30,16 +32,18 @@ impl Channel { audio_type: AudioType::Music, state: ChannelState::Playing, fader: Fader::fade_in(0.0), + pos: Vec3::zero(), } } - pub fn sfx(id: usize, sink: SpatialSink) -> Self { + pub fn sfx(id: usize, sink: SpatialSink, pos: Vec3::) -> Self { Self { id, sink, audio_type: AudioType::Sfx, state: ChannelState::Playing, fader: Fader::fade_in(0.0), + pos } } @@ -64,6 +68,10 @@ impl Channel { self.sink.set_volume(volume); } + pub fn set_emitter_position(&mut self, pos: [f32; 3]) { + self.sink.set_emitter_position(pos); + } + pub fn set_left_ear_position(&mut self, pos: [f32; 3]) { self.sink.set_left_ear_position(pos); } diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index 2a2a040930..75ff3ecf49 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -13,7 +13,7 @@ const RIGHT_EAR : [f32; 3] = [-1.0, 0.0, 0.0]; const EAR_LEFT : Vec3 = Vec3::new(1.0, 0.0, 0.0); const EAR_RIGHT : Vec3 = Vec3::new(-1.0, 0.0, 0.0); -const LISTEN_DISTANCE : f32 = 25.0; +const FALLOFF : f32 = 0.13; pub struct AudioFrontend { @@ -26,8 +26,12 @@ pub struct AudioFrontend { sfx_volume: f32, music_volume: f32, - listener_pos_left: Vec3::, - listener_pos_right: Vec3::, + + listener_pos: Vec3::, + listener_ori: Vec3::, + + listener_pos_left: [f32; 3], + listener_pos_right: [f32; 3], } impl AudioFrontend { @@ -41,8 +45,10 @@ impl AudioFrontend { next_channel_id: 0, sfx_volume: 1.0, music_volume: 1.0, - listener_pos_left: Vec3::from_slice(&LEFT_EAR), - listener_pos_right: Vec3::from_slice(&RIGHT_EAR), + listener_pos: Vec3::zero(), + listener_ori: Vec3::zero(), + listener_pos_left: [0.0; 3], + listener_pos_right: [0.0; 3], } } @@ -56,8 +62,10 @@ impl AudioFrontend { next_channel_id: 0, sfx_volume: 1.0, music_volume: 1.0, - listener_pos_left: Vec3::from_slice(&LEFT_EAR), - listener_pos_right: Vec3::from_slice(&RIGHT_EAR), + listener_pos: Vec3::zero(), + listener_ori: Vec3::zero(), + listener_pos_left: [0.0; 3], + listener_pos_right: [0.0; 3], } } @@ -84,31 +92,47 @@ impl AudioFrontend { self.next_channel_id += 1; if let Some(device) = &self.audio_device { - let pos = pos / LISTEN_DISTANCE; - let sink = SpatialSink::new(device, pos.into_array(), - self.listener_pos_left.into_array(), - self.listener_pos_right.into_array()); + let calc_pos = [ + (pos.x - self.listener_pos.x) * FALLOFF, + (pos.y - self.listener_pos.y) * FALLOFF, + (pos.z - self.listener_pos.z) * FALLOFF, + ]; + let sink = SpatialSink::new(device, calc_pos, + self.listener_pos_left, + self.listener_pos_right); let file = assets::load_file(&sound, &["wav"]).unwrap(); let sound = Decoder::new(file).unwrap(); sink.append(sound); - self.channels.push(Channel::sfx(id, sink)); + self.channels.push(Channel::sfx(id, sink, pos)); } id } - pub fn set_listener_pos(&mut self, pos: &Vec3::) { - let pos_left = (pos.clone() + EAR_LEFT) / LISTEN_DISTANCE; - let pos_right = (pos.clone() + EAR_RIGHT) / LISTEN_DISTANCE; + pub fn set_listener_pos(&mut self, pos: &Vec3::, ori: &Vec3::) { + self.listener_pos = pos.clone(); + self.listener_ori = ori.normalized(); - self.listener_pos_left = pos_left.clone(); - self.listener_pos_right = pos_right.clone(); + let up = Vec3::new(0.0, 0.0, 1.0); + + let pos_left = up.cross(self.listener_ori.clone()).normalized(); + dbg!(pos_left); + let pos_right = self.listener_ori.cross(up.clone()).normalized(); + dbg!(pos_right); + + self.listener_pos_left = pos_left.into_array(); + self.listener_pos_right = pos_right.into_array(); for channel in self.channels.iter_mut() { if channel.get_audio_type() == AudioType::Sfx { + channel.set_emitter_position([ + (channel.pos.x - self.listener_pos.x) * FALLOFF, + (channel.pos.y - self.listener_pos.y) * FALLOFF, + (channel.pos.z - self.listener_pos.z) * FALLOFF, + ]); channel.set_left_ear_position(pos_left.into_array()); channel.set_right_ear_position(pos_right.into_array()); } diff --git a/voxygen/src/scene/sound.rs b/voxygen/src/scene/sound.rs index 02016dc15f..bfc1193c65 100644 --- a/voxygen/src/scene/sound.rs +++ b/voxygen/src/scene/sound.rs @@ -3,6 +3,7 @@ use crate::{ }; use common::comp::{ Pos, + Ori, Body, CharacterState, MovementState::*, @@ -29,17 +30,19 @@ impl SoundMgr { } pub fn maintain(&mut self, audio: &mut AudioFrontend, client: &Client) { - let time = client.state().get_time(); - let tick = client.get_tick(); let ecs = client.state().ecs(); - let dt = client.state().get_delta_time(); // Get player position. let player_pos = ecs .read_storage::() .get(client.entity()) .map_or(Vec3::zero(), |pos| pos.0); - audio.set_listener_pos(&player_pos); + let player_ori = ecs + .read_storage::() + .get(client.entity()) + .map_or(Vec3::zero(), |pos| pos.0); + + audio.set_listener_pos(&player_pos, &player_ori); for (entity, pos, body, character) in ( &ecs.entities(), From 529cb40dc475c9bd6a47e3b42d7bb58282c20065 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Sun, 1 Sep 2019 17:00:12 -0600 Subject: [PATCH 11/19] Add soundcache Still getting the stuttering. Time to rethink channels --- voxygen/src/audio/channel.rs | 22 ++++++++++++-- voxygen/src/audio/mod.rs | 23 +++++--------- voxygen/src/audio/soundcache.rs | 53 +++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 19 deletions(-) create mode 100644 voxygen/src/audio/soundcache.rs diff --git a/voxygen/src/audio/channel.rs b/voxygen/src/audio/channel.rs index 8517a2f326..cf680177b9 100644 --- a/voxygen/src/audio/channel.rs +++ b/voxygen/src/audio/channel.rs @@ -1,4 +1,6 @@ -use rodio::SpatialSink; +use rodio::{SpatialSink, Decoder, Device}; +use std::io::BufReader; +use std::fs::File; use crate::audio::fader::Fader; use vek::*; @@ -10,6 +12,9 @@ pub enum AudioType { #[derive(PartialEq, Clone, Copy)] enum ChannelState { + Init, + ToPlay, + Loading, Playing, Stopping, Stopped, @@ -22,10 +27,16 @@ pub struct Channel { state: ChannelState, fader: Fader, pub pos: Vec3::, + // sound_cache: Option<&SoundCache>, } impl Channel { - pub fn music(id: usize, sink: SpatialSink) -> Self { + pub fn music(id: usize, device: &Device, bufr: BufReader) -> Self { + let sink = SpatialSink::new(device, [0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [-1.0, 0.0, 0.0]); + let sound = Decoder::new(bufr).unwrap(); + + sink.append(sound); + Self { id, sink, @@ -33,6 +44,7 @@ impl Channel { state: ChannelState::Playing, fader: Fader::fade_in(0.0), pos: Vec3::zero(), + // sound_cache: None, } } @@ -43,7 +55,8 @@ impl Channel { audio_type: AudioType::Sfx, state: ChannelState::Playing, fader: Fader::fade_in(0.0), - pos + pos, + // sound_cache, } } @@ -82,6 +95,9 @@ impl Channel { pub fn update(&mut self, dt: f32) { match self.state { + ChannelState::Init | ChannelState::ToPlay | ChannelState::Loading => { + + } ChannelState::Playing => {}, ChannelState::Stopping => { self.fader.update(dt); diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index 75ff3ecf49..d130d30856 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -1,18 +1,14 @@ pub mod fader; pub mod channel; +pub mod soundcache; use fader::Fader; use channel::{AudioType, Channel}; +use soundcache::SoundCache; use common::assets; use rodio::{Decoder, Device, SpatialSink}; use vek::*; -const LEFT_EAR : [f32; 3] = [1.0, 0.0, 0.0]; -const RIGHT_EAR : [f32; 3] = [-1.0, 0.0, 0.0]; - -const EAR_LEFT : Vec3 = Vec3::new(1.0, 0.0, 0.0); -const EAR_RIGHT : Vec3 = Vec3::new(-1.0, 0.0, 0.0); - const FALLOFF : f32 = 0.13; @@ -20,6 +16,7 @@ pub struct AudioFrontend { pub device: String, pub device_list: Vec, audio_device: Option, + sound_cache: SoundCache, channels: Vec, next_channel_id: usize, @@ -41,6 +38,7 @@ impl AudioFrontend { device: device.clone(), device_list: list_devices(), audio_device: get_device_raw(device), + sound_cache: SoundCache::new(), channels: Vec::new(), next_channel_id: 0, sfx_volume: 1.0, @@ -58,6 +56,7 @@ impl AudioFrontend { device: "none".to_string(), device_list: list_devices(), audio_device: None, + sound_cache: SoundCache::new(), channels: Vec::new(), next_channel_id: 0, sfx_volume: 1.0, @@ -101,8 +100,7 @@ impl AudioFrontend { self.listener_pos_left, self.listener_pos_right); - let file = assets::load_file(&sound, &["wav"]).unwrap(); - let sound = Decoder::new(file).unwrap(); + let sound = self.sound_cache.load_sound(sound); sink.append(sound); @@ -119,9 +117,7 @@ impl AudioFrontend { let up = Vec3::new(0.0, 0.0, 1.0); let pos_left = up.cross(self.listener_ori.clone()).normalized(); - dbg!(pos_left); let pos_right = self.listener_ori.cross(up.clone()).normalized(); - dbg!(pos_right); self.listener_pos_left = pos_left.into_array(); self.listener_pos_right = pos_right.into_array(); @@ -144,14 +140,9 @@ impl AudioFrontend { self.next_channel_id += 1; if let Some(device) = &self.audio_device { - let sink = SpatialSink::new(device, [0.0, 0.0, 0.0], LEFT_EAR, RIGHT_EAR); - let file = assets::load_file(&sound, &["ogg"]).unwrap(); - let sound = Decoder::new(file).unwrap(); - sink.append(sound); - - self.channels.push(Channel::music(id, sink)); + self.channels.push(Channel::music(id, device, file)); } id diff --git a/voxygen/src/audio/soundcache.rs b/voxygen/src/audio/soundcache.rs new file mode 100644 index 0000000000..3ed26e33a3 --- /dev/null +++ b/voxygen/src/audio/soundcache.rs @@ -0,0 +1,53 @@ +use rodio; +use hashbrown::HashMap; +use std::io; +use std::io::Read; +use std::convert::AsRef; +use common::assets; +use std::sync::Arc; + +// Implementation of sound taken from this github issue: +// https://github.com/RustAudio/rodio/issues/141 +pub struct Sound (Arc>); + +impl AsRef<[u8]> for Sound { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +impl Sound { + pub fn load(filename: &str) -> Result { + let mut file = assets::load_file(filename, &["wav"])?; + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; + Ok(Sound(Arc::new(buf))) + } + + pub fn cursor(&self) -> io::Cursor { + io::Cursor::new(Sound(self.0.clone())) + } + + pub fn decoder(&self) -> rodio::Decoder> { + rodio::Decoder::new(self.cursor()).unwrap() + } +} + +pub struct SoundCache { + sounds: HashMap, +} + +impl SoundCache { + pub fn new() -> Self { + Self { + sounds: HashMap::new() + } + } + + pub fn load_sound(&mut self, name: String) -> rodio::Decoder> { + self.sounds + .entry(name.clone()) + .or_insert(Sound::load(&name).unwrap()) + .decoder() + } +} From 2bca20cf696b1148de876691fd8f488a7952f25c Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Thu, 5 Sep 2019 03:03:24 -0600 Subject: [PATCH 12/19] Get sound effects working --- voxygen/src/audio/channel.rs | 35 ++++++++++++++++++++--- voxygen/src/audio/mod.rs | 54 +++++++++++++++++++++++------------- voxygen/src/main.rs | 2 +- voxygen/src/menu/main/mod.rs | 2 -- 4 files changed, 66 insertions(+), 27 deletions(-) diff --git a/voxygen/src/audio/channel.rs b/voxygen/src/audio/channel.rs index cf680177b9..ea918a54b0 100644 --- a/voxygen/src/audio/channel.rs +++ b/voxygen/src/audio/channel.rs @@ -1,4 +1,4 @@ -use rodio::{SpatialSink, Decoder, Device}; +use rodio::{SpatialSink, Decoder, Device, Source, Sample}; use std::io::BufReader; use std::fs::File; use crate::audio::fader::Fader; @@ -8,6 +8,7 @@ use vek::*; pub enum AudioType { Sfx, Music, + None, } #[derive(PartialEq, Clone, Copy)] @@ -27,10 +28,22 @@ pub struct Channel { state: ChannelState, fader: Fader, pub pos: Vec3::, - // sound_cache: Option<&SoundCache>, } +// TODO: Implement asynchronous loading impl Channel { + /// Create an empty channel for future use + pub fn new(device: &Device) -> Self { + Self { + id: 0, + sink: SpatialSink::new(device, [0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [-1.0, 0.0, 0.0]), + audio_type: AudioType::None, + state: ChannelState::Stopped, + fader: Fader::fade_in(0.0), + pos: Vec3::zero(), + } + } + pub fn music(id: usize, device: &Device, bufr: BufReader) -> Self { let sink = SpatialSink::new(device, [0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [-1.0, 0.0, 0.0]); let sound = Decoder::new(bufr).unwrap(); @@ -44,7 +57,6 @@ impl Channel { state: ChannelState::Playing, fader: Fader::fade_in(0.0), pos: Vec3::zero(), - // sound_cache: None, } } @@ -56,10 +68,20 @@ impl Channel { state: ChannelState::Playing, fader: Fader::fade_in(0.0), pos, - // sound_cache, } } + pub fn play(&mut self, source: S) + where + S: Source + Send + 'static, + S::Item: Sample, + S::Item: Send, + ::Item: std::fmt::Debug, + { + self.state = ChannelState::Playing; + self.sink.append(source); + } + pub fn is_done(&self) -> bool { self.sink.empty() || self.state == ChannelState::Stopped } @@ -73,6 +95,10 @@ impl Channel { self.id } + pub fn set_id(&mut self, new_id: usize) { + self.id = new_id; + } + pub fn get_audio_type(&self) -> AudioType { self.audio_type } @@ -102,6 +128,7 @@ impl Channel { ChannelState::Stopping => { self.fader.update(dt); self.sink.set_volume(self.fader.get_volume()); + if self.fader.is_finished() { self.state = ChannelState::Stopped; } diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index d130d30856..00c079fbb6 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -33,14 +33,21 @@ pub struct AudioFrontend { impl AudioFrontend { /// Construct with given device - pub fn new(device: String) -> Self { + pub fn new(device: String, channel_num: usize) -> Self { + let mut channels = Vec::with_capacity(channel_num); + let audio_device = get_device_raw(&device); + if let Some(audio_device) = &audio_device { + for i in (0..channel_num) { + channels.push(Channel::new(&audio_device)); + } + } Self { device: device.clone(), device_list: list_devices(), - audio_device: get_device_raw(device), + audio_device, sound_cache: SoundCache::new(), - channels: Vec::new(), - next_channel_id: 0, + channels: channels, + next_channel_id: 1, sfx_volume: 1.0, music_volume: 1.0, listener_pos: Vec3::zero(), @@ -58,7 +65,7 @@ impl AudioFrontend { audio_device: None, sound_cache: SoundCache::new(), channels: Vec::new(), - next_channel_id: 0, + next_channel_id: 1, sfx_volume: 1.0, music_volume: 1.0, listener_pos: Vec3::zero(), @@ -70,18 +77,15 @@ impl AudioFrontend { /// Maintain audio pub fn maintain(&mut self, dt: f32) { - let mut stopped_channels = Vec::::new(); for (i, channel) in self.channels.iter_mut().enumerate() { channel.update(dt); - if channel.is_done() { - stopped_channels.push(i); - } - } - for i in stopped_channels.iter().rev() { - self.channels.remove(*i); } } + pub fn get_channel(&mut self) -> Option<&mut Channel> { + self.channels.iter_mut().find(|c| c.is_done()) + } + /// Play specfied sound file. ///```ignore ///audio.play_sound("voxygen.audio.sfx.step"); @@ -96,15 +100,21 @@ impl AudioFrontend { (pos.y - self.listener_pos.y) * FALLOFF, (pos.z - self.listener_pos.z) * FALLOFF, ]; - let sink = SpatialSink::new(device, calc_pos, - self.listener_pos_left, - self.listener_pos_right); let sound = self.sound_cache.load_sound(sound); - sink.append(sound); + let left_ear = self.listener_pos_left; + let right_ear = self.listener_pos_right; - self.channels.push(Channel::sfx(id, sink, pos)); + if let Some(channel) = self.get_channel() { + channel.set_id(id); + channel.set_emitter_position(calc_pos); + channel.set_left_ear_position(left_ear); + channel.set_right_ear_position(right_ear); + channel.play(sound); + } else { + println!("No available channels!"); + } } id @@ -141,8 +151,12 @@ impl AudioFrontend { if let Some(device) = &self.audio_device { let file = assets::load_file(&sound, &["ogg"]).unwrap(); + let sound = Decoder::new(file).unwrap(); - self.channels.push(Channel::music(id, device, file)); + if let Some(channel) = self.get_channel() { + channel.set_id(id); + channel.play(sound); + } } id @@ -186,7 +200,7 @@ impl AudioFrontend { // TODO: figure out how badly this will break things when it is called pub fn set_device(&mut self, name: String) { self.device = name.clone(); - self.audio_device = get_device_raw(name); + self.audio_device = get_device_raw(&name); } } @@ -230,6 +244,6 @@ fn list_devices_raw() -> Vec { rodio::output_devices().collect() } -fn get_device_raw(device: String) -> Option { +fn get_device_raw(device: &str) -> Option { rodio::output_devices().find(|d| d.name() == device) } diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs index 49d6c7ac7d..07e7f26e0d 100644 --- a/voxygen/src/main.rs +++ b/voxygen/src/main.rs @@ -114,7 +114,7 @@ fn main() { None => audio::get_default_device(), }; let audio = if settings.audio.audio_on { - AudioFrontend::new(audio_device) + AudioFrontend::new(audio_device, 16) } else { AudioFrontend::no_audio() }; diff --git a/voxygen/src/menu/main/mod.rs b/voxygen/src/menu/main/mod.rs index 04f7c2a111..884f136de1 100644 --- a/voxygen/src/menu/main/mod.rs +++ b/voxygen/src/menu/main/mod.rs @@ -34,8 +34,6 @@ impl PlayState for MainMenuState { // Used for client creation. let mut client_init: Option = None; - let music = global_state.audio.play_music("voxygen.audio.soundtrack.veloren_title_tune-3".to_string()); - loop { // Handle window events. for event in global_state.window.fetch_events() { From 8e5f993a5baa7dd2d6216b5fe243f6db93e15d08 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Thu, 5 Sep 2019 03:11:18 -0600 Subject: [PATCH 13/19] Format files --- voxygen/src/audio/channel.rs | 24 +++++++++++------------- voxygen/src/audio/fader.rs | 11 +++++++---- voxygen/src/audio/mod.rs | 15 +++++++-------- voxygen/src/audio/soundcache.rs | 10 +++++----- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/voxygen/src/audio/channel.rs b/voxygen/src/audio/channel.rs index ea918a54b0..5adaff6e7d 100644 --- a/voxygen/src/audio/channel.rs +++ b/voxygen/src/audio/channel.rs @@ -1,7 +1,7 @@ -use rodio::{SpatialSink, Decoder, Device, Source, Sample}; -use std::io::BufReader; -use std::fs::File; use crate::audio::fader::Fader; +use rodio::{Decoder, Device, Sample, Source, SpatialSink}; +use std::fs::File; +use std::io::BufReader; use vek::*; #[derive(PartialEq, Clone, Copy)] @@ -27,7 +27,7 @@ pub struct Channel { audio_type: AudioType, state: ChannelState, fader: Fader, - pub pos: Vec3::, + pub pos: Vec3, } // TODO: Implement asynchronous loading @@ -60,7 +60,7 @@ impl Channel { } } - pub fn sfx(id: usize, sink: SpatialSink, pos: Vec3::) -> Self { + pub fn sfx(id: usize, sink: SpatialSink, pos: Vec3) -> Self { Self { id, sink, @@ -76,7 +76,7 @@ impl Channel { S: Source + Send + 'static, S::Item: Sample, S::Item: Send, - ::Item: std::fmt::Debug, + ::Item: std::fmt::Debug, { self.state = ChannelState::Playing; self.sink.append(source); @@ -121,19 +121,17 @@ impl Channel { pub fn update(&mut self, dt: f32) { match self.state { - ChannelState::Init | ChannelState::ToPlay | ChannelState::Loading => { - - } - ChannelState::Playing => {}, - ChannelState::Stopping => { + ChannelState::Init | ChannelState::ToPlay | ChannelState::Loading => {} + ChannelState::Playing => {} + ChannelState::Stopping => { self.fader.update(dt); self.sink.set_volume(self.fader.get_volume()); if self.fader.is_finished() { self.state = ChannelState::Stopped; } - }, - ChannelState::Stopped => {}, + } + ChannelState::Stopped => {} } } } diff --git a/voxygen/src/audio/fader.rs b/voxygen/src/audio/fader.rs index b0e7fe9709..5adf960c5a 100644 --- a/voxygen/src/audio/fader.rs +++ b/voxygen/src/audio/fader.rs @@ -1,15 +1,14 @@ - #[derive(PartialEq, Clone, Copy)] pub struct Fader { length: f32, running_time: f32, volume_from: f32, volume_to: f32, - is_running: bool + is_running: bool, } fn lerp(t: f32, a: f32, b: f32) -> f32 { - (1.0 - t) * a + t * b + (1.0 - t) * a + t * b } impl Fader { @@ -54,7 +53,11 @@ impl Fader { } pub fn get_volume(&self) -> f32 { - lerp(self.running_time / self.length, self.volume_from, self.volume_to) + lerp( + self.running_time / self.length, + self.volume_from, + self.volume_to, + ) } pub fn is_finished(&self) -> bool { diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index 00c079fbb6..ba63da5250 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -1,16 +1,15 @@ -pub mod fader; pub mod channel; +pub mod fader; pub mod soundcache; -use fader::Fader; use channel::{AudioType, Channel}; +use fader::Fader; use soundcache::SoundCache; use common::assets; use rodio::{Decoder, Device, SpatialSink}; use vek::*; -const FALLOFF : f32 = 0.13; - +const FALLOFF: f32 = 0.13; pub struct AudioFrontend { pub device: String, @@ -24,8 +23,8 @@ pub struct AudioFrontend { sfx_volume: f32, music_volume: f32, - listener_pos: Vec3::, - listener_ori: Vec3::, + listener_pos: Vec3, + listener_ori: Vec3, listener_pos_left: [f32; 3], listener_pos_right: [f32; 3], @@ -90,7 +89,7 @@ impl AudioFrontend { ///```ignore ///audio.play_sound("voxygen.audio.sfx.step"); ///``` - pub fn play_sound(&mut self, sound: String, pos: Vec3::) -> usize { + pub fn play_sound(&mut self, sound: String, pos: Vec3) -> usize { let id = self.next_channel_id; self.next_channel_id += 1; @@ -120,7 +119,7 @@ impl AudioFrontend { id } - pub fn set_listener_pos(&mut self, pos: &Vec3::, ori: &Vec3::) { + pub fn set_listener_pos(&mut self, pos: &Vec3, ori: &Vec3) { self.listener_pos = pos.clone(); self.listener_ori = ori.normalized(); diff --git a/voxygen/src/audio/soundcache.rs b/voxygen/src/audio/soundcache.rs index 3ed26e33a3..451761c2a3 100644 --- a/voxygen/src/audio/soundcache.rs +++ b/voxygen/src/audio/soundcache.rs @@ -1,14 +1,14 @@ -use rodio; +use common::assets; use hashbrown::HashMap; +use rodio; +use std::convert::AsRef; use std::io; use std::io::Read; -use std::convert::AsRef; -use common::assets; use std::sync::Arc; // Implementation of sound taken from this github issue: // https://github.com/RustAudio/rodio/issues/141 -pub struct Sound (Arc>); +pub struct Sound(Arc>); impl AsRef<[u8]> for Sound { fn as_ref(&self) -> &[u8] { @@ -40,7 +40,7 @@ pub struct SoundCache { impl SoundCache { pub fn new() -> Self { Self { - sounds: HashMap::new() + sounds: HashMap::new(), } } From 3fe12ee85fe03bea6e82e224a80c7193b3778756 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Fri, 6 Sep 2019 04:06:26 -0600 Subject: [PATCH 14/19] Fix settings move --- voxygen/src/main.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs index 07e7f26e0d..a69960ca3b 100644 --- a/voxygen/src/main.rs +++ b/voxygen/src/main.rs @@ -31,10 +31,7 @@ pub mod window; // Reexports pub use crate::error::Error; -use crate::{ - audio::AudioFrontend, menu::main::MainMenuState, settings::Settings, - window::Window, -}; +use crate::{audio::AudioFrontend, menu::main::MainMenuState, settings::Settings, window::Window}; use heaptrack::track_mem; use log::{self, debug, error, info}; @@ -103,12 +100,10 @@ lazy_static! { fn main() { // Load the settings let settings = Settings::load(); -<<<<<<< HEAD // Save settings to add new fields or create the file if it is not already there if let Err(err) = settings.save_to_file() { panic!("Failed to save settings: {:?}", err); } -======= let audio_device = match &settings.audio.audio_device { Some(d) => d.to_string(), None => audio::get_default_device(), @@ -124,7 +119,7 @@ fn main() { window: Window::new(&settings).expect("Failed to create window!"), settings, }; ->>>>>>> Revamp AudioFrontend + let settings = &global_state.settings; // Initialize logging. let term_log_level = std::env::var_os("VOXYGEN_LOG") From 57fe89e5c8e331fee6d5fb97233f4d0b581b6e2d Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Fri, 6 Sep 2019 04:25:17 -0600 Subject: [PATCH 15/19] Fix warnings --- voxygen/src/audio/channel.rs | 8 ++++---- voxygen/src/audio/mod.rs | 10 +++++----- voxygen/src/menu/main/mod.rs | 2 +- voxygen/src/scene/sound.rs | 31 ++++++++++++++----------------- 4 files changed, 24 insertions(+), 27 deletions(-) diff --git a/voxygen/src/audio/channel.rs b/voxygen/src/audio/channel.rs index 5adaff6e7d..d9a341324c 100644 --- a/voxygen/src/audio/channel.rs +++ b/voxygen/src/audio/channel.rs @@ -13,9 +13,9 @@ pub enum AudioType { #[derive(PartialEq, Clone, Copy)] enum ChannelState { - Init, - ToPlay, - Loading, + // Init, + // ToPlay, + // Loading, Playing, Stopping, Stopped, @@ -121,7 +121,7 @@ impl Channel { pub fn update(&mut self, dt: f32) { match self.state { - ChannelState::Init | ChannelState::ToPlay | ChannelState::Loading => {} + // ChannelState::Init | ChannelState::ToPlay | ChannelState::Loading => {} ChannelState::Playing => {} ChannelState::Stopping => { self.fader.update(dt); diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index ba63da5250..7745398a87 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -6,7 +6,7 @@ use fader::Fader; use soundcache::SoundCache; use common::assets; -use rodio::{Decoder, Device, SpatialSink}; +use rodio::{Decoder, Device}; use vek::*; const FALLOFF: f32 = 0.13; @@ -36,7 +36,7 @@ impl AudioFrontend { let mut channels = Vec::with_capacity(channel_num); let audio_device = get_device_raw(&device); if let Some(audio_device) = &audio_device { - for i in (0..channel_num) { + for _i in 0..channel_num { channels.push(Channel::new(&audio_device)); } } @@ -76,7 +76,7 @@ impl AudioFrontend { /// Maintain audio pub fn maintain(&mut self, dt: f32) { - for (i, channel) in self.channels.iter_mut().enumerate() { + for channel in self.channels.iter_mut() { channel.update(dt); } } @@ -93,7 +93,7 @@ impl AudioFrontend { let id = self.next_channel_id; self.next_channel_id += 1; - if let Some(device) = &self.audio_device { + if let Some(_) = &self.audio_device { let calc_pos = [ (pos.x - self.listener_pos.x) * FALLOFF, (pos.y - self.listener_pos.y) * FALLOFF, @@ -148,7 +148,7 @@ impl AudioFrontend { let id = self.next_channel_id; self.next_channel_id += 1; - if let Some(device) = &self.audio_device { + if let Some(_) = &self.audio_device { let file = assets::load_file(&sound, &["ogg"]).unwrap(); let sound = Decoder::new(file).unwrap(); diff --git a/voxygen/src/menu/main/mod.rs b/voxygen/src/menu/main/mod.rs index 884f136de1..6b8bbca182 100644 --- a/voxygen/src/menu/main/mod.rs +++ b/voxygen/src/menu/main/mod.rs @@ -3,7 +3,7 @@ mod start_singleplayer; mod ui; use super::char_selection::CharSelectionState; -use crate::{audio::fader::Fader, window::Event, Direction, GlobalState, PlayState, PlayStateResult}; +use crate::{window::Event, Direction, GlobalState, PlayState, PlayStateResult}; use client_init::{ClientInit, Error as InitError}; use common::{clock::Clock, comp}; use log::warn; diff --git a/voxygen/src/scene/sound.rs b/voxygen/src/scene/sound.rs index bfc1193c65..26f7ab04e4 100644 --- a/voxygen/src/scene/sound.rs +++ b/voxygen/src/scene/sound.rs @@ -1,31 +1,23 @@ -use crate::{ - audio::AudioFrontend, -}; -use common::comp::{ - Pos, - Ori, - Body, - CharacterState, - MovementState::*, -}; +use crate::audio::AudioFrontend; use client::Client; -use vek::*; -use specs::{Entity as EcsEntity, Join}; +use common::comp::{Body, CharacterState, MovementState::*, Ori, Pos}; use hashbrown::HashMap; -use std::{f32, time::Instant}; +use specs::{Entity as EcsEntity, Join}; +use std::time::Instant; +use vek::*; pub struct AnimState { last_step_sound: Instant, } pub struct SoundMgr { - character_states: HashMap + character_states: HashMap, } impl SoundMgr { pub fn new() -> Self { Self { - character_states: HashMap::new(), + character_states: HashMap::new(), } } @@ -60,12 +52,17 @@ impl SoundMgr { let state = self .character_states .entry(entity) - .or_insert_with(|| AnimState {last_step_sound: Instant::now()}); + .or_insert_with(|| AnimState { + last_step_sound: Instant::now(), + }); if let Run = &character.movement { if state.last_step_sound.elapsed().as_secs_f64() > 0.25 { let rand_step = (rand::random::() % 7) + 1; - audio.play_sound(format!("voxygen.audio.footsteps.stepdirt_{}", rand_step), pos.0); + audio.play_sound( + format!("voxygen.audio.footsteps.stepdirt_{}", rand_step), + pos.0, + ); state.last_step_sound = Instant::now(); } } From 675d72a3cea340cb01db8362558a4b74dfa63494 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Fri, 6 Sep 2019 04:36:42 -0600 Subject: [PATCH 16/19] Code cleanup --- voxygen/src/audio/mod.rs | 20 +++++++------------- voxygen/src/audio/soundcache.rs | 6 +++--- voxygen/src/scene/sound.rs | 2 +- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index 7745398a87..ee86873d33 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -89,16 +89,12 @@ impl AudioFrontend { ///```ignore ///audio.play_sound("voxygen.audio.sfx.step"); ///``` - pub fn play_sound(&mut self, sound: String, pos: Vec3) -> usize { + pub fn play_sound(&mut self, sound: &str, pos: Vec3) -> usize { let id = self.next_channel_id; self.next_channel_id += 1; if let Some(_) = &self.audio_device { - let calc_pos = [ - (pos.x - self.listener_pos.x) * FALLOFF, - (pos.y - self.listener_pos.y) * FALLOFF, - (pos.z - self.listener_pos.z) * FALLOFF, - ]; + let calc_pos = ((pos - self.listener_pos) * FALLOFF).into_array(); let sound = self.sound_cache.load_sound(sound); @@ -112,7 +108,7 @@ impl AudioFrontend { channel.set_right_ear_position(right_ear); channel.play(sound); } else { - println!("No available channels!"); + log::warn!("No available channels!"); } } @@ -133,18 +129,16 @@ impl AudioFrontend { for channel in self.channels.iter_mut() { if channel.get_audio_type() == AudioType::Sfx { - channel.set_emitter_position([ - (channel.pos.x - self.listener_pos.x) * FALLOFF, - (channel.pos.y - self.listener_pos.y) * FALLOFF, - (channel.pos.z - self.listener_pos.z) * FALLOFF, - ]); + channel.set_emitter_position( + ((channel.pos - self.listener_pos) * FALLOFF).into_array(), + ); channel.set_left_ear_position(pos_left.into_array()); channel.set_right_ear_position(pos_right.into_array()); } } } - pub fn play_music(&mut self, sound: String) -> usize { + pub fn play_music(&mut self, sound: &str) -> usize { let id = self.next_channel_id; self.next_channel_id += 1; diff --git a/voxygen/src/audio/soundcache.rs b/voxygen/src/audio/soundcache.rs index 451761c2a3..4af0ce9a9a 100644 --- a/voxygen/src/audio/soundcache.rs +++ b/voxygen/src/audio/soundcache.rs @@ -44,10 +44,10 @@ impl SoundCache { } } - pub fn load_sound(&mut self, name: String) -> rodio::Decoder> { + pub fn load_sound(&mut self, name: &str) -> rodio::Decoder> { self.sounds - .entry(name.clone()) - .or_insert(Sound::load(&name).unwrap()) + .entry(name.to_string()) + .or_insert(Sound::load(name).unwrap()) .decoder() } } diff --git a/voxygen/src/scene/sound.rs b/voxygen/src/scene/sound.rs index 26f7ab04e4..0a9d5d6e09 100644 --- a/voxygen/src/scene/sound.rs +++ b/voxygen/src/scene/sound.rs @@ -60,7 +60,7 @@ impl SoundMgr { if state.last_step_sound.elapsed().as_secs_f64() > 0.25 { let rand_step = (rand::random::() % 7) + 1; audio.play_sound( - format!("voxygen.audio.footsteps.stepdirt_{}", rand_step), + &format!("voxygen.audio.footsteps.stepdirt_{}", rand_step), pos.0, ); state.last_step_sound = Instant::now(); From 059d968499e307df54d0dc0bc2f76279486ea6b5 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Fri, 6 Sep 2019 04:38:02 -0600 Subject: [PATCH 17/19] Cargo fmt --- voxygen/src/scene/mod.rs | 15 ++++++++++----- voxygen/src/session.rs | 7 +++++-- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index 6936b66f9e..424345d204 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -1,21 +1,21 @@ pub mod camera; pub mod figure; -pub mod terrain; pub mod sound; +pub mod terrain; use self::{ camera::{Camera, CameraMode}, figure::FigureMgr, - terrain::Terrain, sound::SoundMgr, + terrain::Terrain, }; use crate::{ + audio::AudioFrontend, render::{ create_pp_mesh, create_skybox_mesh, Consts, Globals, Light, Model, PostProcessLocals, PostProcessPipeline, Renderer, SkyboxLocals, SkyboxPipeline, }, window::Event, - audio::AudioFrontend, }; use client::Client; use common::{comp, terrain::BlockKind, vol::ReadVol}; @@ -75,7 +75,7 @@ impl Scene { terrain: Terrain::new(renderer), loaded_distance: 0.0, figure_mgr: FigureMgr::new(), - sound_mgr: SoundMgr::new(), + sound_mgr: SoundMgr::new(), } } @@ -120,7 +120,12 @@ impl Scene { } /// Maintain data such as GPU constant buffers, models, etc. To be called once per tick. - pub fn maintain(&mut self, renderer: &mut Renderer, audio: &mut AudioFrontend, client: &Client) { + pub fn maintain( + &mut self, + renderer: &mut Renderer, + audio: &mut AudioFrontend, + client: &Client, + ) { // Get player position. let player_pos = client .state() diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 53b889f669..9710e831ab 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -388,8 +388,11 @@ impl PlayState for SessionState { } // Maintain the scene. - self.scene - .maintain(global_state.window.renderer_mut(), &mut global_state.audio, &self.client.borrow()); + self.scene.maintain( + global_state.window.renderer_mut(), + &mut global_state.audio, + &self.client.borrow(), + ); // Render the session. self.render(global_state.window.renderer_mut()); From 02af86d2d6f720e1ec6988612dc95de459fa610e Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Fri, 6 Sep 2019 04:44:15 -0600 Subject: [PATCH 18/19] Change ear pos to Vec3 --- voxygen/src/audio/mod.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index ee86873d33..e723889319 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -26,8 +26,8 @@ pub struct AudioFrontend { listener_pos: Vec3, listener_ori: Vec3, - listener_pos_left: [f32; 3], - listener_pos_right: [f32; 3], + listener_ear_left: Vec3, + listener_ear_right: Vec3, } impl AudioFrontend { @@ -51,8 +51,8 @@ impl AudioFrontend { music_volume: 1.0, listener_pos: Vec3::zero(), listener_ori: Vec3::zero(), - listener_pos_left: [0.0; 3], - listener_pos_right: [0.0; 3], + listener_ear_left: Vec3::zero(), + listener_ear_right: Vec3::zero(), } } @@ -69,8 +69,8 @@ impl AudioFrontend { music_volume: 1.0, listener_pos: Vec3::zero(), listener_ori: Vec3::zero(), - listener_pos_left: [0.0; 3], - listener_pos_right: [0.0; 3], + listener_ear_left: Vec3::zero(), + listener_ear_right: Vec3::zero(), } } @@ -98,8 +98,8 @@ impl AudioFrontend { let sound = self.sound_cache.load_sound(sound); - let left_ear = self.listener_pos_left; - let right_ear = self.listener_pos_right; + let left_ear = self.listener_ear_left.into_array(); + let right_ear = self.listener_ear_right.into_array(); if let Some(channel) = self.get_channel() { channel.set_id(id); @@ -124,8 +124,8 @@ impl AudioFrontend { let pos_left = up.cross(self.listener_ori.clone()).normalized(); let pos_right = self.listener_ori.cross(up.clone()).normalized(); - self.listener_pos_left = pos_left.into_array(); - self.listener_pos_right = pos_right.into_array(); + self.listener_ear_left = pos_left; + self.listener_ear_right = pos_right; for channel in self.channels.iter_mut() { if channel.get_audio_type() == AudioType::Sfx { From 7f27385f95d5fcc471b57e4c60f241762ed7c2df Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Fri, 6 Sep 2019 05:02:29 -0600 Subject: [PATCH 19/19] Removed unescessary if statements --- voxygen/src/scene/sound.rs | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/voxygen/src/scene/sound.rs b/voxygen/src/scene/sound.rs index 0a9d5d6e09..96776bdf24 100644 --- a/voxygen/src/scene/sound.rs +++ b/voxygen/src/scene/sound.rs @@ -44,11 +44,7 @@ impl SoundMgr { ) .join() { - if let Body::Humanoid(_) = body { - let character = match character { - Some(c) => c, - _ => continue, - }; + if let (Body::Humanoid(_), Some(character)) = (body, character) { let state = self .character_states .entry(entity) @@ -56,15 +52,14 @@ impl SoundMgr { last_step_sound: Instant::now(), }); - if let Run = &character.movement { - if state.last_step_sound.elapsed().as_secs_f64() > 0.25 { - let rand_step = (rand::random::() % 7) + 1; - audio.play_sound( - &format!("voxygen.audio.footsteps.stepdirt_{}", rand_step), - pos.0, - ); - state.last_step_sound = Instant::now(); - } + if character.movement == Run && state.last_step_sound.elapsed().as_secs_f64() > 0.25 + { + let rand_step = (rand::random::() % 7) + 1; + audio.play_sound( + &format!("voxygen.audio.footsteps.stepdirt_{}", rand_step), + pos.0, + ); + state.last_step_sound = Instant::now(); } } }