Compare commits

..

3 Commits

Author SHA1 Message Date
Rekai Nyangadzayi Musuka ce630baa5d feat(snd): implement audio playback using rodio
continuous-integration/drone/push Build is failing Details
2021-07-09 01:25:52 -05:00
Rekai Nyangadzayi Musuka 0fa818a1a6 chore(snd): reimplement NR52 & implement sampling for ch2
Also add rodio as dependency for audio
2021-07-08 22:36:28 -05:00
Rekai Nyangadzayi Musuka 9b3a5d49d2 chore: update error messages in expect() calls 2021-07-08 18:50:58 -05:00
11 changed files with 639 additions and 60 deletions

488
Cargo.lock generated
View File

@ -25,6 +25,28 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "alsa"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75c4da790adcb2ce5e758c064b4f3ec17a30349f9961d3e5e6c9688b052a9e18"
dependencies = [
"alsa-sys",
"bitflags",
"libc",
"nix 0.20.0",
]
[[package]]
name = "alsa-sys"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527"
dependencies = [
"libc",
"pkg-config",
]
[[package]] [[package]]
name = "andrew" name = "andrew"
version = "0.3.1" version = "0.3.1"
@ -97,6 +119,25 @@ version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b"
[[package]]
name = "bindgen"
version = "0.56.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2da379dbebc0b76ef63ca68d8fc6e71c0f13e59432e0987e508c1820e6ab5239"
dependencies = [
"bitflags",
"cexpr",
"clang-sys",
"lazy_static",
"lazycell",
"peeking_take_while",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
]
[[package]] [[package]]
name = "bit-set" name = "bit-set"
version = "0.5.2" version = "0.5.2"
@ -148,6 +189,12 @@ version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
[[package]] [[package]]
name = "calloop" name = "calloop"
version = "0.6.5" version = "0.6.5"
@ -167,6 +214,21 @@ dependencies = [
"jobserver", "jobserver",
] ]
[[package]]
name = "cesu8"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
[[package]]
name = "cexpr"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
dependencies = [
"nom 5.1.2",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "0.1.10" version = "0.1.10"
@ -185,6 +247,17 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
[[package]]
name = "clang-sys"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c"
dependencies = [
"glob",
"libc",
"libloading 0.7.0",
]
[[package]] [[package]]
name = "clap" name = "clap"
version = "2.33.3" version = "2.33.3"
@ -200,6 +273,12 @@ dependencies = [
"vec_map", "vec_map",
] ]
[[package]]
name = "claxon"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bfbf56724aa9eca8afa4fcfadeb479e722935bb2a0900c2d37e0cc477af0688"
[[package]] [[package]]
name = "cocoa" name = "cocoa"
version = "0.24.0" version = "0.24.0"
@ -231,6 +310,16 @@ dependencies = [
"objc", "objc",
] ]
[[package]]
name = "combine"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2d47c1b11006b87e492b53b313bb699ce60e16613c4dddaa91f8f7c220ab2fa"
dependencies = [
"bytes",
"memchr",
]
[[package]] [[package]]
name = "copyless" name = "copyless"
version = "0.1.5" version = "0.1.5"
@ -335,6 +424,70 @@ dependencies = [
"objc", "objc",
] ]
[[package]]
name = "coreaudio-rs"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11894b20ebfe1ff903cbdc52259693389eea03b94918a2def2c30c3bf227ad88"
dependencies = [
"bitflags",
"coreaudio-sys",
]
[[package]]
name = "coreaudio-sys"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b7e3347be6a09b46aba228d6608386739fb70beff4f61e07422da87b0bb31fa"
dependencies = [
"bindgen",
]
[[package]]
name = "cpal"
version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8351ddf2aaa3c583fa388029f8b3d26f3c7035a20911fdd5f2e2ed7ab57dad25"
dependencies = [
"alsa",
"core-foundation-sys 0.6.2",
"coreaudio-rs",
"jni",
"js-sys",
"lazy_static",
"libc",
"mach 0.3.2",
"ndk 0.3.0",
"ndk-glue 0.3.0",
"nix 0.20.0",
"oboe",
"parking_lot",
"stdweb 0.1.3",
"thiserror",
"web-sys",
"winapi 0.3.9",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
dependencies = [
"cfg-if 1.0.0",
"lazy_static",
]
[[package]] [[package]]
name = "d3d12" name = "d3d12"
version = "0.3.2" version = "0.3.2"
@ -542,11 +695,13 @@ dependencies = [
"anyhow", "anyhow",
"bitfield", "bitfield",
"clap", "clap",
"crossbeam-channel",
"egui", "egui",
"egui_wgpu_backend", "egui_wgpu_backend",
"egui_winit_platform", "egui_winit_platform",
"gilrs", "gilrs",
"pixels", "pixels",
"rodio",
"winit", "winit",
"winit_input_helper", "winit_input_helper",
] ]
@ -735,12 +890,18 @@ dependencies = [
"log", "log",
"nix 0.20.0", "nix 0.20.0",
"rusty-xinput", "rusty-xinput",
"stdweb", "stdweb 0.4.20",
"uuid", "uuid",
"vec_map", "vec_map",
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]] [[package]]
name = "glow" name = "glow"
version = "0.7.2" version = "0.7.2"
@ -781,7 +942,7 @@ checksum = "e8a70f1e87a3840ed6a3e99e02c2b861e4dbdf26f0d07e38f42ea5aff46cfce2"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"gpu-descriptor-types", "gpu-descriptor-types",
"hashbrown", "hashbrown 0.9.1",
"tracing", "tracing",
] ]
@ -804,14 +965,26 @@ dependencies = [
] ]
[[package]] [[package]]
name = "hermit-abi" name = "hashbrown"
version = "0.1.18" version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "hound"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549"
[[package]] [[package]]
name = "ident_case" name = "ident_case"
version = "1.0.1" version = "1.0.1"
@ -820,12 +993,12 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.6.2" version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"hashbrown", "hashbrown 0.11.2",
] ]
[[package]] [[package]]
@ -850,7 +1023,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f21dcc74995dd4cd090b147e79789f8d65959cbfb5f0b118002db869ea3bd0a0" checksum = "f21dcc74995dd4cd090b147e79789f8d65959cbfb5f0b118002db869ea3bd0a0"
dependencies = [ dependencies = [
"core-foundation-sys 0.6.2", "core-foundation-sys 0.6.2",
"mach", "mach 0.2.3",
] ]
[[package]] [[package]]
@ -868,6 +1041,20 @@ version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "jni"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24967112a1e4301ca5342ea339763613a37592b8a6ce6cf2e4494537c7a42faf"
dependencies = [
"cesu8",
"combine",
"jni-sys",
"log",
"thiserror",
"walkdir",
]
[[package]] [[package]]
name = "jni-sys" name = "jni-sys"
version = "0.3.0" version = "0.3.0"
@ -925,10 +1112,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]] [[package]]
name = "libc" name = "lewton"
version = "0.2.97" version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" checksum = "777b48df9aaab155475a83a7df3070395ea1ac6902f5cd062b8f2b028075c030"
dependencies = [
"byteorder",
"ogg",
"tinyvec",
]
[[package]]
name = "libc"
version = "0.2.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
[[package]] [[package]]
name = "libloading" name = "libloading"
@ -987,6 +1185,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "mach"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "malloc_buf" name = "malloc_buf"
version = "0.0.6" version = "0.0.6"
@ -1031,6 +1238,26 @@ dependencies = [
"objc", "objc",
] ]
[[package]]
name = "minimp3"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "985438f75febf74c392071a975a29641b420dd84431135a6e6db721de4b74372"
dependencies = [
"minimp3-sys",
"slice-deque",
"thiserror",
]
[[package]]
name = "minimp3-sys"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e21c73734c69dc95696c9ed8926a2b393171d98b3f5f5935686a26a487ab9b90"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "mio" name = "mio"
version = "0.6.23" version = "0.6.23"
@ -1098,7 +1325,19 @@ checksum = "5eb167c1febed0a496639034d0c76b3b74263636045db5489eee52143c246e73"
dependencies = [ dependencies = [
"jni-sys", "jni-sys",
"ndk-sys", "ndk-sys",
"num_enum", "num_enum 0.4.3",
"thiserror",
]
[[package]]
name = "ndk"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8794322172319b972f528bf90c6b467be0079f1fa82780ffb431088e741a73ab"
dependencies = [
"jni-sys",
"ndk-sys",
"num_enum 0.5.1",
"thiserror", "thiserror",
] ]
@ -1111,7 +1350,21 @@ dependencies = [
"lazy_static", "lazy_static",
"libc", "libc",
"log", "log",
"ndk", "ndk 0.2.1",
"ndk-macro",
"ndk-sys",
]
[[package]]
name = "ndk-glue"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5caf0c24d51ac1c905c27d4eda4fa0635bbe0de596b8f79235e0b17a4d29385"
dependencies = [
"lazy_static",
"libc",
"log",
"ndk 0.3.0",
"ndk-macro", "ndk-macro",
"ndk-sys", "ndk-sys",
] ]
@ -1172,14 +1425,35 @@ dependencies = [
[[package]] [[package]]
name = "nom" name = "nom"
version = "6.2.0" version = "5.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "046a595c7251e2f48b291c1b65d98ef1df51dbfbad46e99a1ff09729535a779e" checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
dependencies = [ dependencies = [
"memchr", "memchr",
"version_check", "version_check",
] ]
[[package]]
name = "nom"
version = "6.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c5c51b9083a3c620fa67a2a635d1ce7d95b897e957d6b28ff9a5da960a103a6"
dependencies = [
"memchr",
"version_check",
]
[[package]]
name = "num-derive"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.14" version = "0.2.14"
@ -1196,7 +1470,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca565a7df06f3d4b485494f25ba05da1435950f4dc263440eda7a6fa9b8e36e4" checksum = "ca565a7df06f3d4b485494f25ba05da1435950f4dc263440eda7a6fa9b8e36e4"
dependencies = [ dependencies = [
"derivative", "derivative",
"num_enum_derive", "num_enum_derive 0.4.3",
]
[[package]]
name = "num_enum"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "226b45a5c2ac4dd696ed30fa6b94b057ad909c7b7fc2e0d0808192bced894066"
dependencies = [
"derivative",
"num_enum_derive 0.5.1",
] ]
[[package]] [[package]]
@ -1211,6 +1495,18 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "num_enum_derive"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c0fd9eba1d5db0994a239e09c1be402d35622277e35468ba891aa5e3188ce7e"
dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "objc" name = "objc"
version = "0.2.7" version = "0.2.7"
@ -1230,6 +1526,38 @@ dependencies = [
"cc", "cc",
] ]
[[package]]
name = "oboe"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfa187b38ae20374617b7ad418034ed3dc90ac980181d211518bd03537ae8f8d"
dependencies = [
"jni",
"ndk 0.3.0",
"ndk-glue 0.3.0",
"num-derive",
"num-traits",
"oboe-sys",
]
[[package]]
name = "oboe-sys"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b88e64835aa3f579c08d182526dc34e3907343d5b97e87b71a40ba5bca7aca9e"
dependencies = [
"cc",
]
[[package]]
name = "ogg"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6951b4e8bf21c8193da321bcce9c9dd2e13c858fe078bf9054a288b419ae5d6e"
dependencies = [
"byteorder",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.8.0" version = "1.8.0"
@ -1270,6 +1598,12 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.1.0" version = "2.1.0"
@ -1288,9 +1622,9 @@ dependencies = [
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.6" version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
[[package]] [[package]]
name = "pixels" name = "pixels"
@ -1368,6 +1702,40 @@ dependencies = [
"bitflags", "bitflags",
] ]
[[package]]
name = "regex"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "rodio"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d98f5e557b61525057e2bc142c8cd7f0e70d75dc32852309bec440e6e046bf9"
dependencies = [
"claxon",
"cpal",
"hound",
"lewton",
"minimp3",
]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.2.3" version = "0.2.3"
@ -1483,6 +1851,12 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
[[package]]
name = "shlex"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.3" version = "0.4.3"
@ -1490,10 +1864,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
[[package]] [[package]]
name = "slotmap" name = "slice-deque"
version = "0.4.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c46a3482db8f247956e464d783693ece164ca056e6e67563ee5505bdb86452cd" checksum = "31ef6ee280cdefba6d2d0b4b78a84a1c1a3f3a4cec98c2d4231c8bc225de0f25"
dependencies = [
"libc",
"mach 0.3.2",
"winapi 0.3.9",
]
[[package]]
name = "slotmap"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d61b40583e0c1bd3100652ba8940939decc8808e7b2a07f4f4606c6a8a40035a"
[[package]] [[package]]
name = "smallvec" name = "smallvec"
@ -1541,6 +1926,12 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "stdweb"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef5430c8e36b713e13b48a9f709cc21e046723fe44ce34587b73a830203b533e"
[[package]] [[package]]
name = "stdweb" name = "stdweb"
version = "0.4.20" version = "0.4.20"
@ -1635,18 +2026,18 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.25" version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.25" version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1659,6 +2050,21 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7572415bd688d401c52f6e36f4c8e805b9ae1622619303b9fa835d531db0acae" checksum = "7572415bd688d401c52f6e36f4c8e805b9ae1622619303b9fa835d531db0acae"
[[package]]
name = "tinyvec"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]] [[package]]
name = "toml" name = "toml"
version = "0.5.8" version = "0.5.8"
@ -1830,9 +2236,9 @@ checksum = "7e7811dd7f9398f14cc76efd356f98f03aa30419dea46aa810d71e819fc97158"
[[package]] [[package]]
name = "wayland-client" name = "wayland-client"
version = "0.28.5" version = "0.28.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ca44d86554b85cf449f1557edc6cc7da935cc748c8e4bf1c507cbd43bae02c" checksum = "e3ab332350e502f159382201394a78e3cc12d0f04db863429260164ea40e0355"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"downcast-rs", "downcast-rs",
@ -1846,9 +2252,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-commons" name = "wayland-commons"
version = "0.28.5" version = "0.28.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bd75ae380325dbcff2707f0cd9869827ea1d2d6d534cff076858d3f0460fd5a" checksum = "a21817947c7011bbd0a27e11b17b337bfd022e8544b071a2641232047966fbda"
dependencies = [ dependencies = [
"nix 0.20.0", "nix 0.20.0",
"once_cell", "once_cell",
@ -1858,9 +2264,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-cursor" name = "wayland-cursor"
version = "0.28.5" version = "0.28.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b37e5455ec72f5de555ec39b5c3704036ac07c2ecd50d0bffe02d5fe2d4e65ab" checksum = "be610084edd1586d45e7bdd275fe345c7c1873598caa464c4fb835dee70fa65a"
dependencies = [ dependencies = [
"nix 0.20.0", "nix 0.20.0",
"wayland-client", "wayland-client",
@ -1869,9 +2275,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-protocols" name = "wayland-protocols"
version = "0.28.5" version = "0.28.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95df3317872bcf9eec096c864b69aa4769a1d5d6291a5b513f8ba0af0efbd52c" checksum = "286620ea4d803bacf61fa087a4242ee316693099ee5a140796aaba02b29f861f"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"wayland-client", "wayland-client",
@ -1881,9 +2287,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-scanner" name = "wayland-scanner"
version = "0.28.5" version = "0.28.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "389d680d7bd67512dc9c37f39560224327038deb0f0e8d33f870900441b68720" checksum = "ce923eb2deb61de332d1f356ec7b6bf37094dc5573952e1c8936db03b54c03f1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1892,9 +2298,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-sys" name = "wayland-sys"
version = "0.28.5" version = "0.28.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2907bd297eef464a95ba9349ea771611771aa285b932526c633dc94d5400a8e2" checksum = "d841fca9aed7febf9bed2e9796c49bf58d4152ceda8ac949ebe00868d8f0feb8"
dependencies = [ dependencies = [
"dlib 0.5.0", "dlib 0.5.0",
"lazy_static", "lazy_static",
@ -2041,8 +2447,8 @@ dependencies = [
"log", "log",
"mio", "mio",
"mio-extras", "mio-extras",
"ndk", "ndk 0.2.1",
"ndk-glue", "ndk-glue 0.2.1",
"ndk-sys", "ndk-sys",
"objc", "objc",
"parking_lot", "parking_lot",
@ -2100,7 +2506,7 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a9a231574ae78801646617cefd13bfe94be907c0e4fa979cfd8b770aa3c5d08" checksum = "3a9a231574ae78801646617cefd13bfe94be907c0e4fa979cfd8b770aa3c5d08"
dependencies = [ dependencies = [
"nom", "nom 6.2.1",
] ]
[[package]] [[package]]

View File

@ -17,6 +17,8 @@ winit_input_helper = "^0.9"
egui = "^0.10" egui = "^0.10"
egui_wgpu_backend = { git="https://github.com/hasenbanck/egui_wgpu_backend.git", rev="9d03ad345d15d1e44165849b242d3562fdf3e859" } egui_wgpu_backend = { git="https://github.com/hasenbanck/egui_wgpu_backend.git", rev="9d03ad345d15d1e44165849b242d3562fdf3e859" }
egui_winit_platform = { git="https://github.com/hasenbanck/egui_winit_platform.git", rev="17298250e9721e8bf2c1d4a17b3e22777f8cb2e8" } egui_winit_platform = { git="https://github.com/hasenbanck/egui_winit_platform.git", rev="17298250e9721e8bf2c1d4a17b3e22777f8cb2e8" }
rodio = "^0.14"
crossbeam-channel = "^0.5"
[profile.release] [profile.release]
debug = true debug = true

View File

@ -4,7 +4,7 @@ use crate::interrupt::{Interrupt, InterruptFlag};
use crate::joypad::Joypad; use crate::joypad::Joypad;
use crate::ppu::{Ppu, PpuMode}; use crate::ppu::{Ppu, PpuMode};
use crate::serial::Serial; use crate::serial::Serial;
use crate::sound::Sound; use crate::sound::{SampleSender, Sound};
use crate::timer::Timer; use crate::timer::Timer;
use crate::work_ram::{VariableWorkRam, WorkRam}; use crate::work_ram::{VariableWorkRam, WorkRam};
use std::{fs::File, io::Read}; use std::{fs::File, io::Read};
@ -66,6 +66,10 @@ impl Bus {
self.cartridge.as_ref()?.title() self.cartridge.as_ref()?.title()
} }
pub(crate) fn pass_audio_src(&mut self, sender: SampleSender) {
self.snd.set_audio_src(sender)
}
pub(crate) fn clock(&mut self) { pub(crate) fn clock(&mut self) {
self.ppu.clock(); self.ppu.clock();
self.timer.clock(); self.timer.clock();
@ -233,7 +237,7 @@ impl BusIo for Bus {
0x23 => self.snd.ch4.freq_data(), 0x23 => self.snd.ch4.freq_data(),
0x24 => self.snd.ctrl.channel.into(), 0x24 => self.snd.ctrl.channel.into(),
0x25 => self.snd.ctrl.output.into(), 0x25 => self.snd.ctrl.output.into(),
0x26 => self.snd.ctrl.status.into(), 0x26 => self.snd.ctrl.status(&self.snd),
0x30..=0x3F => self.snd.ch3.wave_ram[addr as usize - 0xFF30], 0x30..=0x3F => self.snd.ch3.wave_ram[addr as usize - 0xFF30],
0x40 => self.ppu.ctrl.into(), 0x40 => self.ppu.ctrl.into(),
0x41 => self.ppu.stat.into(), 0x41 => self.ppu.stat.into(),
@ -351,7 +355,7 @@ impl BusIo for Bus {
0x23 => self.snd.ch4.set_freq_data(byte), 0x23 => self.snd.ch4.set_freq_data(byte),
0x24 => self.snd.ctrl.channel = byte.into(), 0x24 => self.snd.ctrl.channel = byte.into(),
0x25 => self.snd.ctrl.output = byte.into(), 0x25 => self.snd.ctrl.output = byte.into(),
0x26 => self.snd.ctrl.status = byte.into(), // FIXME: Should we control which bytes are written to here? 0x26 => self.snd.ctrl.set_status(byte), // FIXME: Should we control which bytes are written to here?
0x30..=0x3F => self.snd.ch3.wave_ram[addr as usize - 0xFF30] = byte, 0x30..=0x3F => self.snd.ch3.wave_ram[addr as usize - 0xFF30] = byte,
0x40 => self.ppu.ctrl = byte.into(), 0x40 => self.ppu.ctrl = byte.into(),
0x41 => self.ppu.stat.update(byte), 0x41 => self.ppu.stat.update(byte),

View File

@ -3,6 +3,7 @@ use crate::instruction::{Cycle, Instruction};
use crate::interrupt::{InterruptEnable, InterruptFlag}; use crate::interrupt::{InterruptEnable, InterruptFlag};
use crate::joypad::Joypad; use crate::joypad::Joypad;
use crate::ppu::Ppu; use crate::ppu::Ppu;
use crate::sound::SampleSender;
use crate::timer::Timer; use crate::timer::Timer;
use bitfield::bitfield; use bitfield::bitfield;
use std::fmt::{Display, Formatter, Result as FmtResult}; use std::fmt::{Display, Formatter, Result as FmtResult};
@ -44,6 +45,10 @@ impl Cpu {
}) })
} }
pub fn set_audio_src(&mut self, sender: SampleSender) {
self.bus.pass_audio_src(sender)
}
pub(crate) fn ime(&self) -> ImeState { pub(crate) fn ime(&self) -> ImeState {
self.ime self.ime
} }

View File

@ -4,11 +4,12 @@ use crate::joypad;
use crate::ppu::Ppu; use crate::ppu::Ppu;
use anyhow::Result; use anyhow::Result;
use gilrs::Gilrs; use gilrs::Gilrs;
use rodio::OutputStreamHandle;
use std::time::Duration; use std::time::Duration;
pub const SM83_CYCLE_TIME: Duration = Duration::from_nanos(1_000_000_000 / SM83_CLOCK_SPEED); pub const SM83_CYCLE_TIME: Duration = Duration::from_nanos(1_000_000_000 / SM83_CLOCK_SPEED);
pub const CYCLES_IN_FRAME: Cycle = Cycle::new(456 * 154); // 456 Cycles times 154 scanlines pub const CYCLES_IN_FRAME: Cycle = Cycle::new(456 * 154); // 456 Cycles times 154 scanlines
const SM83_CLOCK_SPEED: u64 = 0x40_0000; // Hz which is 4.194304Mhz pub(crate) const SM83_CLOCK_SPEED: u64 = 0x40_0000; // Hz which is 4.194304Mhz
const DEFAULT_TITLE: &str = "DMG-01 Emulator"; const DEFAULT_TITLE: &str = "DMG-01 Emulator";
pub fn init(boot_path: Option<&str>, rom_path: &str) -> Result<SM83> { pub fn init(boot_path: Option<&str>, rom_path: &str) -> Result<SM83> {

View File

@ -2277,13 +2277,13 @@ impl From<Cycle> for u32 {
impl InstrRegisterPair { impl InstrRegisterPair {
fn to_register_pair(self) -> RegisterPair { fn to_register_pair(self) -> RegisterPair {
RegisterPair::try_from(self).expect("Failed to convert InstrRegisterPair to RegisterPair") RegisterPair::try_from(self).expect("InstrRegisterPair is a valid RegisterPair")
} }
} }
impl InstrRegister { impl InstrRegister {
fn to_register(self) -> Register { fn to_register(self) -> Register {
Register::try_from(self).expect("Failed to convert from InstrRegister to Register") Register::try_from(self).expect("InstrRegister is a valid Register")
} }
} }

View File

@ -1,5 +1,6 @@
pub use gui::Egui; pub use gui::Egui;
pub use instruction::Cycle; pub use instruction::Cycle;
pub use sound::AudioSenderReceiver;
pub const GB_WIDTH: usize = 160; pub const GB_WIDTH: usize = 160;
pub const GB_HEIGHT: usize = 144; pub const GB_HEIGHT: usize = 144;

View File

@ -1,12 +1,14 @@
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use clap::{crate_authors, crate_description, crate_name, crate_version, App, Arg}; use clap::{crate_authors, crate_description, crate_name, crate_version, App, Arg};
use gb::{Cycle, Egui, GB_HEIGHT, GB_WIDTH}; use gb::{AudioSenderReceiver, Cycle, Egui, GB_HEIGHT, GB_WIDTH};
use gilrs::Gilrs; use gilrs::Gilrs;
use pixels::{Pixels, SurfaceTexture}; use pixels::{Pixels, SurfaceTexture};
use rodio::{OutputStream, Sink};
use std::time::Instant; use std::time::Instant;
use winit::dpi::LogicalSize; use winit::dpi::LogicalSize;
use winit::event::{Event, VirtualKeyCode}; use winit::event::{Event, VirtualKeyCode};
use winit::event_loop::{ControlFlow, EventLoop}; use winit::event_loop::{ControlFlow, EventLoop};
use winit::platform::windows::WindowBuilderExtWindows;
use winit::window::{Window, WindowBuilder}; use winit::window::{Window, WindowBuilder};
use winit_input_helper::WinitInputHelper; use winit_input_helper::WinitInputHelper;
@ -39,14 +41,16 @@ fn main() -> Result<()> {
// `rom` is a required value in every situation so this will // `rom` is a required value in every situation so this will
// always exist. // always exist.
let rom_path = m.value_of("rom").unwrap(); let rom_path = m
.value_of("rom")
.expect("Required value 'rom' was provided");
let mut game_boy = let mut game_boy =
gb::emu::init(m.value_of("boot"), rom_path).expect("Failed to initialize DMG-01 Emulator"); gb::emu::init(m.value_of("boot"), rom_path).expect("Initialized DMG-01 Emulator");
let cartridge_title = gb::emu::rom_title(&game_boy); let cartridge_title = gb::emu::rom_title(&game_boy);
// Initialize Gamepad Support // Initialize Gamepad Support
let mut gamepad = Gilrs::new().expect("Failed to initialize Gilrs"); let mut gamepad = Gilrs::new().expect("Initialized Gilrs for Controller Input");
// Initialize GUI // Initialize GUI
let event_loop = EventLoop::new(); let event_loop = EventLoop::new();
@ -63,6 +67,19 @@ fn main() -> Result<()> {
(pixels, egui) (pixels, egui)
}; };
let (send, recv) = AudioSenderReceiver::new();
game_boy.set_audio_src(send);
// Initialize Audio
let (_stream, stream_handle) = OutputStream::try_default().expect("Initialized Audio");
let sink = Sink::try_new(&stream_handle).expect("Initialize Audio Sink");
std::thread::spawn(move || {
sink.append(recv);
sink.sleep_until_end();
});
let mut now = Instant::now(); let mut now = Instant::now();
let mut cycle_count: Cycle = Default::default(); let mut cycle_count: Cycle = Default::default();
@ -133,5 +150,6 @@ fn create_window(event_loop: &EventLoop<()>, title: &str) -> Result<Window> {
.with_resizable(true) .with_resizable(true)
.with_decorations(true) .with_decorations(true)
.with_transparent(false) .with_transparent(false)
.with_drag_and_drop(false) // OleInitialize failed error if this is set to true
.build(event_loop)?) .build(event_loop)?)
} }

View File

@ -278,7 +278,7 @@ impl Ppu {
.obj .obj
.tile .tile
.bytes() .bytes()
.expect("Failed to unwrap Tile bytes"); .expect("Tile high & low bytes are present");
let tbpp = Pixels::from_bytes(high, low); let tbpp = Pixels::from_bytes(high, low);
@ -539,7 +539,7 @@ impl ObjectAttributeTable {
let slice: &[u8; 4] = self.buf[start..(start + 4)] let slice: &[u8; 4] = self.buf[start..(start + 4)]
.try_into() .try_into()
.expect("Could not interpret &[u8] as a &[u8; 4]"); .expect("TryInto trait called on a &[u8; 4]");
slice.into() slice.into()
} }
@ -704,7 +704,7 @@ impl PixelFetcher {
let scroll_y = pos.scroll_y; let scroll_y = pos.scroll_y;
let is_window = self.back.is_window_tile(); let is_window = self.back.is_window_tile();
let id = self.back.tile.id.expect("Tile Number unexpectedly missing"); let id = self.back.tile.id.expect("Tile Number is present");
let tile_data_addr = match control.tile_data_addr() { let tile_data_addr = match control.tile_data_addr() {
TileDataAddress::X8800 => 0x9000u16.wrapping_add(((id as i8) as i16 * 16) as u16), TileDataAddress::X8800 => 0x9000u16.wrapping_add(((id as i8) as i16 * 16) as u16),
@ -721,7 +721,11 @@ impl PixelFetcher {
} }
fn send_to_fifo(&self, fifo: &mut FifoRenderer, palette: &BackgroundPalette) { fn send_to_fifo(&self, fifo: &mut FifoRenderer, palette: &BackgroundPalette) {
let (high, low) = self.back.tile.bytes().expect("Failed to unwrap Tile bytes"); let (high, low) = self
.back
.tile
.bytes()
.expect("Tile high & low bytes are present");
let tbpp = Pixels::from_bytes(high, low); let tbpp = Pixels::from_bytes(high, low);

View File

@ -30,7 +30,7 @@ impl DirectMemoryAccess {
.start .start
.addr .addr
.as_mut() .as_mut()
.expect("DMA Transfer Attempted without a known source address"); .expect("Source Address present during DMA Transfer");
let addresses = if (self.cycle - 4) % 4 == 0 { let addresses = if (self.cycle - 4) % 4 == 0 {
*src_addr += 1; *src_addr += 1;

View File

@ -1,8 +1,15 @@
use bitfield::bitfield; use bitfield::bitfield;
use crossbeam_channel::{Receiver, Sender};
use rodio::Source;
use crate::emu::SM83_CLOCK_SPEED;
use crate::Cycle;
const WAVE_PATTERN_RAM_LEN: usize = 0x10; const WAVE_PATTERN_RAM_LEN: usize = 0x10;
const SAMPLE_RATE: u32 = 4800; // Hz
const SAMPLE_RATE_IN_CYCLES: Cycle = Cycle::new((SM83_CLOCK_SPEED / SAMPLE_RATE as u64) as u32);
#[derive(Debug, Clone, Copy, Default)] #[derive(Debug, Clone, Default)]
pub(crate) struct Sound { pub(crate) struct Sound {
pub(crate) ctrl: SoundControl, pub(crate) ctrl: SoundControl,
/// Tone & Sweep /// Tone & Sweep
@ -17,11 +24,15 @@ pub(crate) struct Sound {
// Frame Sequencer // Frame Sequencer
frame_seq_state: FrameSequencerState, frame_seq_state: FrameSequencerState,
div_prev: Option<u8>, div_prev: Option<u8>,
sender: Option<SampleSender>,
cycle: Cycle,
} }
impl Sound { impl Sound {
pub(crate) fn clock(&mut self, div: u16) { pub(crate) fn clock(&mut self, div: u16) {
use FrameSequencerState::*; use FrameSequencerState::*;
self.cycle += 1;
// the 5th bit of the high byte // the 5th bit of the high byte
let bit_5 = (div >> 13 & 0x01) as u8; let bit_5 = (div >> 13 & 0x01) as u8;
@ -49,6 +60,24 @@ impl Sound {
} }
self.div_prev = Some(bit_5); self.div_prev = Some(bit_5);
// TODO: Should the FrameSequencer be run first?
if self.cycle > SAMPLE_RATE_IN_CYCLES {
// Sample the APU
self.cycle %= SAMPLE_RATE_IN_CYCLES;
let left_sample = self.ch2.clock();
let right_sample = self.ch2.clock();
if let Some(send) = self.sender.as_ref() {
send.add_sample(left_sample);
send.add_sample(right_sample);
}
}
}
pub(crate) fn set_audio_src(&mut self, sender: SampleSender) {
self.sender = Some(sender);
} }
fn handle_length(&mut self) { fn handle_length(&mut self) {
@ -213,8 +242,25 @@ pub(crate) struct SoundControl {
pub(crate) channel: ChannelControl, pub(crate) channel: ChannelControl,
/// 0xFF25 | NR51 - Selection of Sound output terminal /// 0xFF25 | NR51 - Selection of Sound output terminal
pub(crate) output: SoundOutput, pub(crate) output: SoundOutput,
enabled: bool,
}
impl SoundControl {
/// 0xFF26 | NR52 - Sound On/Off /// 0xFF26 | NR52 - Sound On/Off
pub(crate) status: SoundStatus, pub fn status(&self, snd: &Sound) -> u8 {
(self.enabled as u8) << 7
| (snd.ch4.enabled as u8) << 3
| (snd.ch3.enabled as u8) << 2
| (snd.ch2.enabled as u8) << 1
| snd.ch1.enabled as u8
}
/// 0xFF26 | NR52 - Sound On/Off
pub fn set_status(&mut self, byte: u8) {
// TODO: Should all channel enabled fields be disabled when this is reset?
self.enabled = (byte >> 7) & 0x01 == 0x01;
}
} }
// TODO: What to do about the separation of freq bits // TODO: What to do about the separation of freq bits
@ -467,10 +513,25 @@ pub(crate) struct Channel2 {
// Length Functionality // Length Functionality
length_timer: u16, length_timer: u16,
freq_timer: u16,
duty_pos: u8,
enabled: bool, enabled: bool,
} }
impl Channel2 { impl Channel2 {
fn clock(&mut self) -> u8 {
self.freq_timer -= 1;
if self.freq_timer == 0 {
// TODO: Why is this 2048?
self.freq_timer = (2048 - self.frequency()) * 4;
self.duty_pos = (self.duty_pos + 1) % 8;
}
self.duty.wave_pattern().amplitude(self.duty_pos)
}
/// 0xFF16 | NR21 - Channel 2 Sound length / Wave Pattern Duty /// 0xFF16 | NR21 - Channel 2 Sound length / Wave Pattern Duty
pub(crate) fn duty(&self) -> u8 { pub(crate) fn duty(&self) -> u8 {
self.duty.into() self.duty.into()
@ -502,6 +563,10 @@ impl Channel2 {
} }
} }
} }
fn frequency(&self) -> u16 {
(self.freq_hi.freq_bits() as u16) << 8 | self.freq_lo as u16
}
} }
bitfield! { bitfield! {
@ -605,6 +670,20 @@ pub enum WavePattern {
ThreeQuarters = 3, // 75% ( ______--______--______-- ) ThreeQuarters = 3, // 75% ( ______--______--______-- )
} }
impl WavePattern {
pub const fn amplitude(&self, index: u8) -> u8 {
use WavePattern::*;
let i = 7 - index; // an index of 0 should get the highest bit
match *self {
OneEighth => (0b00000001 >> i) & 0x01,
OneQuarter => (0b10000001 >> i) & 0x01,
OneHalf => (0b10000111 >> i) & 0x01,
ThreeQuarters => (0b01111110 >> i) & 0x01,
}
}
}
impl Default for WavePattern { impl Default for WavePattern {
fn default() -> Self { fn default() -> Self {
Self::OneEighth // Rationale: OneEighth is 0x00 Self::OneEighth // Rationale: OneEighth is 0x00
@ -947,3 +1026,62 @@ impl From<ChannelControl> for u8 {
ctrl.0 ctrl.0
} }
} }
pub struct AudioSenderReceiver;
impl AudioSenderReceiver {
pub fn new() -> (SampleSender, SampleReceiver) {
let (send, recv) = crossbeam_channel::unbounded();
(SampleSender { send }, SampleReceiver { recv })
}
}
#[derive(Debug, Clone)]
pub struct SampleSender {
send: Sender<u8>,
}
impl SampleSender {
fn add_sample(&self, sample: u8) {
self.send
.send(sample)
.expect("Send audio sample across threads");
}
}
pub struct SampleReceiver {
recv: Receiver<u8>,
}
impl Iterator for SampleReceiver {
type Item = f32;
fn next(&mut self) -> Option<Self::Item> {
// TODO: Should this never return none?
self.recv.recv().ok().map(|num| num as f32)
}
}
impl Source for SampleReceiver {
fn current_frame_len(&self) -> Option<usize> {
// A frame changes when the samples rate or
// number of channels change. This will never happen, so
// we return
None
}
fn channels(&self) -> u16 {
// The Gameboy supports two channels
2
}
fn sample_rate(&self) -> u32 {
SAMPLE_RATE
}
fn total_duration(&self) -> Option<std::time::Duration> {
// The duration of this source is infinite
None
}
}