More work on Rust

This commit is contained in:
Skyler Lehmkuhl 2025-01-25 04:10:04 -05:00
parent f534ca7e5d
commit 98d6e82397
6 changed files with 483 additions and 420 deletions

View File

@ -13,14 +13,14 @@ dependencies = [
[[package]] [[package]]
name = "alsa" name = "alsa"
version = "0.6.0" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5915f52fe2cf65e83924d037b6c5290b7cee097c6b5c8700746e6168a343fd6b" checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43"
dependencies = [ dependencies = [
"alsa-sys", "alsa-sys",
"bitflags 1.3.2", "bitflags 2.8.0",
"cfg-if",
"libc", "libc",
"nix",
] ]
[[package]] [[package]]
@ -33,18 +33,18 @@ dependencies = [
"pkg-config", "pkg-config",
] ]
[[package]]
name = "anyhow"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.4.0" version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "base-x"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270"
[[package]] [[package]]
name = "bindgen" name = "bindgen"
version = "0.70.1" version = "0.70.1"
@ -60,7 +60,7 @@ dependencies = [
"regex", "regex",
"rustc-hash", "rustc-hash",
"shlex", "shlex",
"syn 2.0.96", "syn",
] ]
[[package]] [[package]]
@ -158,11 +158,12 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]] [[package]]
name = "coreaudio-rs" name = "coreaudio-rs"
version = "0.10.0" version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11894b20ebfe1ff903cbdc52259693389eea03b94918a2def2c30c3bf227ad88" checksum = "321077172d79c662f64f5071a03120748d5bb652f5231570141be24cfcd2bace"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
"core-foundation-sys",
"coreaudio-sys", "coreaudio-sys",
] ]
@ -177,33 +178,32 @@ dependencies = [
[[package]] [[package]]
name = "cpal" name = "cpal"
version = "0.14.2" version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f342c1b63e185e9953584ff2199726bf53850d96610a310e3aca09e9405a2d0b" checksum = "873dab07c8f743075e57f524c583985fbaf745602acbe916a01539364369a779"
dependencies = [ dependencies = [
"alsa", "alsa",
"core-foundation-sys", "core-foundation-sys",
"coreaudio-rs", "coreaudio-rs",
"dasp_sample",
"jni", "jni",
"js-sys", "js-sys",
"libc", "libc",
"mach", "mach2",
"ndk 0.7.0", "ndk",
"ndk-context", "ndk-context",
"oboe", "oboe",
"once_cell", "wasm-bindgen",
"parking_lot", "wasm-bindgen-futures",
"stdweb",
"thiserror",
"web-sys", "web-sys",
"windows", "windows",
] ]
[[package]] [[package]]
name = "discard" name = "dasp_sample"
version = "1.0.4" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f"
[[package]] [[package]]
name = "either" name = "either"
@ -248,24 +248,20 @@ dependencies = [
"either", "either",
] ]
[[package]]
name = "itoa"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
[[package]] [[package]]
name = "jni" name = "jni"
version = "0.19.0" version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
dependencies = [ dependencies = [
"cesu8", "cesu8",
"cfg-if",
"combine", "combine",
"jni-sys", "jni-sys",
"log", "log",
"thiserror", "thiserror",
"walkdir", "walkdir",
"windows-sys 0.45.0",
] ]
[[package]] [[package]]
@ -306,30 +302,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"windows-targets", "windows-targets 0.52.6",
] ]
[[package]] [[package]]
name = "lightningbeam-core" name = "lightningbeam-core"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow",
"console_error_panic_hook", "console_error_panic_hook",
"cpal", "cpal",
"log",
"serde", "serde",
"wasm-bindgen", "wasm-bindgen",
"wasm-logger",
"web-sys", "web-sys",
] ]
[[package]]
name = "lock_api"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.25" version = "0.4.25"
@ -337,10 +326,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
[[package]] [[package]]
name = "mach" name = "mach2"
version = "0.3.2" version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -351,15 +340,6 @@ version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "memoffset"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "minimal-lexical" name = "minimal-lexical"
version = "0.2.1" version = "0.2.1"
@ -368,31 +348,18 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]] [[package]]
name = "ndk" name = "ndk"
version = "0.6.0" version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2032c77e030ddee34a6787a64166008da93f6a352b629261d0fee232b8742dd4" checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 2.8.0",
"jni-sys", "jni-sys",
"ndk-sys 0.3.0", "log",
"ndk-sys",
"num_enum", "num_enum",
"thiserror", "thiserror",
] ]
[[package]]
name = "ndk"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0"
dependencies = [
"bitflags 1.3.2",
"jni-sys",
"ndk-sys 0.4.1+23.1.7779620",
"num_enum",
"raw-window-handle",
"thiserror",
]
[[package]] [[package]]
name = "ndk-context" name = "ndk-context"
version = "0.1.1" version = "0.1.1"
@ -401,35 +368,13 @@ checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
[[package]] [[package]]
name = "ndk-sys" name = "ndk-sys"
version = "0.3.0" version = "0.5.0+25.2.9519653"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e5a6ae77c8ee183dcbbba6150e2e6b9f3f4196a7666c02a715a95692ec1fa97" checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691"
dependencies = [ dependencies = [
"jni-sys", "jni-sys",
] ]
[[package]]
name = "ndk-sys"
version = "0.4.1+23.1.7779620"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3"
dependencies = [
"jni-sys",
]
[[package]]
name = "nix"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c"
dependencies = [
"bitflags 1.3.2",
"cc",
"cfg-if",
"libc",
"memoffset",
]
[[package]] [[package]]
name = "nom" name = "nom"
version = "7.1.3" version = "7.1.3"
@ -442,13 +387,13 @@ dependencies = [
[[package]] [[package]]
name = "num-derive" name = "num-derive"
version = "0.3.3" version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 1.0.109", "syn",
] ]
[[package]] [[package]]
@ -462,33 +407,33 @@ dependencies = [
[[package]] [[package]]
name = "num_enum" name = "num_enum"
version = "0.5.11" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179"
dependencies = [ dependencies = [
"num_enum_derive", "num_enum_derive",
] ]
[[package]] [[package]]
name = "num_enum_derive" name = "num_enum_derive"
version = "0.5.11" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
dependencies = [ dependencies = [
"proc-macro-crate", "proc-macro-crate",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 1.0.109", "syn",
] ]
[[package]] [[package]]
name = "oboe" name = "oboe"
version = "0.4.6" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27f63c358b4fa0fbcfefd7c8be5cfc39c08ce2389f5325687e7762a48d30a5c1" checksum = "e8b61bebd49e5d43f5f8cc7ee2891c16e0f41ec7954d36bcb6c14c5e0de867fb"
dependencies = [ dependencies = [
"jni", "jni",
"ndk 0.6.0", "ndk",
"ndk-context", "ndk-context",
"num-derive", "num-derive",
"num-traits", "num-traits",
@ -497,9 +442,9 @@ dependencies = [
[[package]] [[package]]
name = "oboe-sys" name = "oboe-sys"
version = "0.4.5" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3370abb7372ed744232c12954d920d1a40f1c4686de9e79e800021ef492294bd" checksum = "6c8bb09a4a2b1d668170cfe0a7d5bc103f8999fb316c98099b6a9939c9f2e79d"
dependencies = [ dependencies = [
"cc", "cc",
] ]
@ -510,29 +455,6 @@ version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "parking_lot"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-targets",
]
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.31" version = "0.3.31"
@ -567,21 +489,6 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "raw-window-handle"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
[[package]]
name = "redox_syscall"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
dependencies = [
"bitflags 2.8.0",
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.11.1" version = "1.11.1"
@ -617,27 +524,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[package]] [[package]]
name = "rustversion" name = "rustversion"
version = "1.0.19" version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
[[package]]
name = "ryu"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]] [[package]]
name = "same-file" name = "same-file"
version = "1.0.6" version = "1.0.6"
@ -647,27 +539,6 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.217" version = "1.0.217"
@ -685,108 +556,15 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.96", "syn",
] ]
[[package]]
name = "serde_json"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "sha1"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770"
dependencies = [
"sha1_smol",
]
[[package]]
name = "sha1_smol"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d"
[[package]] [[package]]
name = "shlex" name = "shlex"
version = "1.3.0" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "stdweb"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5"
dependencies = [
"discard",
"rustc_version",
"stdweb-derive",
"stdweb-internal-macros",
"stdweb-internal-runtime",
"wasm-bindgen",
]
[[package]]
name = "stdweb-derive"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
dependencies = [
"proc-macro2",
"quote",
"serde",
"serde_derive",
"syn 1.0.109",
]
[[package]]
name = "stdweb-internal-macros"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11"
dependencies = [
"base-x",
"proc-macro2",
"quote",
"serde",
"serde_derive",
"serde_json",
"sha1",
"syn 1.0.109",
]
[[package]]
name = "stdweb-internal-runtime"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.96" version = "2.0.96"
@ -815,7 +593,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.96", "syn",
] ]
[[package]] [[package]]
@ -873,10 +651,23 @@ dependencies = [
"log", "log",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.96", "syn",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
dependencies = [
"cfg-if",
"js-sys",
"once_cell",
"wasm-bindgen",
"web-sys",
]
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.100" version = "0.2.100"
@ -895,7 +686,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.96", "syn",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -909,6 +700,17 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "wasm-logger"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "074649a66bb306c8f2068c9016395fa65d8e08d2affcbf95acf3c24c3ab19718"
dependencies = [
"log",
"wasm-bindgen",
"web-sys",
]
[[package]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.77" version = "0.3.77"
@ -925,20 +727,45 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [ dependencies = [
"windows-sys", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
name = "windows" name = "windows"
version = "0.37.0" version = "0.54.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57b543186b344cc61c85b5aab0d2e3adf4e0f99bc076eff9aa5927bcc0b8a647" checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49"
dependencies = [ dependencies = [
"windows_aarch64_msvc 0.37.0", "windows-core",
"windows_i686_gnu 0.37.0", "windows-targets 0.52.6",
"windows_i686_msvc 0.37.0", ]
"windows_x86_64_gnu 0.37.0",
"windows_x86_64_msvc 0.37.0", [[package]]
name = "windows-core"
version = "0.54.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65"
dependencies = [
"windows-result",
"windows-targets 0.52.6",
]
[[package]]
name = "windows-result"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets 0.42.2",
] ]
[[package]] [[package]]
@ -947,7 +774,22 @@ version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [ dependencies = [
"windows-targets", "windows-targets 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
"windows_aarch64_gnullvm 0.42.2",
"windows_aarch64_msvc 0.42.2",
"windows_i686_gnu 0.42.2",
"windows_i686_msvc 0.42.2",
"windows_x86_64_gnu 0.42.2",
"windows_x86_64_gnullvm 0.42.2",
"windows_x86_64_msvc 0.42.2",
] ]
[[package]] [[package]]
@ -956,16 +798,22 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm", "windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6", "windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6", "windows_i686_gnu 0.52.6",
"windows_i686_gnullvm", "windows_i686_gnullvm",
"windows_i686_msvc 0.52.6", "windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6", "windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm", "windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6", "windows_x86_64_msvc 0.52.6",
] ]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.52.6" version = "0.52.6"
@ -974,9 +822,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.37.0" version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2623277cb2d1c216ba3b578c0f3cf9cdebeddb6e66b1b218bb33596ea7769c3a" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
@ -986,9 +834,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.37.0" version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3925fd0b0b804730d44d4b6278c50f9699703ec49bcd628020f46f4ba07d9e1" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
@ -1004,9 +852,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.37.0" version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce907ac74fe331b524c1298683efbf598bb031bc84d5e274db2083696d07c57c" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
@ -1016,9 +864,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.37.0" version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2babfba0828f2e6b32457d5341427dcbb577ceef556273229959ac23a10af33d" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
@ -1026,6 +874,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.52.6" version = "0.52.6"
@ -1034,9 +888,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.37.0" version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4dd6dc7df2d84cf7b33822ed5b86318fb1781948e9663bacd047fc9dd52259d" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"

View File

@ -8,8 +8,11 @@ crate-type = ["cdylib", "rlib"]
[dependencies] [dependencies]
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
wasm-bindgen = "0.2" wasm-bindgen = "0.2.45"
cpal = "0.14" cpal = { version = "0.15", features = ["wasm-bindgen"] }
anyhow = "1.0"
wasm-logger = "0.2"
log = "0.4"
[dependencies.web-sys] [dependencies.web-sys]
version = "0.3.22" version = "0.3.22"

3
lightningbeam-core/build.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
cd core
wasm-pack build --target web --out-dir ../src/pkg --features wasm

View File

@ -1,25 +1,93 @@
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use cpal::{SampleFormat, SampleRate, Stream, StreamConfig}; use cpal::{Sample, SampleFormat, StreamConfig, SupportedBufferSize, SampleRate, BufferSize};
use cpal::{BufferSize, SupportedBufferSize};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use crate::AudioOutput; use crate::{TrackManager, Timestamp, Duration, SampleCount, AudioOutput, PlaybackState};
// #[cfg(feature = "wasm")]
// use wasm_bindgen::prelude::*;
// #[cfg(feature="wasm")]
// #[wasm_bindgen]
pub struct CpalAudioOutput { pub struct CpalAudioOutput {
stream: Option<Stream>, track_manager: Option<Arc<Mutex<TrackManager>>>,
buffer: Arc<Mutex<Vec<f32>>>, // Shared buffer for audio chunks _stream: Option<cpal::Stream>,
playback_state: PlaybackState,
timestamp: Arc<Mutex<Timestamp>>,
chunk_size: usize,
sample_rate: u32, sample_rate: u32,
channels: u16,
} }
// #[cfg(feature="wasm")]
// #[wasm_bindgen]
impl CpalAudioOutput { impl CpalAudioOutput {
pub fn new(sample_rate: u32, channels: u16) -> Self { pub fn new() -> Self {
Self { Self {
stream: None, track_manager: None,
buffer: Arc::new(Mutex::new(Vec::new())), _stream: None,
sample_rate, playback_state: PlaybackState::Stopped,
channels, timestamp: Arc::new(Mutex::new(Timestamp::from_seconds(0.0))),
chunk_size: 0,
sample_rate: 44100, // Default sample rate, updated later
} }
} }
fn build_stream<T>(
&mut self,
device: &cpal::Device,
config: cpal::SupportedStreamConfig,
) -> Result<cpal::Stream, anyhow::Error>
where
T: Sample + From<f32> + cpal::SizedSample,
{
let supported_config = config.config();
self.sample_rate = supported_config.sample_rate.0;
let num_channels = supported_config.channels as usize; // Get channel count
let track_manager = self.track_manager.clone();
let playback_state = self.playback_state.clone();
let timestamp = self.timestamp.clone();
let sample_rate = self.sample_rate;
let err_fn = |err| eprintln!("Audio stream error: {:?}", err);
let stream = device.build_output_stream(
&supported_config,
move |data: &mut [T], _: &cpal::OutputCallbackInfo| {
if let Some(track_manager) = &track_manager {
let num_frames = data.len() / num_channels; // Stereo: divide by 2
let sample_count = SampleCount::new(num_frames);
let chunk_duration = Duration::new(num_frames as f64 / sample_rate as f64);
let mut track_manager = track_manager.lock().unwrap();
let playing = matches!(playback_state, PlaybackState::Playing);
let mut timestamp_guard = timestamp.lock().unwrap();
let timestamp = &mut *timestamp_guard;
let chunk = track_manager.update_audio(
timestamp.clone(),
playing,
sample_count,
sample_rate,
);
// Write samples (interleaved stereo)
for (i, frame) in chunk.iter().enumerate() {
let sample = T::from(*frame);
data[i * num_channels] = sample; // Left channel
data[i * num_channels + 1] = sample; // Right channel (or process separately)
}
*timestamp_guard += chunk_duration;
}
},
err_fn,
None,
)?;
Ok(stream)
}
} }
impl AudioOutput for CpalAudioOutput { impl AudioOutput for CpalAudioOutput {
@ -27,79 +95,34 @@ impl AudioOutput for CpalAudioOutput {
let host = cpal::default_host(); let host = cpal::default_host();
let device = host let device = host
.default_output_device() .default_output_device()
.ok_or("No output device available")?; .ok_or_else(|| "No output device available")?;
let supported_config = device let supported_config = device.default_output_config()?;
.default_output_config().unwrap(); self._stream = Some(self.build_stream::<f32>(&device, supported_config)?);
// .with_sample_rate(SampleRate(self.sample_rate)); if let Some(stream) = self._stream.as_ref() {
let config = StreamConfig { stream.play().unwrap();
channels: self.channels, } else {
sample_rate: SampleRate(self.sample_rate), eprintln!("Stream is not initialized!");
buffer_size: match supported_config.buffer_size() { }
SupportedBufferSize::Range { min, max: _ } => BufferSize::Fixed(*min),
SupportedBufferSize::Unknown => BufferSize::Default,
},
};
let buffer = self.buffer.clone();
let sample_format = supported_config.sample_format();
let stream = match sample_format {
SampleFormat::F32 => device.build_output_stream(
&config,
move |data: &mut [f32], _| {
let mut buffer = buffer.lock().unwrap();
for (out_sample, buffer_sample) in data.iter_mut().zip(buffer.iter()) {
*out_sample = *buffer_sample;
}
buffer.clear(); // Clear buffer after playback
},
move |err| {
eprintln!("Audio stream error: {:?}", err);
},
),
SampleFormat::I16 => device.build_output_stream(
&config,
move |data: &mut [i16], _| {
let mut buffer = buffer.lock().unwrap();
for (out_sample, buffer_sample) in data.iter_mut().zip(buffer.iter()) {
*out_sample = (*buffer_sample * i16::MAX as f32) as i16;
}
buffer.clear();
},
move |err| {
eprintln!("Audio stream error: {:?}", err);
},
),
SampleFormat::U16 => device.build_output_stream(
&config,
move |data: &mut [u16], _| {
let mut buffer = buffer.lock().unwrap();
for (out_sample, buffer_sample) in data.iter_mut().zip(buffer.iter()) {
*out_sample = ((*buffer_sample + 1.0) * 0.5 * u16::MAX as f32) as u16;
}
buffer.clear();
},
move |err| {
eprintln!("Audio stream error: {:?}", err);
},
),
};
// If the stream creation failed, return the error
let stream = stream.map_err(|e| {
format!(
"Failed to build output stream for sample format {:?}: {:?}",
sample_format, e
)
})?;
stream.play()?;
self.stream = Some(stream);
Ok(()) Ok(())
} }
fn play_chunk(&mut self, chunk: Vec<f32>) { fn play(&mut self, start_timestamp: Timestamp) {
let mut buffer = self.buffer.lock().unwrap(); self.timestamp.lock().unwrap().set(start_timestamp);
buffer.extend(chunk); self.playback_state = PlaybackState::Playing;
} }
}
fn stop(&mut self) {
self.playback_state = PlaybackState::Stopped;
}
fn register_track_manager(&mut self, track_manager: Arc<Mutex<TrackManager>>) {
self.track_manager = Some(track_manager);
}
fn get_timestamp(&mut self) -> Timestamp {
*self.timestamp.lock().unwrap()
}
fn set_chunk_size(&mut self, chunk_size: usize) {
self.chunk_size = chunk_size
}
}

