A multiplayer VR framework w/voice chat

final commit before i fucking lose it with steam audio xD

phaz.uk 3d34f6e9 ef6de1af

verified
Changed files
+1131 -26
.vscode
audio
client
+106
.vscode/launch.json
··· 1 + { 2 + // Use IntelliSense to learn about possible attributes. 3 + // Hover to view descriptions of existing attributes. 4 + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 + "version": "0.2.0", 6 + "configurations": [ 7 + 8 + { 9 + "name": "Debug unit tests in library 'felix_audio'", 10 + "type": "lldb", 11 + "request": "launch", 12 + "cargo": { 13 + "args": [ 14 + "test", 15 + "--package=felix-audio" 16 + ] 17 + } 18 + }, 19 + { 20 + "name": "Debug example 'test'", 21 + "type": "lldb", 22 + "request": "launch", 23 + "cargo": { 24 + "args": [ 25 + "run", 26 + "--example=test", 27 + "--package=felix-audio" 28 + ] 29 + }, 30 + "args": [] 31 + }, 32 + { 33 + "name": "Debug unit tests in example 'test'", 34 + "type": "lldb", 35 + "request": "launch", 36 + "cargo": { 37 + "args": [ 38 + "test", 39 + "--example=test", 40 + "--package=felix-audio" 41 + ] 42 + } 43 + }, 44 + { 45 + "name": "Debug executable 'felix-client'", 46 + "type": "lldb", 47 + "request": "launch", 48 + "cargo": { 49 + "args": [ 50 + "run", 51 + "--bin=felix-client", 52 + "--package=felix-client" 53 + ] 54 + }, 55 + "args": [] 56 + }, 57 + { 58 + "name": "Debug unit tests in executable 'felix-client'", 59 + "type": "lldb", 60 + "request": "launch", 61 + "cargo": { 62 + "args": [ 63 + "test", 64 + "--bin=felix-client", 65 + "--package=felix-client" 66 + ] 67 + } 68 + }, 69 + { 70 + "name": "Debug unit tests in library 'felix_net'", 71 + "type": "lldb", 72 + "request": "launch", 73 + "cargo": { 74 + "args": [ 75 + "test", 76 + "--package=felix-net" 77 + ] 78 + } 79 + }, 80 + { 81 + "name": "Debug executable 'felix-server'", 82 + "type": "lldb", 83 + "request": "launch", 84 + "cargo": { 85 + "args": [ 86 + "run", 87 + "--bin=felix-server", 88 + "--package=felix-server" 89 + ] 90 + }, 91 + "args": [] 92 + }, 93 + { 94 + "name": "Debug unit tests in executable 'felix-server'", 95 + "type": "lldb", 96 + "request": "launch", 97 + "cargo": { 98 + "args": [ 99 + "test", 100 + "--bin=felix-server", 101 + "--package=felix-server" 102 + ] 103 + } 104 + } 105 + ] 106 + }
+649 -23
Cargo.lock
··· 45 45 "hashbrown 0.15.5", 46 46 "objc2 0.5.2", 47 47 "objc2-app-kit", 48 - "objc2-foundation", 48 + "objc2-foundation 0.2.2", 49 49 ] 50 50 51 51 [[package]] ··· 306 306 dependencies = [ 307 307 "portable-atomic", 308 308 "portable-atomic-util", 309 + ] 310 + 311 + [[package]] 312 + name = "audionimbus-sys" 313 + version = "4.7.0" 314 + source = "registry+https://github.com/rust-lang/crates.io-index" 315 + checksum = "fb5d2e6b2a80ceca3ed697ddf6d11389a70a2186ae02e8038278469097d4ec44" 316 + dependencies = [ 317 + "bindgen 0.71.1", 309 318 ] 310 319 311 320 [[package]] ··· 505 514 "bevy_reflect", 506 515 "bevy_transform", 507 516 "coreaudio-sys", 508 - "cpal", 517 + "cpal 0.15.3", 509 518 "rodio", 510 519 "tracing", 511 520 ] ··· 927 936 "approx", 928 937 "bevy_reflect", 929 938 "derive_more", 930 - "glam", 939 + "glam 0.30.9", 931 940 "itertools 0.14.0", 932 941 "libm", 933 942 "rand 0.9.2", ··· 1102 1111 "downcast-rs 2.0.2", 1103 1112 "erased-serde", 1104 1113 "foldhash 0.2.0", 1105 - "glam", 1114 + "glam 0.30.9", 1106 1115 "inventory", 1107 1116 "petgraph", 1108 1117 "serde", ··· 1211 1220 ] 1212 1221 1213 1222 [[package]] 1223 + name = "bevy_seedling" 1224 + version = "0.6.1" 1225 + source = "registry+https://github.com/rust-lang/crates.io-index" 1226 + checksum = "cb0d2bb3af43e45ea318865e49cf2c33e32f32a986fcaf6d7a4e73a093ce1766" 1227 + dependencies = [ 1228 + "bevy_app", 1229 + "bevy_asset", 1230 + "bevy_ecs", 1231 + "bevy_log", 1232 + "bevy_math", 1233 + "bevy_platform", 1234 + "bevy_reflect", 1235 + "bevy_seedling_macros", 1236 + "bevy_time", 1237 + "bevy_transform", 1238 + "ebur128", 1239 + "firewheel", 1240 + "firewheel-ircam-hrtf", 1241 + "portable-atomic", 1242 + "rand 0.9.2", 1243 + "smallvec", 1244 + "symphonia", 1245 + "symphonium", 1246 + ] 1247 + 1248 + [[package]] 1249 + name = "bevy_seedling_macros" 1250 + version = "0.6.0" 1251 + source = "registry+https://github.com/rust-lang/crates.io-index" 1252 + checksum = "71af121c6c880413f48ce79a217312bb951d2b07cbd3f654dc93211c12bd7c05" 1253 + dependencies = [ 1254 + "bevy_macro_utils", 1255 + "proc-macro2", 1256 + "quote", 1257 + "syn", 1258 + ] 1259 + 1260 + [[package]] 1214 1261 name = "bevy_shader" 1215 1262 version = "0.17.3" 1216 1263 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1515 1562 "web-sys", 1516 1563 "wgpu-types", 1517 1564 "winit", 1565 + ] 1566 + 1567 + [[package]] 1568 + name = "bindgen" 1569 + version = "0.71.1" 1570 + source = "registry+https://github.com/rust-lang/crates.io-index" 1571 + checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" 1572 + dependencies = [ 1573 + "bitflags 2.10.0", 1574 + "cexpr", 1575 + "clang-sys", 1576 + "itertools 0.13.0", 1577 + "log", 1578 + "prettyplease", 1579 + "proc-macro2", 1580 + "quote", 1581 + "regex", 1582 + "rustc-hash 2.1.1", 1583 + "shlex", 1584 + "syn", 1518 1585 ] 1519 1586 1520 1587 [[package]] ··· 1895 1962 ] 1896 1963 1897 1964 [[package]] 1965 + name = "coreaudio-rs" 1966 + version = "0.13.0" 1967 + source = "registry+https://github.com/rust-lang/crates.io-index" 1968 + checksum = "1aae284fbaf7d27aa0e292f7677dfbe26503b0d555026f702940805a630eac17" 1969 + dependencies = [ 1970 + "bitflags 1.3.2", 1971 + "libc", 1972 + "objc2-audio-toolbox", 1973 + "objc2-core-audio", 1974 + "objc2-core-audio-types", 1975 + "objc2-core-foundation", 1976 + ] 1977 + 1978 + [[package]] 1898 1979 name = "coreaudio-sys" 1899 1980 version = "0.2.17" 1900 1981 source = "registry+https://github.com/rust-lang/crates.io-index" 1901 1982 checksum = "ceec7a6067e62d6f931a2baf6f3a751f4a892595bcec1461a3c94ef9949864b6" 1902 1983 dependencies = [ 1903 - "bindgen", 1984 + "bindgen 0.72.1", 1904 1985 ] 1905 1986 1906 1987 [[package]] ··· 1934 2015 dependencies = [ 1935 2016 "alsa", 1936 2017 "core-foundation-sys", 1937 - "coreaudio-rs", 2018 + "coreaudio-rs 0.11.3", 1938 2019 "dasp_sample", 1939 2020 "jni", 1940 2021 "js-sys", ··· 1950 2031 ] 1951 2032 1952 2033 [[package]] 2034 + name = "cpal" 2035 + version = "0.16.0" 2036 + source = "registry+https://github.com/rust-lang/crates.io-index" 2037 + checksum = "cbd307f43cc2a697e2d1f8bc7a1d824b5269e052209e28883e5bc04d095aaa3f" 2038 + dependencies = [ 2039 + "alsa", 2040 + "coreaudio-rs 0.13.0", 2041 + "dasp_sample", 2042 + "jni", 2043 + "js-sys", 2044 + "libc", 2045 + "mach2", 2046 + "ndk 0.9.0", 2047 + "ndk-context", 2048 + "num-derive", 2049 + "num-traits", 2050 + "objc2-audio-toolbox", 2051 + "objc2-core-audio", 2052 + "objc2-core-audio-types", 2053 + "wasm-bindgen", 2054 + "wasm-bindgen-futures", 2055 + "web-sys", 2056 + "windows 0.54.0", 2057 + ] 2058 + 2059 + [[package]] 1953 2060 name = "crc32fast" 1954 2061 version = "1.5.0" 1955 2062 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2012 2119 checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" 2013 2120 2014 2121 [[package]] 2122 + name = "dasp_frame" 2123 + version = "0.11.0" 2124 + source = "registry+https://github.com/rust-lang/crates.io-index" 2125 + checksum = "b2a3937f5fe2135702897535c8d4a5553f8b116f76c1529088797f2eee7c5cd6" 2126 + dependencies = [ 2127 + "dasp_sample", 2128 + ] 2129 + 2130 + [[package]] 2015 2131 name = "dasp_sample" 2016 2132 version = "0.11.0" 2017 2133 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2113 2229 checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" 2114 2230 2115 2231 [[package]] 2232 + name = "ebur128" 2233 + version = "0.1.10" 2234 + source = "registry+https://github.com/rust-lang/crates.io-index" 2235 + checksum = "e227cc62d64d6fe01abbef48134b9c1f17d470cef1e7a56337ad05b1f81df7f9" 2236 + dependencies = [ 2237 + "bitflags 1.3.2", 2238 + "dasp_frame", 2239 + "dasp_sample", 2240 + "smallvec", 2241 + ] 2242 + 2243 + [[package]] 2116 2244 name = "either" 2117 2245 version = "1.15.0" 2118 2246 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2126 2254 dependencies = [ 2127 2255 "const_panic", 2128 2256 "encase_derive", 2129 - "glam", 2257 + "glam 0.30.9", 2130 2258 "thiserror 2.0.17", 2131 2259 ] 2132 2260 ··· 2151 2279 ] 2152 2280 2153 2281 [[package]] 2282 + name = "encoding_rs" 2283 + version = "0.8.35" 2284 + source = "registry+https://github.com/rust-lang/crates.io-index" 2285 + checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" 2286 + dependencies = [ 2287 + "cfg-if", 2288 + ] 2289 + 2290 + [[package]] 2154 2291 name = "equivalent" 2155 2292 version = "1.0.2" 2156 2293 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2208 2345 ] 2209 2346 2210 2347 [[package]] 2348 + name = "extended" 2349 + version = "0.1.0" 2350 + source = "registry+https://github.com/rust-lang/crates.io-index" 2351 + checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365" 2352 + 2353 + [[package]] 2354 + name = "fast-interleave" 2355 + version = "0.1.3" 2356 + source = "registry+https://github.com/rust-lang/crates.io-index" 2357 + checksum = "a0a5ab837f0983c0a9210d7847931f64e3be67fcb0ab93d625f7845a0132c825" 2358 + 2359 + [[package]] 2211 2360 name = "fastrand" 2212 2361 version = "2.3.0" 2213 2362 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2223 2372 ] 2224 2373 2225 2374 [[package]] 2375 + name = "felix-audio" 2376 + version = "0.1.0" 2377 + dependencies = [ 2378 + "anyhow", 2379 + "audionimbus-sys", 2380 + "cpal 0.16.0", 2381 + "hound", 2382 + ] 2383 + 2384 + [[package]] 2226 2385 name = "felix-client" 2227 2386 version = "0.1.0" 2228 2387 dependencies = [ 2229 2388 "anyhow", 2230 2389 "bevy", 2390 + "bevy_seedling", 2391 + "cpal 0.16.0", 2231 2392 "dotenvy", 2232 2393 "felix-net", 2233 2394 "tokio", ··· 2259 2420 checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" 2260 2421 2261 2422 [[package]] 2423 + name = "firewheel" 2424 + version = "0.9.2" 2425 + source = "registry+https://github.com/rust-lang/crates.io-index" 2426 + checksum = "b4a3247a4004d294962675375b2f539fb31990563261a385e7ef1353c1addd60" 2427 + dependencies = [ 2428 + "firewheel-core", 2429 + "firewheel-cpal", 2430 + "firewheel-graph", 2431 + "firewheel-nodes", 2432 + "firewheel-pool", 2433 + "thiserror 2.0.17", 2434 + ] 2435 + 2436 + [[package]] 2437 + name = "firewheel-core" 2438 + version = "0.9.2" 2439 + source = "registry+https://github.com/rust-lang/crates.io-index" 2440 + checksum = "9d57ae9ba24554846916e77affb2c9efea35f6d7f39ae2f56329db309f8396a9" 2441 + dependencies = [ 2442 + "arrayvec", 2443 + "bevy_ecs", 2444 + "bevy_platform", 2445 + "bevy_reflect", 2446 + "bitflags 2.10.0", 2447 + "firewheel-macros", 2448 + "fixed-resample", 2449 + "glam 0.29.3", 2450 + "glam 0.30.9", 2451 + "log", 2452 + "num-traits", 2453 + "portable-atomic", 2454 + "ringbuf", 2455 + "rtgc", 2456 + "smallvec", 2457 + "symphonium", 2458 + "thiserror 2.0.17", 2459 + "thunderdome", 2460 + "wmidi", 2461 + ] 2462 + 2463 + [[package]] 2464 + name = "firewheel-cpal" 2465 + version = "0.9.2" 2466 + source = "registry+https://github.com/rust-lang/crates.io-index" 2467 + checksum = "f561251f37171d143922c3b8e45c102f9d79fd9ce4bd6faaa62550af1c5b2b1d" 2468 + dependencies = [ 2469 + "bevy_platform", 2470 + "cpal 0.16.0", 2471 + "fast-interleave", 2472 + "firewheel-core", 2473 + "firewheel-graph", 2474 + "fixed-resample", 2475 + "log", 2476 + "ringbuf", 2477 + "thiserror 2.0.17", 2478 + ] 2479 + 2480 + [[package]] 2481 + name = "firewheel-graph" 2482 + version = "0.9.2" 2483 + source = "registry+https://github.com/rust-lang/crates.io-index" 2484 + checksum = "7730621467abd9aa6a945c6aa11447d5334d9427f0e51699c391e2648b8bc0c8" 2485 + dependencies = [ 2486 + "arrayvec", 2487 + "bevy_platform", 2488 + "bevy_reflect", 2489 + "firewheel-core", 2490 + "log", 2491 + "num-traits", 2492 + "ringbuf", 2493 + "smallvec", 2494 + "thiserror 2.0.17", 2495 + "thunderdome", 2496 + "triple_buffer", 2497 + ] 2498 + 2499 + [[package]] 2500 + name = "firewheel-ircam-hrtf" 2501 + version = "0.2.0" 2502 + source = "registry+https://github.com/rust-lang/crates.io-index" 2503 + checksum = "16ef3ba4e1f227a7247ddc94f5850324010ecf7ecf59ee3af5a2c9fcd326b744" 2504 + dependencies = [ 2505 + "bevy_ecs", 2506 + "bevy_reflect", 2507 + "firewheel", 2508 + "glam 0.30.9", 2509 + "hrtf", 2510 + ] 2511 + 2512 + [[package]] 2513 + name = "firewheel-macros" 2514 + version = "0.9.2" 2515 + source = "registry+https://github.com/rust-lang/crates.io-index" 2516 + checksum = "34833b22730fd510e34b07df943ce4e1495bc4f1d738a959cb31c0431f938b46" 2517 + dependencies = [ 2518 + "bevy_macro_utils", 2519 + "proc-macro2", 2520 + "quote", 2521 + "syn", 2522 + "toml_edit", 2523 + ] 2524 + 2525 + [[package]] 2526 + name = "firewheel-nodes" 2527 + version = "0.9.2" 2528 + source = "registry+https://github.com/rust-lang/crates.io-index" 2529 + checksum = "0513d8c83c24108b8dd8e28f572d5c90a87d085ca81929adb0cff2a62eff0863" 2530 + dependencies = [ 2531 + "bevy_ecs", 2532 + "bevy_platform", 2533 + "bevy_reflect", 2534 + "firewheel-core", 2535 + "fixed-resample", 2536 + "num-traits", 2537 + "smallvec", 2538 + ] 2539 + 2540 + [[package]] 2541 + name = "firewheel-pool" 2542 + version = "0.9.2" 2543 + source = "registry+https://github.com/rust-lang/crates.io-index" 2544 + checksum = "57b3f2122f632fcaff37d9c42e3b33d050199c180d8c13161f9f808a47b009f9" 2545 + dependencies = [ 2546 + "bevy_platform", 2547 + "firewheel-core", 2548 + "firewheel-graph", 2549 + "firewheel-nodes", 2550 + "smallvec", 2551 + "thiserror 2.0.17", 2552 + "thunderdome", 2553 + ] 2554 + 2555 + [[package]] 2556 + name = "fixed-resample" 2557 + version = "0.9.2" 2558 + source = "registry+https://github.com/rust-lang/crates.io-index" 2559 + checksum = "3e548b80c8a294b230847d73ae8e53d1b2d5b407a1a9ec51c9698a761c4610b1" 2560 + dependencies = [ 2561 + "arrayvec", 2562 + "fast-interleave", 2563 + "ringbuf", 2564 + "rubato 0.16.2", 2565 + ] 2566 + 2567 + [[package]] 2262 2568 name = "fixedbitset" 2263 2569 version = "0.5.7" 2264 2570 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2464 2770 "log", 2465 2771 "xml-rs", 2466 2772 ] 2773 + 2774 + [[package]] 2775 + name = "glam" 2776 + version = "0.29.3" 2777 + source = "registry+https://github.com/rust-lang/crates.io-index" 2778 + checksum = "8babf46d4c1c9d92deac9f7be466f76dfc4482b6452fc5024b5e8daf6ffeb3ee" 2467 2779 2468 2780 [[package]] 2469 2781 name = "glam" ··· 2672 2984 checksum = "29a164ceff4500f2a72b1d21beaa8aa8ad83aec2b641844c659b190cb3ea2e0b" 2673 2985 dependencies = [ 2674 2986 "constgebra", 2675 - "glam", 2987 + "glam 0.30.9", 2676 2988 "tinyvec", 2677 2989 ] 2678 2990 ··· 2683 2995 checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" 2684 2996 2685 2997 [[package]] 2998 + name = "hound" 2999 + version = "3.5.1" 3000 + source = "registry+https://github.com/rust-lang/crates.io-index" 3001 + checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f" 3002 + 3003 + [[package]] 3004 + name = "hrtf" 3005 + version = "0.8.1" 3006 + source = "registry+https://github.com/rust-lang/crates.io-index" 3007 + checksum = "0f4de47a84fd55fa33aa5ef337016814fdc869fdad23e7898b5322fa290248e6" 3008 + dependencies = [ 3009 + "byteorder", 3010 + "rubato 0.14.1", 3011 + "rustfft", 3012 + ] 3013 + 3014 + [[package]] 2686 3015 name = "image" 2687 3016 version = "0.25.9" 2688 3017 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3184 3513 ] 3185 3514 3186 3515 [[package]] 3516 + name = "num-complex" 3517 + version = "0.4.6" 3518 + source = "registry+https://github.com/rust-lang/crates.io-index" 3519 + checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" 3520 + dependencies = [ 3521 + "num-traits", 3522 + ] 3523 + 3524 + [[package]] 3187 3525 name = "num-derive" 3188 3526 version = "0.4.2" 3189 3527 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3192 3530 "proc-macro2", 3193 3531 "quote", 3194 3532 "syn", 3533 + ] 3534 + 3535 + [[package]] 3536 + name = "num-integer" 3537 + version = "0.1.46" 3538 + source = "registry+https://github.com/rust-lang/crates.io-index" 3539 + checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 3540 + dependencies = [ 3541 + "num-traits", 3195 3542 ] 3196 3543 3197 3544 [[package]] ··· 3272 3619 "objc2 0.5.2", 3273 3620 "objc2-core-data", 3274 3621 "objc2-core-image", 3275 - "objc2-foundation", 3622 + "objc2-foundation 0.2.2", 3276 3623 "objc2-quartz-core", 3277 3624 ] 3278 3625 3279 3626 [[package]] 3627 + name = "objc2-audio-toolbox" 3628 + version = "0.3.2" 3629 + source = "registry+https://github.com/rust-lang/crates.io-index" 3630 + checksum = "6948501a91121d6399b79abaa33a8aa4ea7857fe019f341b8c23ad6e81b79b08" 3631 + dependencies = [ 3632 + "bitflags 2.10.0", 3633 + "libc", 3634 + "objc2 0.6.3", 3635 + "objc2-core-audio", 3636 + "objc2-core-audio-types", 3637 + "objc2-core-foundation", 3638 + "objc2-foundation 0.3.2", 3639 + ] 3640 + 3641 + [[package]] 3280 3642 name = "objc2-cloud-kit" 3281 3643 version = "0.2.2" 3282 3644 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3286 3648 "block2 0.5.1", 3287 3649 "objc2 0.5.2", 3288 3650 "objc2-core-location", 3289 - "objc2-foundation", 3651 + "objc2-foundation 0.2.2", 3290 3652 ] 3291 3653 3292 3654 [[package]] ··· 3297 3659 dependencies = [ 3298 3660 "block2 0.5.1", 3299 3661 "objc2 0.5.2", 3300 - "objc2-foundation", 3662 + "objc2-foundation 0.2.2", 3663 + ] 3664 + 3665 + [[package]] 3666 + name = "objc2-core-audio" 3667 + version = "0.3.2" 3668 + source = "registry+https://github.com/rust-lang/crates.io-index" 3669 + checksum = "e1eebcea8b0dbff5f7c8504f3107c68fc061a3eb44932051c8cf8a68d969c3b2" 3670 + dependencies = [ 3671 + "dispatch2", 3672 + "objc2 0.6.3", 3673 + "objc2-core-audio-types", 3674 + "objc2-core-foundation", 3675 + ] 3676 + 3677 + [[package]] 3678 + name = "objc2-core-audio-types" 3679 + version = "0.3.2" 3680 + source = "registry+https://github.com/rust-lang/crates.io-index" 3681 + checksum = "5a89f2ec274a0cf4a32642b2991e8b351a404d290da87bb6a9a9d8632490bd1c" 3682 + dependencies = [ 3683 + "bitflags 2.10.0", 3684 + "objc2 0.6.3", 3301 3685 ] 3302 3686 3303 3687 [[package]] ··· 3309 3693 "bitflags 2.10.0", 3310 3694 "block2 0.5.1", 3311 3695 "objc2 0.5.2", 3312 - "objc2-foundation", 3696 + "objc2-foundation 0.2.2", 3313 3697 ] 3314 3698 3315 3699 [[package]] ··· 3319 3703 checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" 3320 3704 dependencies = [ 3321 3705 "bitflags 2.10.0", 3706 + "dispatch2", 3707 + "objc2 0.6.3", 3322 3708 ] 3323 3709 3324 3710 [[package]] ··· 3329 3715 dependencies = [ 3330 3716 "block2 0.5.1", 3331 3717 "objc2 0.5.2", 3332 - "objc2-foundation", 3718 + "objc2-foundation 0.2.2", 3333 3719 "objc2-metal", 3334 3720 ] 3335 3721 ··· 3342 3728 "block2 0.5.1", 3343 3729 "objc2 0.5.2", 3344 3730 "objc2-contacts", 3345 - "objc2-foundation", 3731 + "objc2-foundation 0.2.2", 3346 3732 ] 3347 3733 3348 3734 [[package]] ··· 3365 3751 ] 3366 3752 3367 3753 [[package]] 3754 + name = "objc2-foundation" 3755 + version = "0.3.2" 3756 + source = "registry+https://github.com/rust-lang/crates.io-index" 3757 + checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" 3758 + dependencies = [ 3759 + "objc2 0.6.3", 3760 + ] 3761 + 3762 + [[package]] 3368 3763 name = "objc2-io-kit" 3369 3764 version = "0.3.2" 3370 3765 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3383 3778 "block2 0.5.1", 3384 3779 "objc2 0.5.2", 3385 3780 "objc2-app-kit", 3386 - "objc2-foundation", 3781 + "objc2-foundation 0.2.2", 3387 3782 ] 3388 3783 3389 3784 [[package]] ··· 3395 3790 "bitflags 2.10.0", 3396 3791 "block2 0.5.1", 3397 3792 "objc2 0.5.2", 3398 - "objc2-foundation", 3793 + "objc2-foundation 0.2.2", 3399 3794 ] 3400 3795 3401 3796 [[package]] ··· 3407 3802 "bitflags 2.10.0", 3408 3803 "block2 0.5.1", 3409 3804 "objc2 0.5.2", 3410 - "objc2-foundation", 3805 + "objc2-foundation 0.2.2", 3411 3806 "objc2-metal", 3412 3807 ] 3413 3808 ··· 3418 3813 checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" 3419 3814 dependencies = [ 3420 3815 "objc2 0.5.2", 3421 - "objc2-foundation", 3816 + "objc2-foundation 0.2.2", 3422 3817 ] 3423 3818 3424 3819 [[package]] ··· 3434 3829 "objc2-core-data", 3435 3830 "objc2-core-image", 3436 3831 "objc2-core-location", 3437 - "objc2-foundation", 3832 + "objc2-foundation 0.2.2", 3438 3833 "objc2-link-presentation", 3439 3834 "objc2-quartz-core", 3440 3835 "objc2-symbols", ··· 3450 3845 dependencies = [ 3451 3846 "block2 0.5.1", 3452 3847 "objc2 0.5.2", 3453 - "objc2-foundation", 3848 + "objc2-foundation 0.2.2", 3454 3849 ] 3455 3850 3456 3851 [[package]] ··· 3463 3858 "block2 0.5.1", 3464 3859 "objc2 0.5.2", 3465 3860 "objc2-core-location", 3466 - "objc2-foundation", 3861 + "objc2-foundation 0.2.2", 3467 3862 ] 3468 3863 3469 3864 [[package]] ··· 3705 4100 checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" 3706 4101 3707 4102 [[package]] 4103 + name = "prettyplease" 4104 + version = "0.2.37" 4105 + source = "registry+https://github.com/rust-lang/crates.io-index" 4106 + checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" 4107 + dependencies = [ 4108 + "proc-macro2", 4109 + "syn", 4110 + ] 4111 + 4112 + [[package]] 4113 + name = "primal-check" 4114 + version = "0.3.4" 4115 + source = "registry+https://github.com/rust-lang/crates.io-index" 4116 + checksum = "dc0d895b311e3af9902528fbb8f928688abbd95872819320517cc24ca6b2bd08" 4117 + dependencies = [ 4118 + "num-integer", 4119 + ] 4120 + 4121 + [[package]] 3708 4122 name = "proc-macro-crate" 3709 4123 version = "3.4.0" 3710 4124 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3865 4279 ] 3866 4280 3867 4281 [[package]] 4282 + name = "realfft" 4283 + version = "3.5.0" 4284 + source = "registry+https://github.com/rust-lang/crates.io-index" 4285 + checksum = "f821338fddb99d089116342c46e9f1fbf3828dba077674613e734e01d6ea8677" 4286 + dependencies = [ 4287 + "rustfft", 4288 + ] 4289 + 4290 + [[package]] 3868 4291 name = "rectangle-pack" 3869 4292 version = "0.4.2" 3870 4293 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3933 4356 checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" 3934 4357 3935 4358 [[package]] 4359 + name = "ringbuf" 4360 + version = "0.4.8" 4361 + source = "registry+https://github.com/rust-lang/crates.io-index" 4362 + checksum = "fe47b720588c8702e34b5979cb3271a8b1842c7cb6f57408efa70c779363488c" 4363 + dependencies = [ 4364 + "crossbeam-utils", 4365 + "portable-atomic", 4366 + "portable-atomic-util", 4367 + ] 4368 + 4369 + [[package]] 3936 4370 name = "rodio" 3937 4371 version = "0.20.1" 3938 4372 source = "registry+https://github.com/rust-lang/crates.io-index" 3939 4373 checksum = "e7ceb6607dd738c99bc8cb28eff249b7cd5c8ec88b9db96c0608c1480d140fb1" 3940 4374 dependencies = [ 3941 - "cpal", 4375 + "cpal 0.15.3", 3942 4376 "lewton", 3943 4377 ] 3944 4378 ··· 3962 4396 checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" 3963 4397 3964 4398 [[package]] 4399 + name = "rtgc" 4400 + version = "0.2.4" 4401 + source = "registry+https://github.com/rust-lang/crates.io-index" 4402 + checksum = "8ff37e188d26f62b595065458583a6a7101a52343b112c10a2b277e7a490247d" 4403 + dependencies = [ 4404 + "bevy_platform", 4405 + ] 4406 + 4407 + [[package]] 4408 + name = "rubato" 4409 + version = "0.14.1" 4410 + source = "registry+https://github.com/rust-lang/crates.io-index" 4411 + checksum = "e6dd52e80cfc21894deadf554a5673002938ae4625f7a283e536f9cf7c17b0d5" 4412 + dependencies = [ 4413 + "num-complex", 4414 + "num-integer", 4415 + "num-traits", 4416 + "realfft", 4417 + ] 4418 + 4419 + [[package]] 4420 + name = "rubato" 4421 + version = "0.16.2" 4422 + source = "registry+https://github.com/rust-lang/crates.io-index" 4423 + checksum = "5258099699851cfd0082aeb645feb9c084d9a5e1f1b8d5372086b989fc5e56a1" 4424 + dependencies = [ 4425 + "num-complex", 4426 + "num-integer", 4427 + "num-traits", 4428 + "realfft", 4429 + ] 4430 + 4431 + [[package]] 3965 4432 name = "rustc-hash" 3966 4433 version = "1.1.0" 3967 4434 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3980 4447 checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" 3981 4448 dependencies = [ 3982 4449 "semver", 4450 + ] 4451 + 4452 + [[package]] 4453 + name = "rustfft" 4454 + version = "6.4.1" 4455 + source = "registry+https://github.com/rust-lang/crates.io-index" 4456 + checksum = "21db5f9893e91f41798c88680037dba611ca6674703c1a18601b01a72c8adb89" 4457 + dependencies = [ 4458 + "num-complex", 4459 + "num-integer", 4460 + "num-traits", 4461 + "primal-check", 4462 + "strength_reduce", 4463 + "transpose", 3983 4464 ] 3984 4465 3985 4466 [[package]] ··· 4286 4767 checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 4287 4768 4288 4769 [[package]] 4770 + name = "strength_reduce" 4771 + version = "0.2.4" 4772 + source = "registry+https://github.com/rust-lang/crates.io-index" 4773 + checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" 4774 + 4775 + [[package]] 4289 4776 name = "strict-num" 4290 4777 version = "0.1.1" 4291 4778 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4309 4796 ] 4310 4797 4311 4798 [[package]] 4799 + name = "symphonia" 4800 + version = "0.5.5" 4801 + source = "registry+https://github.com/rust-lang/crates.io-index" 4802 + checksum = "5773a4c030a19d9bfaa090f49746ff35c75dfddfa700df7a5939d5e076a57039" 4803 + dependencies = [ 4804 + "lazy_static", 4805 + "symphonia-codec-pcm", 4806 + "symphonia-codec-vorbis", 4807 + "symphonia-core", 4808 + "symphonia-format-ogg", 4809 + "symphonia-format-riff", 4810 + "symphonia-metadata", 4811 + ] 4812 + 4813 + [[package]] 4814 + name = "symphonia-codec-pcm" 4815 + version = "0.5.5" 4816 + source = "registry+https://github.com/rust-lang/crates.io-index" 4817 + checksum = "4e89d716c01541ad3ebe7c91ce4c8d38a7cf266a3f7b2f090b108fb0cb031d95" 4818 + dependencies = [ 4819 + "log", 4820 + "symphonia-core", 4821 + ] 4822 + 4823 + [[package]] 4824 + name = "symphonia-codec-vorbis" 4825 + version = "0.5.5" 4826 + source = "registry+https://github.com/rust-lang/crates.io-index" 4827 + checksum = "f025837c309cd69ffef572750b4a2257b59552c5399a5e49707cc5b1b85d1c73" 4828 + dependencies = [ 4829 + "log", 4830 + "symphonia-core", 4831 + "symphonia-utils-xiph", 4832 + ] 4833 + 4834 + [[package]] 4835 + name = "symphonia-core" 4836 + version = "0.5.5" 4837 + source = "registry+https://github.com/rust-lang/crates.io-index" 4838 + checksum = "ea00cc4f79b7f6bb7ff87eddc065a1066f3a43fe1875979056672c9ef948c2af" 4839 + dependencies = [ 4840 + "arrayvec", 4841 + "bitflags 1.3.2", 4842 + "bytemuck", 4843 + "lazy_static", 4844 + "log", 4845 + "rustfft", 4846 + ] 4847 + 4848 + [[package]] 4849 + name = "symphonia-format-ogg" 4850 + version = "0.5.5" 4851 + source = "registry+https://github.com/rust-lang/crates.io-index" 4852 + checksum = "2b4955c67c1ed3aa8ae8428d04ca8397fbef6a19b2b051e73b5da8b1435639cb" 4853 + dependencies = [ 4854 + "log", 4855 + "symphonia-core", 4856 + "symphonia-metadata", 4857 + "symphonia-utils-xiph", 4858 + ] 4859 + 4860 + [[package]] 4861 + name = "symphonia-format-riff" 4862 + version = "0.5.5" 4863 + source = "registry+https://github.com/rust-lang/crates.io-index" 4864 + checksum = "c2d7c3df0e7d94efb68401d81906eae73c02b40d5ec1a141962c592d0f11a96f" 4865 + dependencies = [ 4866 + "extended", 4867 + "log", 4868 + "symphonia-core", 4869 + "symphonia-metadata", 4870 + ] 4871 + 4872 + [[package]] 4873 + name = "symphonia-metadata" 4874 + version = "0.5.5" 4875 + source = "registry+https://github.com/rust-lang/crates.io-index" 4876 + checksum = "36306ff42b9ffe6e5afc99d49e121e0bd62fe79b9db7b9681d48e29fa19e6b16" 4877 + dependencies = [ 4878 + "encoding_rs", 4879 + "lazy_static", 4880 + "log", 4881 + "symphonia-core", 4882 + ] 4883 + 4884 + [[package]] 4885 + name = "symphonia-utils-xiph" 4886 + version = "0.5.5" 4887 + source = "registry+https://github.com/rust-lang/crates.io-index" 4888 + checksum = "ee27c85ab799a338446b68eec77abf42e1a6f1bb490656e121c6e27bfbab9f16" 4889 + dependencies = [ 4890 + "symphonia-core", 4891 + "symphonia-metadata", 4892 + ] 4893 + 4894 + [[package]] 4895 + name = "symphonium" 4896 + version = "0.6.5" 4897 + source = "registry+https://github.com/rust-lang/crates.io-index" 4898 + checksum = "94700d892b055c7c25e2fc5319b43d59434119627a08a5096cdcd0fe5345914f" 4899 + dependencies = [ 4900 + "fast-interleave", 4901 + "fixed-resample", 4902 + "log", 4903 + "symphonia", 4904 + ] 4905 + 4906 + [[package]] 4312 4907 name = "syn" 4313 4908 version = "2.0.111" 4314 4909 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4411 5006 dependencies = [ 4412 5007 "cfg-if", 4413 5008 ] 5009 + 5010 + [[package]] 5011 + name = "thunderdome" 5012 + version = "0.6.1" 5013 + source = "registry+https://github.com/rust-lang/crates.io-index" 5014 + checksum = "92e170f93360bf9ae6fe3c31116bbf27adb1d054cedd6bc3d7857e34f2d98d0b" 4414 5015 4415 5016 [[package]] 4416 5017 name = "tiny-skia" ··· 4592 5193 "tracing", 4593 5194 "tracing-subscriber", 4594 5195 "wasm-bindgen", 5196 + ] 5197 + 5198 + [[package]] 5199 + name = "transpose" 5200 + version = "0.2.3" 5201 + source = "registry+https://github.com/rust-lang/crates.io-index" 5202 + checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" 5203 + dependencies = [ 5204 + "num-integer", 5205 + "strength_reduce", 5206 + ] 5207 + 5208 + [[package]] 5209 + name = "triple_buffer" 5210 + version = "8.1.1" 5211 + source = "registry+https://github.com/rust-lang/crates.io-index" 5212 + checksum = "420466259f9fa5decc654c490b9ab538400e5420df8237f84ecbe20368bcf72b" 5213 + dependencies = [ 5214 + "crossbeam-utils", 4595 5215 ] 4596 5216 4597 5217 [[package]] ··· 5669 6289 "ndk 0.9.0", 5670 6290 "objc2 0.5.2", 5671 6291 "objc2-app-kit", 5672 - "objc2-foundation", 6292 + "objc2-foundation 0.2.2", 5673 6293 "objc2-ui-kit", 5674 6294 "orbclient", 5675 6295 "percent-encoding", ··· 5710 6330 version = "0.46.0" 5711 6331 source = "registry+https://github.com/rust-lang/crates.io-index" 5712 6332 checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" 6333 + 6334 + [[package]] 6335 + name = "wmidi" 6336 + version = "4.0.10" 6337 + source = "registry+https://github.com/rust-lang/crates.io-index" 6338 + checksum = "4e55f35b40ad0178422d06e9ba845041baf2faf04627b91fde928d0f6a21c712" 5713 6339 5714 6340 [[package]] 5715 6341 name = "x11-dl"
+1 -1
Cargo.toml
··· 1 1 [workspace] 2 2 resolver = "3" 3 - members = [ "client", "net", "server" ] 3 + members = [ "audio", "client", "net", "server" ]
+10
audio/Cargo.toml
··· 1 + [package] 2 + name = "felix-audio" 3 + version = "0.1.0" 4 + edition = "2024" 5 + 6 + [dependencies] 7 + anyhow = "1.0.100" 8 + cpal = "0.16.0" 9 + hound = "3.5.1" 10 + audionimbus-sys = { version = "4.7.0", features = ["auto-install"] }
+23
audio/examples/test.rs
··· 1 + use felix_audio::{AudioThread, source::AudioSource, utils::wav}; 2 + 3 + fn main(){ 4 + let audio = AudioThread::start(); 5 + 6 + let mut source = AudioSource::new(); 7 + 8 + let mut sample_index = 0; 9 + let samples = wav::load_wav_file("/home/phaze/Projects/Projects/felix/audio/out2.wav".into()); 10 + 11 + source.on_request_data(move | output, _ | { 12 + let length = output.len(); 13 + 14 + let input_stream = &samples[sample_index..(sample_index + length)]; 15 + sample_index += length; 16 + 17 + for i in 0..length{ output[i] = input_stream[i] } 18 + }); 19 + 20 + audio.add_source(source); 21 + 22 + loop {} 23 + }
+214
audio/src/lib.rs
··· 1 + use std::{ptr::{null, null_mut}, sync::{Arc, Mutex, mpsc::{Sender, channel}}, thread, vec}; 2 + 3 + use audionimbus_sys::*; 4 + use cpal::{BufferSize, SampleRate, Stream, StreamConfig, traits::{DeviceTrait, HostTrait, StreamTrait}}; 5 + 6 + use crate::source::AudioSource; 7 + 8 + pub mod source; 9 + mod voice; 10 + pub mod utils; 11 + 12 + const CHANNEL_COUNT: u16 = 2; 13 + const SAMPLE_RATE: u32 = 48_000; 14 + const BUFFER_SIZE: u32 = 512; 15 + const DISTANCE_FALLOFF: f32 = 1.0; 16 + 17 + pub type Sample = f32; 18 + 19 + enum AudioThreadCommand{ 20 + AddSource(AudioSource) 21 + } 22 + 23 + pub struct AudioThread{ 24 + sender: Sender<AudioThreadCommand>, 25 + stream: Stream 26 + } 27 + 28 + fn build_context() -> IPLContext{ 29 + let mut context: IPLContext = IPLContext::default(); 30 + unsafe { 31 + iplContextCreate( 32 + &mut IPLContextSettings { 33 + version: STEAMAUDIO_VERSION, 34 + logCallback: None, 35 + allocateCallback: None, 36 + freeCallback: None, 37 + simdLevel: IPLSIMDLevel::IPL_SIMDLEVEL_AVX2, 38 + flags: IPLContextFlags::IPL_CONTEXTFLAGS_FORCE_32BIT 39 + }, 40 + &mut context 41 + ); 42 + } 43 + 44 + context 45 + } 46 + 47 + impl AudioThread{ 48 + pub fn start() -> Self{ 49 + let ( sender, recv ) = channel(); 50 + 51 + let host = cpal::default_host(); 52 + let device = host.default_output_device().expect("No output available."); 53 + 54 + let info = AudioThreadInfo { 55 + sample_rate: SAMPLE_RATE, 56 + buffer_size: BUFFER_SIZE, 57 + channel_count: CHANNEL_COUNT 58 + }; 59 + 60 + let ( request_sender, request_recv ) = channel(); 61 + let ( response_sender, response_recv ) = channel(); 62 + 63 + let stream = device.build_output_stream( 64 + &(&info).into(), 65 + move | output: &mut [ Sample ], _ |{ 66 + request_sender.send(output.len()).unwrap(); 67 + let dat: Vec<f32> = response_recv.recv().unwrap(); 68 + 69 + for i in 0..output.len(){ output[i] = dat[i]; } 70 + }, 71 + |err| println!("{err:?}"), 72 + None 73 + ).unwrap(); 74 + 75 + thread::spawn(move || { 76 + // Audio thread. 77 + let mut audio_settings: IPLAudioSettings = (&info).into(); 78 + 79 + let mut sources: Vec<AudioSource> = vec![]; 80 + let context = build_context(); 81 + 82 + let mut hrtf: IPLHRTF = IPLHRTF::default(); 83 + unsafe { 84 + iplHRTFCreate( 85 + &mut *context, 86 + &mut audio_settings, 87 + &mut IPLHRTFSettings { 88 + type_: IPLHRTFType::IPL_HRTFTYPE_DEFAULT, 89 + sofaFileName: null(), 90 + sofaData: null(), 91 + sofaDataSize: 0, 92 + volume: 1.0, 93 + normType: IPLHRTFNormType::IPL_HRTFNORMTYPE_RMS 94 + }, 95 + &mut hrtf 96 + ); 97 + } 98 + 99 + let mut binaural_effect: IPLBinauralEffect = IPLBinauralEffect::default(); 100 + unsafe { 101 + iplBinauralEffectCreate( 102 + &mut *context, 103 + &mut audio_settings, 104 + &mut IPLBinauralEffectSettings { hrtf: &mut *hrtf }, 105 + &mut binaural_effect 106 + ); 107 + } 108 + 109 + while let Ok(length) = request_recv.recv(){ 110 + let mut output = vec![0.0; length]; 111 + 112 + if let Ok(ev) = recv.try_recv(){ 113 + match ev{ 114 + AudioThreadCommand::AddSource(mut source) => { 115 + source.setup(&info); 116 + sources.push(source); 117 + } 118 + } 119 + } 120 + 121 + output.fill(0.0); 122 + for source in &mut sources{ 123 + let input = source.render(output.len(), &info); 124 + 125 + let direction: ( f32, f32, f32 ) = ( 1.0, 0.2, 1.0 ); 126 + 127 + let dist = ( 128 + direction.0 * direction.0 + 129 + direction.1 * direction.1 + 130 + direction.2 * direction.2 131 + ).sqrt(); 132 + 133 + let dist_falloff = (1.0 / (1.0 + DISTANCE_FALLOFF * ( dist - 1.0 ) )).clamp(0.0, 1.0); 134 + 135 + if dist_falloff < 0.05{ return }; // If too far away, skip audio processing. 136 + 137 + let mut input_buffer = IPLAudioBuffer { 138 + numChannels: 1, 139 + numSamples: input.len() as i32, 140 + data: input.as_ptr() as *mut *mut Sample // NOTE: Technically this buffer is interleaved, but it *should* be mono, so we don't need to deinterleave it. 141 + }; 142 + 143 + let staging_container = vec![0.0; input.len() * 2 as usize]; 144 + let mut staging_buffer = IPLAudioBuffer { 145 + numChannels: info.channel_count as i32, 146 + numSamples: input.len() as i32, 147 + data: staging_container.as_slice().as_ptr() as *mut *mut Sample 148 + }; 149 + 150 + let mut binaural_effect_params = IPLBinauralEffectParams { 151 + direction: IPLVector3 { x: direction.0, y: direction.1, z: direction.2 }, 152 + interpolation: IPLHRTFInterpolation::IPL_HRTFINTERPOLATION_NEAREST, 153 + spatialBlend: 1.0, 154 + hrtf: hrtf, 155 + peakDelays: null_mut() 156 + }; 157 + 158 + unsafe { 159 + iplBinauralEffectApply( 160 + binaural_effect, 161 + &mut binaural_effect_params, 162 + &mut input_buffer, 163 + &mut staging_buffer 164 + ); 165 + } 166 + 167 + for i in 0..staging_container.len(){ 168 + output[i] = staging_container[i] * dist_falloff; 169 + } 170 + 171 + unsafe { iplAudioBufferFree(&mut *context, &mut staging_buffer); } 172 + } 173 + 174 + response_sender.send(output).unwrap(); 175 + } 176 + }); 177 + 178 + stream.play().unwrap(); 179 + 180 + Self { 181 + sender, 182 + stream 183 + } 184 + } 185 + 186 + pub fn add_source( &self, source: AudioSource ){ 187 + self.sender.send(AudioThreadCommand::AddSource(source)).unwrap(); 188 + } 189 + } 190 + 191 + pub struct AudioThreadInfo{ 192 + pub sample_rate: u32, 193 + pub buffer_size: u32, 194 + pub channel_count: u16 195 + } 196 + 197 + impl Into<IPLAudioSettings> for &AudioThreadInfo{ 198 + fn into(self) -> IPLAudioSettings { 199 + IPLAudioSettings { 200 + samplingRate: self.sample_rate as i32, 201 + frameSize: self.buffer_size as i32 202 + } 203 + } 204 + } 205 + 206 + impl Into<StreamConfig> for &AudioThreadInfo{ 207 + fn into(self) -> StreamConfig { 208 + StreamConfig { 209 + channels: self.channel_count, 210 + sample_rate: SampleRate(self.sample_rate), 211 + buffer_size: BufferSize::Fixed(self.buffer_size) 212 + } 213 + } 214 + }
+53
audio/src/source.rs
··· 1 + use std::ptr::{null, null_mut}; 2 + 3 + use anyhow::bail; 4 + use audionimbus_sys::*; 5 + 6 + use crate::{AudioThreadInfo, DISTANCE_FALLOFF, Sample}; 7 + 8 + pub struct AudioSource{ 9 + saturate_cb: Option<Box<dyn FnMut(&mut [ Sample ], &AudioThreadInfo) + Send>>, 10 + 11 + buffer: Vec<Sample> 12 + } 13 + 14 + unsafe impl Send for AudioSource {} 15 + 16 + impl AudioSource{ 17 + pub fn new() -> Self{ 18 + Self { 19 + saturate_cb: None, 20 + 21 + buffer: Vec::new() 22 + } 23 + } 24 + 25 + pub fn on_request_data<T>( &mut self, saturate_cb: T ) 26 + where 27 + T: FnMut(&mut [ Sample ], &AudioThreadInfo) + Send + 'static 28 + { 29 + self.saturate_cb = Some(Box::new(saturate_cb)); 30 + } 31 + 32 + pub fn handle( &self ) -> AudioSourceHandle{ 33 + AudioSourceHandle { } 34 + } 35 + 36 + // Internal stuff, called by audio thread. 37 + pub fn setup( &mut self, audio_settings: &AudioThreadInfo ){ 38 + self.buffer = vec![0.0; audio_settings.buffer_size as usize]; 39 + } 40 + 41 + pub fn render( &mut self, length: usize, info: &AudioThreadInfo ) -> &mut [ Sample ]{ 42 + if let Some(saturate_cb) = &mut self.saturate_cb{ 43 + saturate_cb(&mut self.buffer[0..length], &info); 44 + &mut self.buffer[0..length] 45 + } else{ 46 + &mut self.buffer[0..length] 47 + } 48 + } 49 + } 50 + 51 + pub struct AudioSourceHandle{ 52 + 53 + }
+1
audio/src/utils/mod.rs
··· 1 + pub mod wav;
+15
audio/src/utils/wav.rs
··· 1 + pub fn load_wav_file( path: String ) -> Vec<f32>{ 2 + let mut reader = hound::WavReader::open(path).unwrap(); 3 + let spec = reader.spec(); 4 + dbg!(&spec); 5 + 6 + let mut samples = vec![0.0; (reader.len() / spec.channels as u32) as usize]; 7 + let original_samples: Vec<_> = reader.samples::<i16>().map(|x| x.unwrap() as f32 / i16::MAX as f32).collect(); 8 + 9 + for i in 0..samples.len(){ 10 + let j = i * spec.channels as usize; 11 + samples[i] = original_samples[j]; 12 + } 13 + 14 + samples 15 + }
+51
audio/src/voice/mod.rs
··· 1 + use cpal::{BufferSize, SampleRate, SizedSample, Stream, StreamConfig, traits::{DeviceTrait, HostTrait}}; 2 + 3 + // Credits to: https://github.com/TapGhoul/vban_transceiver/blob/main/src/main.rs#L125 4 + // (thanks tap) 5 + 6 + const SAMPLE_RATE: SampleRate = SampleRate(44_100); 7 + const BUFFER_SIZE: BufferSize = BufferSize::Fixed(512); 8 + 9 + pub fn open_mic<T, K>( mut cb: T ) -> anyhow::Result<Stream> 10 + where 11 + T: FnMut(&[K]) + Send + 'static, 12 + K: SizedSample 13 + { 14 + let host = cpal::default_host(); 15 + let mic = host.default_input_device().unwrap(); 16 + 17 + let stream = mic.build_input_stream( 18 + &StreamConfig { 19 + channels: 1, 20 + buffer_size: BUFFER_SIZE, 21 + sample_rate: SAMPLE_RATE 22 + }, 23 + move | data, _ | cb(data), 24 + | err | panic!("{err}"), 25 + None 26 + ).unwrap(); 27 + 28 + Ok(stream) 29 + } 30 + 31 + pub fn open_output<T, K>( mut cb: T ) -> anyhow::Result<Stream> 32 + where 33 + T: FnMut(&mut [K]) + Send + 'static, 34 + K: SizedSample 35 + { 36 + let host = cpal::default_host(); 37 + let output = host.default_output_device().unwrap(); 38 + 39 + let stream = output.build_output_stream( 40 + &StreamConfig { 41 + channels: 1, 42 + sample_rate: SAMPLE_RATE, 43 + buffer_size: BUFFER_SIZE 44 + }, 45 + move | data, _ | cb(data), 46 + | err | panic!("{err}"), 47 + None 48 + ).unwrap(); 49 + 50 + Ok(stream) 51 + }
+2
client/Cargo.toml
··· 6 6 [dependencies] 7 7 anyhow = "1.0.100" 8 8 bevy = "0.17.3" 9 + bevy_seedling = "0.6.1" 10 + cpal = "0.16.0" 9 11 dotenvy = "0.15.7" 10 12 felix-net = { path = '../net' } 11 13 tokio = { version = "1.48.0", features = ["full"] }
+1
client/src/components/network_interface.rs
··· 1 1 use std::collections::HashMap; 2 2 3 3 use bevy::prelude::*; 4 + use bevy_seedling::prelude::StreamWriterNode; 4 5 use felix_net::{packet::PacketTypes, packets::update_server_position::UpdateServerPositions}; 5 6 6 7 use crate::{debug_camera::DebugCamera, net::{NetClientCommand, connection::Connection}, remote_player::RemotePlayer};
-1
client/src/components/remote_player.rs
··· 8 8 pub rot: Quat 9 9 } 10 10 11 - 12 11 pub fn update( 13 12 players: Query<(&mut Transform, &RemotePlayer)> 14 13 ){
+5 -1
client/src/main.rs
··· 1 1 use bevy::{DefaultPlugins, app::{App, FixedUpdate, Startup, Update}, ecs::system::Commands}; 2 + use bevy_seedling::prelude::*; 2 3 3 4 use crate::{components::{debug_camera, network_interface, remote_player}, setup::setup}; 4 5 ··· 10 11 dotenvy::dotenv().unwrap(); 11 12 12 13 App::new() 13 - .add_plugins(DefaultPlugins) 14 + .add_plugins(( 15 + DefaultPlugins, 16 + SeedlingPlugin::default() 17 + )) 14 18 .add_systems(Startup, setup) 15 19 .add_systems(Startup, move | mut commands: Commands |{ 16 20 commands.spawn(net::handle_net().expect("Network Module Failed."));