View File

@ -1,20 +1,30 @@
mod time; mod time;
use time::{Timestamp, Duration, Frame}; use time::{Timestamp, Duration, Frame, SampleCount};
mod audio; mod audio;
use audio::{CpalAudioOutput}; use audio::{CpalAudioOutput};
use log::{Level, LevelFilter, Log, Metadata, Record, SetLoggerError};
use std::sync::{Arc, Mutex};
#[cfg(feature = "wasm")] #[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*; mod wasm_imports {
pub use wasm_bindgen::prelude::*;
pub use web_sys::console;
use wasm_logger;
}
#[cfg(feature = "wasm")]
use wasm_imports::*;
pub trait AudioTrack {
pub trait AudioTrack: Send {
/// Render a chunk of audio for the given timestamp and duration. /// Render a chunk of audio for the given timestamp and duration.
fn render_chunk(&self, timestamp: Timestamp, duration: Duration) -> Vec<f32>; fn render_chunk(&mut self, timestamp: Timestamp, duration: SampleCount) -> Vec<f32>;
/// Get the sample rate of the audio track. /// Get the sample rate of the audio track.
fn sample_rate(&self) -> u32; fn sample_rate(&self) -> u32;
} }
pub trait VideoTrack { pub trait VideoTrack: Send {
/// Render a frame for the given timestamp. /// Render a frame for the given timestamp.
fn render_frame(&self, timestamp: Timestamp) -> Frame; fn render_frame(&self, timestamp: Timestamp) -> Frame;
@ -25,8 +35,10 @@ pub trait VideoTrack {
pub struct TrackManager { pub struct TrackManager {
audio_tracks: Vec<Box<dyn AudioTrack>>, audio_tracks: Vec<Box<dyn AudioTrack>>,
video_tracks: Vec<Box<dyn VideoTrack>>, video_tracks: Vec<Box<dyn VideoTrack>>,
sample_rate: u32, // sample_rate: u32,
frame_duration: Duration, // Duration of each frame in seconds (e.g., 1/60 for 60 FPS) // frame_duration: Duration, // Duration of each frame in seconds (e.g., 1/60 for 60 FPS)
timestamp: Timestamp,
playback_state: PlaybackState,
} }
impl TrackManager { impl TrackManager {
@ -34,8 +46,10 @@ impl TrackManager {
Self { Self {
audio_tracks: Vec::new(), audio_tracks: Vec::new(),
video_tracks: Vec::new(), video_tracks: Vec::new(),
sample_rate, // sample_rate,
frame_duration: Duration::new(frame_duration), // frame_duration: Duration::new(frame_duration),
playback_state: PlaybackState::Stopped,
timestamp: Timestamp::from_seconds(0.0),
} }
} }
@ -46,47 +60,180 @@ impl TrackManager {
pub fn add_video_track(&mut self, track: Box<dyn VideoTrack>) { pub fn add_video_track(&mut self, track: Box<dyn VideoTrack>) {
self.video_tracks.push(track); self.video_tracks.push(track);
} }
pub fn play(&mut self, start_timestamp: Timestamp) {
self.timestamp = start_timestamp;
self.playback_state = PlaybackState::Playing;
}
pub fn stop(&mut self) {
self.playback_state = PlaybackState::Stopped;
}
pub fn play(&mut self, timestamp: Timestamp, audio_output: &mut dyn AudioOutput, video_output: &mut dyn FrameTarget) { // pub fn play(&mut self, timestamp: Timestamp, audio_output: &mut dyn AudioOutput, video_output: &mut dyn FrameTarget) {
let mut timestamp = timestamp.clone(); // let mut timestamp = timestamp.clone();
// Main playback loop // // Main playback loop
loop { // loop {
// Render and play audio chunks // // Render and play audio chunks
let mut audio_mix: Vec<f32> = vec![0.0; self.frame_duration.to_samples(self.sample_rate) as usize]; // let mut audio_mix: Vec<f32> = vec![0.0; self.frame_duration.to_samples(self.sample_rate) as usize];
for track in &mut self.audio_tracks { // for track in &mut self.audio_tracks {
let chunk = track.render_chunk(timestamp, self.frame_duration); // let chunk = track.render_chunk(timestamp, self.frame_duration);
for (i, sample) in chunk.iter().enumerate() { // for (i, sample) in chunk.iter().enumerate() {
audio_mix[i] += sample; // Simple mixing (sum of samples) // audio_mix[i] += sample; // Simple mixing (sum of samples)
} // }
} // }
audio_output.play_chunk(audio_mix); // audio_output.play_chunk(audio_mix);
// Render video frames // // Render video frames
for track in &self.video_tracks { // for track in &self.video_tracks {
let track_frame = track.render_frame(timestamp); // let track_frame = track.render_frame(timestamp);
} // }
// Update timestamp // // Update timestamp
timestamp += self.frame_duration; // timestamp += self.frame_duration;
// Break condition (e.g., end of tracks) // // Break condition (e.g., end of tracks)
if self.audio_tracks.iter().all(|t| t.render_chunk(timestamp, self.frame_duration).is_empty()) { // if self.audio_tracks.iter().all(|t| t.render_chunk(timestamp, self.frame_duration).is_empty()) {
break; // break;
// }
// }
// }
pub fn update_audio(&mut self, timestamp: Timestamp, playing: bool, chunk_size: SampleCount, sample_rate: u32) -> Vec<f32> {
let mut mixed_audio = vec![0.0; chunk_size.as_usize()];
// TODO: render video
for track in &mut self.audio_tracks {
let track_audio = track.render_chunk(timestamp, chunk_size);
for (i, sample) in track_audio.iter().enumerate() {
mixed_audio[i] += *sample; // Simple mixing, add samples together
} }
} }
mixed_audio
} }
} }
pub trait AudioOutput { pub trait AudioOutput {
fn start(&mut self) -> Result<(), Box<dyn std::error::Error>>; fn start(&mut self) -> Result<(), Box<dyn std::error::Error>>;
fn play_chunk(&mut self, chunk: Vec<f32>); fn play(&mut self, start_timestamp: Timestamp);
fn stop(&mut self);
fn register_track_manager(&mut self, track_manager: Arc<Mutex<TrackManager>>);
fn get_timestamp(&mut self) -> Timestamp;
fn set_chunk_size(&mut self, chunk_size: usize);
} }
pub trait FrameTarget { pub trait FrameTarget {
fn draw(&mut self, frame: &[u8], width: u32, height: u32); fn draw(&mut self, frame: &[u8], width: u32, height: u32);
} }
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
enum PlaybackState {
Playing,
Stopped,
}
pub struct SineWaveTrack {
frequency: f32,
phase: f32,
sample_rate: u32,
}
impl SineWaveTrack {
pub fn new(frequency: f32, sample_rate: u32) -> Self {
Self {
frequency,
phase: 0.0,
sample_rate,
}
}
}
impl AudioTrack for SineWaveTrack {
fn render_chunk(&mut self, timestamp: Timestamp, chunk_size: SampleCount) -> Vec<f32> {
let mut chunk = Vec::with_capacity(chunk_size.as_usize());
let phase_increment = (2.0 * std::f32::consts::PI * self.frequency) / self.sample_rate as f32;
for _ in 0..chunk_size.as_usize() {
chunk.push((self.phase).sin());
self.phase += phase_increment;
if self.phase > 2.0 * std::f32::consts::PI {
self.phase -= 2.0 * std::f32::consts::PI;
}
}
chunk
}
fn sample_rate(&self) -> u32 {
self.sample_rate
}
}
#[cfg(feature="wasm")]
#[wasm_bindgen]
pub struct CoreInterface {
#[wasm_bindgen(skip)]
track_manager: Arc<Mutex<TrackManager>>,
#[wasm_bindgen(skip)]
cpal_audio_output: Box<dyn AudioOutput>,
}
#[cfg(feature="wasm")]
#[wasm_bindgen]
impl CoreInterface {
#[wasm_bindgen(constructor)]
pub fn new(sample_rate: u32, frame_duration: f64) -> Self {
Self {
track_manager: Arc::new(Mutex::new(TrackManager::new(sample_rate, frame_duration))),
cpal_audio_output: Box::new(CpalAudioOutput::new())
}
}
pub fn init(&mut self) {
println!("Init CoreInterface");
let track_manager_clone = self.track_manager.clone();
self.cpal_audio_output.register_track_manager(track_manager_clone);
self.cpal_audio_output.start();
}
pub fn play(&mut self, timestamp: f64) {
// Lock the Mutex to get access to TrackManager
let mut track_manager = self.track_manager.lock().unwrap();
track_manager.play(Timestamp::new(timestamp));
}
pub fn get_timestamp(&mut self) -> f64 {
self.cpal_audio_output.get_timestamp().as_seconds()
}
}
struct PlainTextLogger;
impl Log for PlainTextLogger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= Level::Info
}
fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
console::log_1(&format!(
"{} [{}:{}] {}",
record.level(),
record.file().unwrap_or("unknown"),
record.line().unwrap_or(0),
record.args()
).into());
}
}
fn flush(&self) {}
}
pub fn init_plain_text_logger() -> Result<(), SetLoggerError> {
log::set_boxed_logger(Box::new(PlainTextLogger))?;
log::set_max_level(LevelFilter::Info);
Ok(())
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -106,6 +253,10 @@ pub fn main_js() -> Result<(), JsValue> {
// It's disabled in release mode so it doesn't bloat up the file size. // It's disabled in release mode so it doesn't bloat up the file size.
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
console_error_panic_hook::set_once(); console_error_panic_hook::set_once();
init_plain_text_logger().expect("Failed to initialize plain text logger");
log::info!("Logger initialized!");
Ok(()) Ok(())
} }

View File

@ -6,12 +6,21 @@ pub struct Timestamp(f64);
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, Copy, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)]
pub struct Duration(f64); pub struct Duration(f64);
/// A strongly-typed representation of a number of samples.
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)]
pub struct SampleCount(usize);
impl Timestamp { impl Timestamp {
/// Create a new timestamp in seconds. /// Create a new timestamp in seconds.
pub fn new(seconds: f64) -> Self { pub fn new(seconds: f64) -> Self {
Timestamp(seconds) Timestamp(seconds)
} }
/// Create a new timestamp from seconds. (dummy method)
pub fn from_seconds(seconds: f64) -> Self {
Timestamp(seconds)
}
/// Create a new timestamp from milliseconds. /// Create a new timestamp from milliseconds.
pub fn from_millis(milliseconds: u64) -> Self { pub fn from_millis(milliseconds: u64) -> Self {
Timestamp(milliseconds as f64 / 1000.0) Timestamp(milliseconds as f64 / 1000.0)
@ -41,6 +50,10 @@ impl Timestamp {
pub fn subtract_timestamp(&self, other: Timestamp) -> Duration { pub fn subtract_timestamp(&self, other: Timestamp) -> Duration {
Duration(self.0 - other.0) Duration(self.0 - other.0)
} }
pub fn set(&mut self, other: Timestamp) {
self.0 = other.as_seconds();
}
} }
impl Duration { impl Duration {
@ -79,6 +92,10 @@ impl Duration {
(self.0 * sample_rate as f64).round() as u64 (self.0 * sample_rate as f64).round() as u64
} }
pub fn to_std(&self) -> std::time::Duration {
std::time::Duration::from_nanos((self.0/1_000_000_000.0).round() as u64)
}
/// Add two durations together. /// Add two durations together.
pub fn add(&self, other: Duration) -> Duration { pub fn add(&self, other: Duration) -> Duration {
Duration(self.0 + other.0) Duration(self.0 + other.0)
@ -90,6 +107,18 @@ impl Duration {
} }
} }
impl SampleCount {
/// Create a new count of samples.
pub fn new(samples: usize) -> Self {
SampleCount(samples)
}
pub fn as_usize(&self) -> usize {
self.0
}
}
// Overloading operators for more natural usage // Overloading operators for more natural usage
use std::ops::{Add, Sub, AddAssign, SubAssign}; use std::ops::{Add, Sub, AddAssign, SubAssign};