Backed out 2 changesets (bug 1670633) as requested for causing Bug 1866014. CLOSED TREE
Backed out changeset be8e9a8eaa80 (bug 1670633) Backed out changeset bace8b9c91dc (bug 1670633)
This commit is contained in:
@@ -65,9 +65,9 @@ git = "https://github.com/mozilla/audioipc"
|
||||
rev = "6be424d75f1367e70f2f5ddcacd6d0237e81a6a9"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/mozilla/cubeb-coreaudio-rs?rev=964e14628f285ad44522bdeeb566c1864ecd2fd8"]
|
||||
[source."git+https://github.com/mozilla/cubeb-coreaudio-rs?rev=93b5c01a131f65c83c11aeb317f4583405c5eb79"]
|
||||
git = "https://github.com/mozilla/cubeb-coreaudio-rs"
|
||||
rev = "964e14628f285ad44522bdeeb566c1864ecd2fd8"
|
||||
rev = "93b5c01a131f65c83c11aeb317f4583405c5eb79"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/mozilla/cubeb-pulse-rs?rev=cf48897be5cbe147d051ebbbe1eaf5fd8fb6bbc9"]
|
||||
|
||||
28
Cargo.lock
generated
28
Cargo.lock
generated
@@ -432,14 +432,14 @@ dependencies = [
|
||||
name = "bindgen"
|
||||
version = "0.66.999"
|
||||
dependencies = [
|
||||
"bindgen 0.69.1",
|
||||
"bindgen 0.68.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.69.1"
|
||||
version = "0.68.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ffcebc3849946a7170a05992aac39da343a90676ab392c51a4280981d6379c2"
|
||||
checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078"
|
||||
dependencies = [
|
||||
"bitflags 2.4.0",
|
||||
"cexpr",
|
||||
@@ -584,7 +584,7 @@ dependencies = [
|
||||
name = "builtins-static"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bindgen 0.69.1",
|
||||
"bindgen 0.68.1",
|
||||
"mozilla-central-workspace-hack",
|
||||
"nom",
|
||||
"pkcs11-bindings",
|
||||
@@ -885,17 +885,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "coreaudio-sys"
|
||||
version = "0.2.14"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3120ebb80a9de008e638ad833d4127d50ea3d3a960ea23ea69bc66d9358a028"
|
||||
checksum = "d8478e5bdad14dce236b9898ea002eabfa87cbe14f0aa538dbe3b6a4bec4332d"
|
||||
dependencies = [
|
||||
"bindgen 0.69.1",
|
||||
"bindgen 0.68.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "coreaudio-sys-utils"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/cubeb-coreaudio-rs?rev=964e14628f285ad44522bdeeb566c1864ecd2fd8#964e14628f285ad44522bdeeb566c1864ecd2fd8"
|
||||
source = "git+https://github.com/mozilla/cubeb-coreaudio-rs?rev=93b5c01a131f65c83c11aeb317f4583405c5eb79#93b5c01a131f65c83c11aeb317f4583405c5eb79"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"coreaudio-sys",
|
||||
@@ -1106,11 +1106,11 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cubeb-coreaudio"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/cubeb-coreaudio-rs?rev=964e14628f285ad44522bdeeb566c1864ecd2fd8#964e14628f285ad44522bdeeb566c1864ecd2fd8"
|
||||
source = "git+https://github.com/mozilla/cubeb-coreaudio-rs?rev=93b5c01a131f65c83c11aeb317f4583405c5eb79#93b5c01a131f65c83c11aeb317f4583405c5eb79"
|
||||
dependencies = [
|
||||
"atomic",
|
||||
"audio-mixer",
|
||||
"bitflags 2.4.0",
|
||||
"bitflags 1.999.999",
|
||||
"coreaudio-sys-utils",
|
||||
"cubeb-backend",
|
||||
"float-cmp",
|
||||
@@ -2020,7 +2020,7 @@ name = "gecko-profiler"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bindgen 0.69.1",
|
||||
"bindgen 0.68.1",
|
||||
"lazy_static",
|
||||
"mozbuild",
|
||||
"profiler-macros",
|
||||
@@ -2562,7 +2562,7 @@ name = "http3server"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"base64 0.21.3",
|
||||
"bindgen 0.69.1",
|
||||
"bindgen 0.68.1",
|
||||
"cfg-if 1.0.0",
|
||||
"http",
|
||||
"hyper",
|
||||
@@ -3632,7 +3632,7 @@ name = "mozilla-central-workspace-hack"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bindgen 0.69.1",
|
||||
"bindgen 0.68.1",
|
||||
"bitflags 2.4.0",
|
||||
"bytes",
|
||||
"chrono",
|
||||
@@ -5234,7 +5234,7 @@ dependencies = [
|
||||
"app_units",
|
||||
"arrayvec",
|
||||
"atomic_refcell",
|
||||
"bindgen 0.69.1",
|
||||
"bindgen 0.68.1",
|
||||
"bitflags 2.4.0",
|
||||
"byteorder",
|
||||
"cssparser",
|
||||
|
||||
@@ -137,7 +137,7 @@ wasi = { path = "build/rust/wasi" }
|
||||
# else we do use requires backtrace, so dummy it out for now.
|
||||
backtrace = { path = "build/rust/backtrace" }
|
||||
|
||||
# Patch bindgen 0.63, 0.64 and 0.66 to 0.69
|
||||
# Patch bindgen 0.63, 0.64 and 0.66 to 0.68
|
||||
bindgen_0_63 = { package = "bindgen", path = "build/rust/bindgen-0.63" }
|
||||
bindgen_0_64 = { package = "bindgen", path = "build/rust/bindgen-0.64" }
|
||||
bindgen = { path = "build/rust/bindgen" }
|
||||
|
||||
@@ -8,7 +8,7 @@ license = "BSD-3-Clause"
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies.bindgen]
|
||||
version = "0.69.0"
|
||||
version = "0.68.0"
|
||||
default-features = false
|
||||
|
||||
[features]
|
||||
|
||||
@@ -52,7 +52,7 @@ uuid = { version = "1", features = ["serde", "v4"], optional = true }
|
||||
scopeguard = { version = "1", optional = true }
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = { version = "0.69", default-features = false, features = ["runtime"], optional = true }
|
||||
bindgen = { version = "0.68", default-features = false, features = ["runtime"], optional = true }
|
||||
libc = "0.2"
|
||||
memchr = { version = "2", optional = true }
|
||||
nom = { version = "7", optional = true }
|
||||
|
||||
@@ -28,7 +28,7 @@ features = ["gecko"]
|
||||
|
||||
# Make sure to use bindgen's runtime-loading of libclang, as it allows for a wider range of clang versions to be used
|
||||
[build-dependencies]
|
||||
bindgen = {version = "0.69", default-features = false, features = ["runtime"] }
|
||||
bindgen = {version = "0.68", default-features = false, features = ["runtime"] }
|
||||
|
||||
[[bin]]
|
||||
name = "http3server"
|
||||
|
||||
@@ -11,7 +11,7 @@ smallvec = { version = "1.9.0", features = ["const_new"] }
|
||||
mozilla-central-workspace-hack = { version = "0.1", features = ["builtins-static"], optional = true }
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = { default-features = false, features = ["runtime"], version = "0.69" }
|
||||
bindgen = { default-features = false, features = ["runtime"], version = "0.68" }
|
||||
nom = "7.1.1"
|
||||
|
||||
[lib]
|
||||
|
||||
@@ -84,7 +84,7 @@ gecko-profiler = { path = "../../../tools/profiler/rust-api" }
|
||||
[build-dependencies]
|
||||
lazy_static = "1"
|
||||
log = { version = "0.4", features = ["std"] }
|
||||
bindgen = {version = "0.69", optional = true, default-features = false}
|
||||
bindgen = {version = "0.68", optional = true, default-features = false}
|
||||
regex = {version = "1.0", optional = true, default-features = false, features = ["perf", "std"]}
|
||||
walkdir = "2.1.4"
|
||||
toml = {version = "0.5", optional = true, default-features = false}
|
||||
|
||||
@@ -681,11 +681,6 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.66.1 -> 0.68.1"
|
||||
|
||||
[[audits.bindgen]]
|
||||
who = "Andreas Pehrson <apehrson@mozilla.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.68.1 -> 0.69.1"
|
||||
|
||||
[[audits.bit-set]]
|
||||
who = "Aria Beingessner <a.beingessner@gmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
@@ -886,11 +881,6 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.2.12 -> 0.2.13"
|
||||
|
||||
[[audits.coreaudio-sys]]
|
||||
who = "Andreas Pehrson <apehrson@mozilla.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.2.13 -> 0.2.14"
|
||||
|
||||
[[audits.cose]]
|
||||
who = "Mathew Hodson <mathew.hodson@gmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
File diff suppressed because one or more lines are too long
19
third_party/rust/bindgen/Cargo.toml
vendored
19
third_party/rust/bindgen/Cargo.toml
vendored
@@ -13,7 +13,7 @@
|
||||
edition = "2018"
|
||||
rust-version = "1.60.0"
|
||||
name = "bindgen"
|
||||
version = "0.69.1"
|
||||
version = "0.68.1"
|
||||
authors = [
|
||||
"Jyun-Yan You <jyyou.tw@gmail.com>",
|
||||
"Emilio Cobos Álvarez <emilio@crisal.io>",
|
||||
@@ -41,25 +41,8 @@ repository = "https://github.com/rust-lang/rust-bindgen"
|
||||
features = ["experimental"]
|
||||
|
||||
[package.metadata.release]
|
||||
pre-release-hook = [
|
||||
"../node_modules/doctoc/doctoc.js",
|
||||
"../CHANGELOG.md",
|
||||
]
|
||||
release = true
|
||||
|
||||
[[package.metadata.release.pre-release-replacements]]
|
||||
file = "../CHANGELOG.md"
|
||||
replace = """
|
||||
# Unreleased
|
||||
## Added
|
||||
## Changed
|
||||
## Removed
|
||||
## Fixed
|
||||
## Security
|
||||
|
||||
# {{version}} ({{date}})"""
|
||||
search = "# Unreleased"
|
||||
|
||||
[lib]
|
||||
name = "bindgen"
|
||||
path = "lib.rs"
|
||||
|
||||
3
third_party/rust/bindgen/callbacks.rs
vendored
3
third_party/rust/bindgen/callbacks.rs
vendored
@@ -99,9 +99,6 @@ pub trait ParseCallbacks: fmt::Debug {
|
||||
None
|
||||
}
|
||||
|
||||
/// This will be called on every header filename passed to (`Builder::header`)[`crate::Builder::header`].
|
||||
fn header_file(&self, _filename: &str) {}
|
||||
|
||||
/// This will be called on every file inclusion, with the full path of the included file.
|
||||
fn include_file(&self, _filename: &str) {}
|
||||
|
||||
|
||||
2
third_party/rust/bindgen/clang.rs
vendored
2
third_party/rust/bindgen/clang.rs
vendored
@@ -1820,7 +1820,7 @@ impl TranslationUnit {
|
||||
let fname = CString::new(file).unwrap();
|
||||
let _c_args: Vec<CString> = cmd_args
|
||||
.iter()
|
||||
.map(|s| CString::new(s.as_bytes()).unwrap())
|
||||
.map(|s| CString::new(s.clone().into_boxed_bytes()).unwrap())
|
||||
.collect();
|
||||
let c_args: Vec<*const c_char> =
|
||||
_c_args.iter().map(|s| s.as_ptr()).collect();
|
||||
|
||||
19
third_party/rust/bindgen/codegen/error.rs
vendored
19
third_party/rust/bindgen/codegen/error.rs
vendored
@@ -14,36 +14,25 @@ pub(crate) enum Error {
|
||||
|
||||
/// Function ABI is not supported.
|
||||
UnsupportedAbi(&'static str),
|
||||
|
||||
/// The pointer type size does not match the target's pointer size.
|
||||
InvalidPointerSize {
|
||||
ty_name: String,
|
||||
ty_size: usize,
|
||||
ptr_size: usize,
|
||||
},
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
f.write_str(match *self {
|
||||
Error::NoLayoutForOpaqueBlob => {
|
||||
"Tried to generate an opaque blob, but had no layout.".fmt(f)
|
||||
"Tried to generate an opaque blob, but had no layout."
|
||||
}
|
||||
Error::InstantiationOfOpaqueType => {
|
||||
"Instantiation of opaque template type or partial template specialization."
|
||||
.fmt(f)
|
||||
}
|
||||
Error::UnsupportedAbi(abi) => {
|
||||
write!(
|
||||
return write!(
|
||||
f,
|
||||
"{} ABI is not supported by the configured Rust target.",
|
||||
abi
|
||||
)
|
||||
}
|
||||
Error::InvalidPointerSize { ty_name, ty_size, ptr_size } => {
|
||||
write!(f, "The {} pointer type has size {} but the current target's pointer size is {}.", ty_name, ty_size, ptr_size)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
11
third_party/rust/bindgen/codegen/mod.rs
vendored
11
third_party/rust/bindgen/codegen/mod.rs
vendored
@@ -21,7 +21,6 @@ use self::struct_layout::StructLayoutTracker;
|
||||
use super::BindgenOptions;
|
||||
|
||||
use crate::callbacks::{DeriveInfo, FieldInfo, TypeKind as DeriveTypeKind};
|
||||
use crate::codegen::error::Error;
|
||||
use crate::ir::analysis::{HasVtable, Sizedness};
|
||||
use crate::ir::annotations::{
|
||||
Annotations, FieldAccessorKind, FieldVisibilityKind,
|
||||
@@ -3924,16 +3923,6 @@ impl TryToRustTy for Type {
|
||||
}
|
||||
TypeKind::Opaque => self.try_to_opaque(ctx, item),
|
||||
TypeKind::Pointer(inner) | TypeKind::Reference(inner) => {
|
||||
// Check that this type has the same size as the target's pointer type.
|
||||
let size = self.get_layout(ctx, item).size;
|
||||
if size != ctx.target_pointer_size() {
|
||||
return Err(Error::InvalidPointerSize {
|
||||
ty_name: self.name().unwrap_or("unknown").into(),
|
||||
ty_size: size,
|
||||
ptr_size: ctx.target_pointer_size(),
|
||||
});
|
||||
}
|
||||
|
||||
let is_const = ctx.resolve_type(inner).is_const();
|
||||
|
||||
let inner =
|
||||
|
||||
35
third_party/rust/bindgen/codegen/serialize.rs
vendored
35
third_party/rust/bindgen/codegen/serialize.rs
vendored
@@ -322,26 +322,21 @@ impl<'a> CSerialize<'a> for Type {
|
||||
}
|
||||
write!(writer, ")")?;
|
||||
|
||||
let args = signature.argument_types();
|
||||
if args.is_empty() {
|
||||
write!(writer, " (void)")?;
|
||||
} else {
|
||||
write!(writer, " (")?;
|
||||
serialize_sep(
|
||||
", ",
|
||||
args.iter(),
|
||||
ctx,
|
||||
writer,
|
||||
|(name, type_id), ctx, buf| {
|
||||
let mut stack = vec![];
|
||||
if let Some(name) = name {
|
||||
stack.push(name.clone());
|
||||
}
|
||||
type_id.serialize(ctx, (), &mut stack, buf)
|
||||
},
|
||||
)?;
|
||||
write!(writer, ")")?
|
||||
}
|
||||
write!(writer, " (")?;
|
||||
serialize_sep(
|
||||
", ",
|
||||
signature.argument_types().iter(),
|
||||
ctx,
|
||||
writer,
|
||||
|(name, type_id), ctx, buf| {
|
||||
let mut stack = vec![];
|
||||
if let Some(name) = name {
|
||||
stack.push(name.clone());
|
||||
}
|
||||
type_id.serialize(ctx, (), &mut stack, buf)
|
||||
},
|
||||
)?;
|
||||
write!(writer, ")")?
|
||||
}
|
||||
TypeKind::ResolvedTypeRef(type_id) => {
|
||||
if self.is_const() {
|
||||
|
||||
13
third_party/rust/bindgen/ir/analysis/mod.rs
vendored
13
third_party/rust/bindgen/ir/analysis/mod.rs
vendored
@@ -334,13 +334,20 @@ mod tests {
|
||||
// Yes, what follows is a **terribly** inefficient set union
|
||||
// implementation. Don't copy this code outside of this test!
|
||||
|
||||
let original_size = self.reachable.entry(node).or_default().len();
|
||||
let original_size = self
|
||||
.reachable
|
||||
.entry(node)
|
||||
.or_insert_with(HashSet::default)
|
||||
.len();
|
||||
|
||||
for sub_node in self.graph.0[&node].iter() {
|
||||
self.reachable.get_mut(&node).unwrap().insert(*sub_node);
|
||||
|
||||
let sub_reachable =
|
||||
self.reachable.entry(*sub_node).or_default().clone();
|
||||
let sub_reachable = self
|
||||
.reachable
|
||||
.entry(*sub_node)
|
||||
.or_insert_with(HashSet::default)
|
||||
.clone();
|
||||
|
||||
for transitive in sub_reachable {
|
||||
self.reachable.get_mut(&node).unwrap().insert(transitive);
|
||||
|
||||
6
third_party/rust/bindgen/ir/item.rs
vendored
6
third_party/rust/bindgen/ir/item.rs
vendored
@@ -98,13 +98,13 @@ pub(crate) trait ItemAncestors {
|
||||
fn ancestors<'a>(&self, ctx: &'a BindgenContext) -> ItemAncestorsIter<'a>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "__testing_only_extra_assertions")]
|
||||
#[cfg(__testing_only_extra_assertions)]
|
||||
type DebugOnlyItemSet = ItemSet;
|
||||
|
||||
#[cfg(not(feature = "__testing_only_extra_assertions"))]
|
||||
#[cfg(not(__testing_only_extra_assertions))]
|
||||
struct DebugOnlyItemSet;
|
||||
|
||||
#[cfg(not(feature = "__testing_only_extra_assertions"))]
|
||||
#[cfg(not(__testing_only_extra_assertions))]
|
||||
impl DebugOnlyItemSet {
|
||||
fn new() -> Self {
|
||||
DebugOnlyItemSet
|
||||
|
||||
17
third_party/rust/bindgen/ir/objc.rs
vendored
17
third_party/rust/bindgen/ir/objc.rs
vendored
@@ -253,24 +253,11 @@ impl ObjCMethod {
|
||||
let split_name: Vec<Option<Ident>> = self
|
||||
.name
|
||||
.split(':')
|
||||
.enumerate()
|
||||
.map(|(idx, name)| {
|
||||
.map(|name| {
|
||||
if name.is_empty() {
|
||||
None
|
||||
} else if idx == 0 {
|
||||
// Try to parse the method name as an identifier. Having a keyword is ok
|
||||
// unless it is `crate`, `self`, `super` or `Self`, so we try to add the `_`
|
||||
// suffix to it and parse it.
|
||||
if ["crate", "self", "super", "Self"].contains(&name) {
|
||||
Some(Ident::new(
|
||||
&format!("{}_", name),
|
||||
Span::call_site(),
|
||||
))
|
||||
} else {
|
||||
Some(Ident::new(name, Span::call_site()))
|
||||
}
|
||||
} else {
|
||||
// Try to parse the current joining name as an identifier. This might fail if the name
|
||||
// Try to parse the current name as an identifier. This might fail if the name
|
||||
// is a keyword, so we try to "r#" to it and parse again, this could also fail
|
||||
// if the name is `crate`, `self`, `super` or `Self`, so we try to add the `_`
|
||||
// suffix to it and parse again. If this also fails, we panic with the first
|
||||
|
||||
52
third_party/rust/bindgen/lib.rs
vendored
52
third_party/rust/bindgen/lib.rs
vendored
@@ -325,11 +325,6 @@ impl Builder {
|
||||
.map(String::into_boxed_str),
|
||||
);
|
||||
|
||||
for header in &self.options.input_headers {
|
||||
self.options
|
||||
.for_each_callback(|cb| cb.header_file(header.as_ref()));
|
||||
}
|
||||
|
||||
// Transform input headers to arguments on the clang command line.
|
||||
self.options.clang_args.extend(
|
||||
self.options.input_headers
|
||||
@@ -571,10 +566,6 @@ impl BindgenOptions {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn for_each_callback(&self, f: impl Fn(&dyn callbacks::ParseCallbacks)) {
|
||||
self.parse_callbacks.iter().for_each(|cb| f(cb.as_ref()));
|
||||
}
|
||||
|
||||
fn process_comment(&self, comment: &str) -> String {
|
||||
let comment = comment::preprocess(comment);
|
||||
self.parse_callbacks
|
||||
@@ -1241,50 +1232,9 @@ fn get_target_dependent_env_var(
|
||||
/// .generate();
|
||||
/// ```
|
||||
#[derive(Debug)]
|
||||
pub struct CargoCallbacks {
|
||||
rerun_on_header_files: bool,
|
||||
}
|
||||
|
||||
/// Create a new `CargoCallbacks` value with [`CargoCallbacks::rerun_on_header_files`] disabled.
|
||||
///
|
||||
/// This constructor has been deprecated in favor of [`CargoCallbacks::new`] where
|
||||
/// [`CargoCallbacks::rerun_on_header_files`] is enabled by default.
|
||||
#[deprecated = "Use `CargoCallbacks::new()` instead. Please, check the documentation for further information."]
|
||||
pub const CargoCallbacks: CargoCallbacks = CargoCallbacks {
|
||||
rerun_on_header_files: false,
|
||||
};
|
||||
|
||||
impl CargoCallbacks {
|
||||
/// Create a new `CargoCallbacks` value.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
rerun_on_header_files: true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether Cargo should re-run the build script if any of the input header files has changed.
|
||||
///
|
||||
/// This option is enabled by default unless the deprecated [`const@CargoCallbacks`]
|
||||
/// constructor is used.
|
||||
pub fn rerun_on_header_files(mut self, doit: bool) -> Self {
|
||||
self.rerun_on_header_files = doit;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CargoCallbacks {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
pub struct CargoCallbacks;
|
||||
|
||||
impl callbacks::ParseCallbacks for CargoCallbacks {
|
||||
fn header_file(&self, filename: &str) {
|
||||
if self.rerun_on_header_files {
|
||||
println!("cargo:rerun-if-changed={}", filename);
|
||||
}
|
||||
}
|
||||
|
||||
fn include_file(&self, filename: &str) {
|
||||
println!("cargo:rerun-if-changed={}", filename);
|
||||
}
|
||||
|
||||
2
third_party/rust/bindgen/options/mod.rs
vendored
2
third_party/rust/bindgen/options/mod.rs
vendored
@@ -1374,7 +1374,7 @@ options! {
|
||||
/// or `-fno-inline-functions` if you are responsible of compiling the library to make
|
||||
/// them callable.
|
||||
#[cfg_attr(
|
||||
feature = "experimental",
|
||||
features = "experimental",
|
||||
doc = "\nCheck the [`Builder::wrap_static_fns`] method for an alternative."
|
||||
)]
|
||||
pub fn generate_inline_functions(mut self, doit: bool) -> Self {
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"87292d055a2fc0f070f54abd549a5f79ec8ac33611ecde80ba394f256b88294c","src/aggregate_device.rs":"7d2bd5f5fd7f3d008ebb69ad81f522ca0cb73db6d7b3e50ed1a63ea26ff721f4","src/audio_object.rs":"5447179330a862659a25bceedfdc5d29a1296f63490908d1c868c6b21c5f95a1","src/audio_unit.rs":"d783878930df4923b57ad230138c0f3fd6b0b9bb80a39725092ff4c6615162d8","src/cf_mutable_dict.rs":"fc42edd270c6dfb02f123214d2d8e487bbd62b5bd923b71eec13190fd0104d2a","src/dispatch.rs":"f6267fe587217c3d3ad5fe7f3a35955221c936103bf853c477a2e44eba5f1e46","src/lib.rs":"bcc559d69ef6ed0cbea5b2a36fec89d8c011eb9da70e2f26c00f881ad97a2546","src/string.rs":"28f88b816c768bcfcc674a60d962b93f1c94e5e0f4cc8ed2a1301138b91039e7"},"package":null}
|
||||
{"files":{"Cargo.toml":"d15a17e76eddf5088ad0b09544704479b3269ef1bc9060118bda7e87ed499eab","src/aggregate_device.rs":"7d2bd5f5fd7f3d008ebb69ad81f522ca0cb73db6d7b3e50ed1a63ea26ff721f4","src/audio_object.rs":"5447179330a862659a25bceedfdc5d29a1296f63490908d1c868c6b21c5f95a1","src/audio_unit.rs":"d783878930df4923b57ad230138c0f3fd6b0b9bb80a39725092ff4c6615162d8","src/cf_mutable_dict.rs":"fc42edd270c6dfb02f123214d2d8e487bbd62b5bd923b71eec13190fd0104d2a","src/dispatch.rs":"82ca429be8f930db730c7c571d6f2246e59e82ecb220b5290a3cf4a53e997053","src/lib.rs":"bcc559d69ef6ed0cbea5b2a36fec89d8c011eb9da70e2f26c00f881ad97a2546","src/string.rs":"28f88b816c768bcfcc674a60d962b93f1c94e5e0f4cc8ed2a1301138b91039e7"},"package":null}
|
||||
@@ -20,10 +20,9 @@ license = "ISC"
|
||||
version = "0.8"
|
||||
|
||||
[dependencies.coreaudio-sys]
|
||||
version = "0.2.14"
|
||||
version = "0.2"
|
||||
features = [
|
||||
"audio_unit",
|
||||
"core_audio",
|
||||
"io_kit_audio",
|
||||
]
|
||||
default-features = false
|
||||
|
||||
@@ -22,16 +22,6 @@ impl Queue {
|
||||
queue
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
pub fn debug_assert_is_current(&self) {
|
||||
unsafe {
|
||||
dispatch_assert_queue(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
pub fn debug_assert_is_current(&self) {}
|
||||
|
||||
pub fn run_async<F>(&self, work: F)
|
||||
where
|
||||
F: Send + FnOnce(),
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"21b0b00002a9b66a31357ddc5ac4c0f2a1702c85f6303cc7309e9dc7ffcaefd8","LICENSE":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","README.md":"a8adeaf1947035175b890109b36604ac3676f887911b5b8debd216689c0b65bd","build.rs":"d109f0a043b4f62bee52674888a52595f9b0dc37345815905a12ad0723ab8de5","src/lib.rs":"22c9dbbb1dc38d6f77b9362e806a7ee59a8ca1aa9b2c9344d1a487a91287ed59"},"package":"f3120ebb80a9de008e638ad833d4127d50ea3d3a960ea23ea69bc66d9358a028"}
|
||||
{"files":{"Cargo.toml":"17c9796d79b692e07056a6f6b45fcb8160c98385d9dd46c3a3d67a02865b3d33","LICENSE":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","README.md":"a8adeaf1947035175b890109b36604ac3676f887911b5b8debd216689c0b65bd","build.rs":"e3d45b1a17b655996a09b1d8f5f4dabb8c574e5b803814a13494f56dfce32f4e","src/lib.rs":"22c9dbbb1dc38d6f77b9362e806a7ee59a8ca1aa9b2c9344d1a487a91287ed59"},"package":"d8478e5bdad14dce236b9898ea002eabfa87cbe14f0aa538dbe3b6a4bec4332d"}
|
||||
5
third_party/rust/coreaudio-sys/Cargo.toml
vendored
5
third_party/rust/coreaudio-sys/Cargo.toml
vendored
@@ -11,7 +11,7 @@
|
||||
|
||||
[package]
|
||||
name = "coreaudio-sys"
|
||||
version = "0.2.14"
|
||||
version = "0.2.13"
|
||||
authors = ["Mitchell Nordine <mitchell.nordine@gmail.com>"]
|
||||
build = "build.rs"
|
||||
description = "Bindings for Apple's CoreAudio frameworks generated via rust-bindgen"
|
||||
@@ -36,7 +36,7 @@ targets = [
|
||||
]
|
||||
|
||||
[build-dependencies.bindgen]
|
||||
version = "0.69"
|
||||
version = "0.68"
|
||||
features = ["runtime"]
|
||||
default-features = false
|
||||
|
||||
@@ -52,5 +52,4 @@ default = [
|
||||
"open_al",
|
||||
"core_midi",
|
||||
]
|
||||
io_kit_audio = []
|
||||
open_al = []
|
||||
|
||||
7
third_party/rust/coreaudio-sys/build.rs
vendored
7
third_party/rust/coreaudio-sys/build.rs
vendored
@@ -86,13 +86,6 @@ fn build(sdk_path: Option<&str>, target: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "io_kit_audio")]
|
||||
{
|
||||
assert!(target.contains("apple-darwin"));
|
||||
println!("cargo:rustc-link-lib=framework=IOKit");
|
||||
headers.push("IOKit/audio/IOAudioTypes.h");
|
||||
}
|
||||
|
||||
#[cfg(feature = "open_al")]
|
||||
{
|
||||
println!("cargo:rustc-link-lib=framework=OpenAL");
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"files":{".circleci/config.yml":"7f3dc865105ca8f33965a7958b1fe2e627ae2d5a703f3b2a4ab6e2e796018597",".editorconfig":"4e53b182bcc78b83d7e1b5c03efa14d22d4955c4ed2514d1ba4e99c1eb1a50ba",".githooks/pre-push":"8b8b26544cd56f54c0c33812551f786bb25cb08c86dbfeb6bf3daad881c826a1",".github/workflows/test.yml":"aa1998a3b104ad131805ca3513832cef3f65300192824f8b1efc9a5a0cc108f6",".travis.yml":"dc07bac53f70f16c9bdf52264bdc58500ae6018c1b4c567bc7642f6b4ca3cc35","Cargo.toml":"4d868f1f8698945fb84b9700926f5d6800d003d289d5ae773bcfaaaeb436b45e","LICENSE":"6e6f56aff5bbf3cbc60747e152fb1a719bd0716aaf6d711c554f57d92e96297c","README.md":"0007782a05a5330f739ad789c19c82562c82e32386b0447000fc72c0d48405bc","build-audiounit-rust-in-cubeb.sh":"d228a05985dcd02ec1ecac66a2b64dae5a530804a25a7054ccc95905aedfb7ef","install_git_hook.sh":"d38c8e51e636f6b90b489621ac34ccd1d1b1f40dccce3d178ed1da1c5068f16d","install_rustfmt_clippy.sh":"4ae90d8dcb9757cb3ae4ae142ef80e5377c0dde61c63f4a3c32418646e80ca7b","run_device_tests.sh":"d717e598c96e4911d9494b18382d6bd3a8d5038b7d68d3166ad4336e237a97d8","run_sanitizers.sh":"d6c3cde105ae0759e753cc31cab691eb417c4d0ad68f20da5e87fe0138a0d92f","run_tests.sh":"916a7ae4a406d2274417d6eca939a878db5adcb6144e5680d9d148bf90178f1c","src/backend/aggregate_device.rs":"43511107ba2a75a19340ac663c981362ca1b75b679b6c295d88b5035bd7e3619","src/backend/auto_release.rs":"050fdcee74cf46b9a8a85a877e166d72a853d33220f59cf734cbb6ea09daa441","src/backend/buffer_manager.rs":"314c3404f1a44f8c23856f96510779e7e64ebb7dde5abe444946c16d04af7c29","src/backend/device_property.rs":"a7622feaa41db1cd76fd35a85a022e44f4894e396a104a59008d5b8757d2ab4e","src/backend/mixer.rs":"ed299d3954e2a823060c870a8244673a7d4bca530830cb66b964d047a80ee3af","src/backend/mod.rs":"21ca892ccd925991e7f4877a5ac1b8e70a5f4785e7d498024965c46eabdd3033","src/backend/resampler.rs":"48bf8f56ae8d60dbabca6417b768000619abee8731ac3902164b45651ac08a4d","src/backend/tests/aggregate_device.rs":"e3f94e118e1dd47941fbba4417de40bddc4254d9f06b1e938f58d8f1aa566a5c","src/backend/tests/api.rs":"566546bec17220641960342374516da3baf6032a8843ac7a6c1f0b1cb8911594","src/backend/tests/backlog.rs":"3b189a7e036543c467cc242af0ed3332721179ee2b1c8847a6db563546f1ac52","src/backend/tests/device_change.rs":"b1b4f7f71de99d07406a8a38dc67e46a43b883d4a845daaf356e72fbe0d5a08b","src/backend/tests/device_property.rs":"ea0be5f8834be494cb33f854ce9d334b5763dc5287f949bcb4bd025d8a8b2d3b","src/backend/tests/interfaces.rs":"c8ca26d0fd098b8a230d9aa8d67a062da2ab3ac0f868739485c793618fc75700","src/backend/tests/manual.rs":"8d485a6666a3f4518b03e39dab80bf2acfd760af2d2f43bad99023cb135b38ca","src/backend/tests/mod.rs":"8dba770023d7f9c4228f0e11915347f0e07da5fd818e3ee4478c4b197af9aa2a","src/backend/tests/parallel.rs":"504613b1b5fa4d67cbb2560cb8d8cef0a4e8929c28b31d9d4695ac5286969f38","src/backend/tests/tone.rs":"779cc14fc2a362bf7f26ce66ad70c0639501176175655a99b7fefb3c59d56c7a","src/backend/tests/utils.rs":"7d74298435260566838ece9a84ee42e4a02c16683f5434d7ba2671a9acf4424f","src/backend/utils.rs":"6c3ffbcd602e6cc9f56deb9ecb07b2eef2e6f074ef924178e466f380aae5c595","src/capi.rs":"21b66b70545bf04ec719928004d1d9adb45b24ced51288f5b2993d79aaf78f5f","src/lib.rs":"5e586d45cd6b3722f0a6736d9252593299269817a153eef1930a5fb9bfbb56f5","todo.md":"efc1f012eb9a331a040cad4ac03aa79307f25885f71b6fb38f3ad7af8d7d515c"},"package":null}
|
||||
{"files":{".circleci/config.yml":"7f3dc865105ca8f33965a7958b1fe2e627ae2d5a703f3b2a4ab6e2e796018597",".editorconfig":"4e53b182bcc78b83d7e1b5c03efa14d22d4955c4ed2514d1ba4e99c1eb1a50ba",".githooks/pre-push":"8b8b26544cd56f54c0c33812551f786bb25cb08c86dbfeb6bf3daad881c826a1",".github/workflows/test.yml":"aa1998a3b104ad131805ca3513832cef3f65300192824f8b1efc9a5a0cc108f6",".travis.yml":"dc07bac53f70f16c9bdf52264bdc58500ae6018c1b4c567bc7642f6b4ca3cc35","Cargo.toml":"b82f0d73e2afde65c328c9263c7e4ff3f53fe1671e5fc9a96ced50fb12698933","LICENSE":"6e6f56aff5bbf3cbc60747e152fb1a719bd0716aaf6d711c554f57d92e96297c","README.md":"0007782a05a5330f739ad789c19c82562c82e32386b0447000fc72c0d48405bc","build-audiounit-rust-in-cubeb.sh":"d228a05985dcd02ec1ecac66a2b64dae5a530804a25a7054ccc95905aedfb7ef","install_git_hook.sh":"d38c8e51e636f6b90b489621ac34ccd1d1b1f40dccce3d178ed1da1c5068f16d","install_rustfmt_clippy.sh":"4ae90d8dcb9757cb3ae4ae142ef80e5377c0dde61c63f4a3c32418646e80ca7b","run_device_tests.sh":"cac9a7d588c2be0efa842c15d24c8cf0573bc9f9d73011662ba764dc9f6245e8","run_sanitizers.sh":"8828c73439dfd540cd21fc713c4a1011ec05baca6f282f285743f310ace39563","run_tests.sh":"916a7ae4a406d2274417d6eca939a878db5adcb6144e5680d9d148bf90178f1c","src/backend/aggregate_device.rs":"e822b4496e2ea5c6e1a288c6e92f57e598abf67cb0bdff813f859d57c63be5f9","src/backend/auto_release.rs":"050fdcee74cf46b9a8a85a877e166d72a853d33220f59cf734cbb6ea09daa441","src/backend/buffer_manager.rs":"314c3404f1a44f8c23856f96510779e7e64ebb7dde5abe444946c16d04af7c29","src/backend/device_property.rs":"2a63837b98b9b6bfb314b4aa6dce919412b71e13e18c7b8f3477aa1482f70b29","src/backend/mixer.rs":"ed299d3954e2a823060c870a8244673a7d4bca530830cb66b964d047a80ee3af","src/backend/mod.rs":"c1d4c753d30fc5e6f2aafcd5d34c3ae2393e0bae4aeb5bc477af396014ec1877","src/backend/resampler.rs":"8641c672d00f77be287d64f6cd4a2b2cd36f8630e2ded1eff6b39834b1b7ddc3","src/backend/tests/aggregate_device.rs":"7542cbb1c82398d00a5cba5b335842c517af2cda887946ebb5aaf512fd06b527","src/backend/tests/api.rs":"2cbae3a49f39fc78ec379c8c0c0266ad3e3552ef22b42168ac9d62d9d983a4a7","src/backend/tests/backlog.rs":"3b189a7e036543c467cc242af0ed3332721179ee2b1c8847a6db563546f1ac52","src/backend/tests/device_change.rs":"97555244a8081251f1447c6a677609d1e91f33c9c0f4fb3f8a4082005c68ae0c","src/backend/tests/device_property.rs":"373f76d3bee83b263db3f02be3b94b408bdf852d84e4b5153273fda34b11a374","src/backend/tests/interfaces.rs":"9ed857625147c3d13c1458e630db8a78362612e6ef679d918bfdafa6e927fe75","src/backend/tests/manual.rs":"8d485a6666a3f4518b03e39dab80bf2acfd760af2d2f43bad99023cb135b38ca","src/backend/tests/mod.rs":"8dba770023d7f9c4228f0e11915347f0e07da5fd818e3ee4478c4b197af9aa2a","src/backend/tests/parallel.rs":"f9e1883660d6146b6e5075806561f5f689810e25c5e7764dfd28c9b939821a49","src/backend/tests/tone.rs":"779cc14fc2a362bf7f26ce66ad70c0639501176175655a99b7fefb3c59d56c7a","src/backend/tests/utils.rs":"3c430e519c0e7a17dda6b57c110fab725a846da39606fd99274bad20a637cf35","src/backend/utils.rs":"6c3ffbcd602e6cc9f56deb9ecb07b2eef2e6f074ef924178e466f380aae5c595","src/capi.rs":"21b66b70545bf04ec719928004d1d9adb45b24ced51288f5b2993d79aaf78f5f","src/lib.rs":"5e586d45cd6b3722f0a6736d9252593299269817a153eef1930a5fb9bfbb56f5","todo.md":"efc1f012eb9a331a040cad4ac03aa79307f25885f71b6fb38f3ad7af8d7d515c"},"package":null}
|
||||
5
third_party/rust/cubeb-coreaudio/Cargo.toml
vendored
5
third_party/rust/cubeb-coreaudio/Cargo.toml
vendored
@@ -28,7 +28,7 @@ crate-type = [
|
||||
[dependencies]
|
||||
atomic = "0.4"
|
||||
audio-mixer = "0.1"
|
||||
bitflags = "2"
|
||||
bitflags = "1.0"
|
||||
cubeb-backend = "0.10.3"
|
||||
float-cmp = "0.6"
|
||||
lazy_static = "1.2"
|
||||
@@ -39,6 +39,3 @@ triple_buffer = "5.0.5"
|
||||
|
||||
[dependencies.coreaudio-sys-utils]
|
||||
path = "coreaudio-sys-utils"
|
||||
|
||||
[dev-dependencies]
|
||||
itertools = "0.11"
|
||||
|
||||
@@ -24,17 +24,21 @@ cargo test test_suspend_input_stream_by_unplugging_a_nondefault_input_device --
|
||||
cargo test test_destroy_input_stream_after_unplugging_a_default_input_device -- --ignored --nocapture
|
||||
cargo test test_reinit_input_stream_by_unplugging_a_default_input_device -- --ignored --nocapture
|
||||
|
||||
cargo test test_destroy_output_stream_after_unplugging_a_nondefault_output_device -- --ignored --nocapture
|
||||
cargo test test_suspend_output_stream_by_unplugging_a_nondefault_output_device -- --ignored --nocapture
|
||||
# FIXME: We don't monitor the alive-status for output device currently
|
||||
# cargo test test_destroy_output_stream_after_unplugging_a_nondefault_output_device -- --ignored --nocapture
|
||||
# FIXME: We don't monitor the alive-status for output device currently
|
||||
# cargo test test_suspend_output_stream_by_unplugging_a_nondefault_output_device -- --ignored --nocapture
|
||||
|
||||
cargo test test_destroy_output_stream_after_unplugging_a_default_output_device -- --ignored --nocapture
|
||||
cargo test test_reinit_output_stream_by_unplugging_a_default_output_device -- --ignored --nocapture
|
||||
|
||||
cargo test test_destroy_duplex_stream_after_unplugging_a_nondefault_input_device -- --ignored --nocapture
|
||||
cargo test test_suspend_duplex_stream_by_unplugging_a_nondefault_input_device -- --ignored --nocapture
|
||||
cargo test test_suspend_duplex_stream_by_unplugging_a_nondefault_input_device
|
||||
|
||||
cargo test test_destroy_duplex_stream_after_unplugging_a_nondefault_output_device -- --ignored --nocapture
|
||||
cargo test test_suspend_duplex_stream_by_unplugging_a_nondefault_output_device -- --ignored --nocapture
|
||||
# FIXME: We don't monitor the alive-status for output device currently
|
||||
# cargo test test_destroy_duplex_stream_after_unplugging_a_nondefault_output_device -- --ignored --nocapture
|
||||
# FIXME: We don't monitor the alive-status for output device currently
|
||||
# cargo test test_suspend_duplex_stream_by_unplugging_a_nondefault_output_device -- --ignored --nocapture
|
||||
|
||||
cargo test test_destroy_duplex_stream_after_unplugging_a_default_input_device -- --ignored --nocapture
|
||||
cargo test test_reinit_duplex_stream_by_unplugging_a_default_input_device -- --ignored --nocapture
|
||||
|
||||
@@ -15,7 +15,8 @@ fi
|
||||
# - `memory`: It doesn't works with target x86_64-apple-darwin
|
||||
# - `leak`: Get some errors that are out of our control. See:
|
||||
# https://github.com/mozilla/cubeb-coreaudio-rs/issues/45#issuecomment-591642931
|
||||
sanitizers=("address" "thread")
|
||||
# - `thread`: It's blocked by #129
|
||||
sanitizers=("address")
|
||||
for san in "${sanitizers[@]}"
|
||||
do
|
||||
San="$(tr '[:lower:]' '[:upper:]' <<< ${san:0:1})${san:1}"
|
||||
|
||||
@@ -180,7 +180,7 @@ impl AggregateDevice {
|
||||
let device = Self::create_blank_device(plugin_id)?;
|
||||
|
||||
// Wait until the aggregate is created.
|
||||
let (lock, cvar) = &*condvar_pair;
|
||||
let &(ref lock, ref cvar) = &*condvar_pair;
|
||||
let devices = lock.lock().unwrap();
|
||||
if !devices.contains(&device) {
|
||||
let (devs, timeout_res) = cvar.wait_timeout(devices, waiting_time).unwrap();
|
||||
@@ -203,7 +203,7 @@ impl AggregateDevice {
|
||||
) -> OSStatus {
|
||||
assert_eq!(id, kAudioObjectSystemObject);
|
||||
let pair = unsafe { &mut *(data as *mut Arc<(Mutex<Vec<AudioObjectID>>, Condvar)>) };
|
||||
let (lock, cvar) = &**pair;
|
||||
let &(ref lock, ref cvar) = &**pair;
|
||||
let mut devices = lock.lock().unwrap();
|
||||
*devices = audiounit_get_devices();
|
||||
cvar.notify_one();
|
||||
@@ -339,7 +339,7 @@ impl AggregateDevice {
|
||||
Self::set_sub_devices(device_id, input_id, output_id)?;
|
||||
|
||||
// Wait until the sub devices are added.
|
||||
let (lock, cvar) = &*condvar_pair;
|
||||
let &(ref lock, ref cvar) = &*condvar_pair;
|
||||
let device = lock.lock().unwrap();
|
||||
if *device != device_id {
|
||||
let (dev, timeout_res) = cvar.wait_timeout(device, waiting_time).unwrap();
|
||||
@@ -370,7 +370,7 @@ impl AggregateDevice {
|
||||
data: *mut c_void,
|
||||
) -> OSStatus {
|
||||
let pair = unsafe { &mut *(data as *mut Arc<(Mutex<AudioObjectID>, Condvar)>) };
|
||||
let (lock, cvar) = &**pair;
|
||||
let &(ref lock, ref cvar) = &**pair;
|
||||
let mut device = lock.lock().unwrap();
|
||||
*device = id;
|
||||
cvar.notify_one();
|
||||
|
||||
@@ -223,49 +223,13 @@ pub fn get_ranges_of_device_sample_rate(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_stream_latency(id: AudioStreamID) -> std::result::Result<u32, OSStatus> {
|
||||
assert_ne!(id, kAudioObjectUnknown);
|
||||
|
||||
let address = get_property_address(
|
||||
Property::StreamLatency,
|
||||
DeviceType::INPUT | DeviceType::OUTPUT,
|
||||
);
|
||||
let mut size = mem::size_of::<u32>();
|
||||
let mut latency: u32 = 0;
|
||||
let err = audio_object_get_property_data(id, &address, &mut size, &mut latency);
|
||||
if err == NO_ERR {
|
||||
Ok(latency)
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_stream_terminal_type(id: AudioStreamID) -> std::result::Result<u32, OSStatus> {
|
||||
assert_ne!(id, kAudioObjectUnknown);
|
||||
|
||||
let address = get_property_address(
|
||||
Property::StreamTerminalType,
|
||||
DeviceType::INPUT | DeviceType::OUTPUT,
|
||||
);
|
||||
let mut size = mem::size_of::<u32>();
|
||||
let mut terminal_type: u32 = 0;
|
||||
let err = audio_object_get_property_data(id, &address, &mut size, &mut terminal_type);
|
||||
if err == NO_ERR {
|
||||
Ok(terminal_type)
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_stream_virtual_format(
|
||||
id: AudioStreamID,
|
||||
pub fn get_device_stream_format(
|
||||
id: AudioDeviceID,
|
||||
devtype: DeviceType,
|
||||
) -> std::result::Result<AudioStreamBasicDescription, OSStatus> {
|
||||
assert_ne!(id, kAudioObjectUnknown);
|
||||
|
||||
let address = get_property_address(
|
||||
Property::StreamVirtualFormat,
|
||||
DeviceType::INPUT | DeviceType::OUTPUT,
|
||||
);
|
||||
let address = get_property_address(Property::DeviceStreamFormat, devtype);
|
||||
let mut size = mem::size_of::<AudioStreamBasicDescription>();
|
||||
let mut format = AudioStreamBasicDescription::default();
|
||||
let err = audio_object_get_property_data(id, &address, &mut size, &mut format);
|
||||
@@ -276,6 +240,51 @@ pub fn get_stream_virtual_format(
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_ptr_alignment)] // Allow casting *mut u8 to *mut AudioBufferList
|
||||
pub fn get_device_stream_configuration(
|
||||
id: AudioDeviceID,
|
||||
devtype: DeviceType,
|
||||
) -> std::result::Result<Vec<AudioBuffer>, OSStatus> {
|
||||
assert_ne!(id, kAudioObjectUnknown);
|
||||
|
||||
let address = get_property_address(Property::DeviceStreamConfiguration, devtype);
|
||||
let mut size: usize = 0;
|
||||
let err = audio_object_get_property_data_size(id, &address, &mut size);
|
||||
if err != NO_ERR {
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
let mut data: Vec<u8> = allocate_array_by_size(size);
|
||||
let ptr = data.as_mut_ptr() as *mut AudioBufferList;
|
||||
let err = audio_object_get_property_data(id, &address, &mut size, ptr);
|
||||
if err != NO_ERR {
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
let list = unsafe { &(*ptr) };
|
||||
let ptr = list.mBuffers.as_ptr() as *const AudioBuffer;
|
||||
let len = list.mNumberBuffers as usize;
|
||||
let buffers = unsafe { slice::from_raw_parts(ptr, len) };
|
||||
Ok(buffers.to_vec())
|
||||
}
|
||||
|
||||
pub fn get_stream_latency(
|
||||
id: AudioStreamID,
|
||||
devtype: DeviceType,
|
||||
) -> std::result::Result<u32, OSStatus> {
|
||||
assert_ne!(id, kAudioObjectUnknown);
|
||||
|
||||
let address = get_property_address(Property::StreamLatency, devtype);
|
||||
let mut size = mem::size_of::<u32>();
|
||||
let mut latency: u32 = 0;
|
||||
let err = audio_object_get_property_data(id, &address, &mut size, &mut latency);
|
||||
if err == NO_ERR {
|
||||
Ok(latency)
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_clock_domain(
|
||||
id: AudioStreamID,
|
||||
devtype: DeviceType,
|
||||
@@ -303,6 +312,8 @@ pub enum Property {
|
||||
DeviceSampleRates,
|
||||
DeviceSource,
|
||||
DeviceSourceName,
|
||||
DeviceStreamConfiguration,
|
||||
DeviceStreamFormat,
|
||||
DeviceStreams,
|
||||
DeviceUID,
|
||||
HardwareDefaultInputDevice,
|
||||
@@ -310,8 +321,6 @@ pub enum Property {
|
||||
HardwareDevices,
|
||||
ModelUID,
|
||||
StreamLatency,
|
||||
StreamTerminalType,
|
||||
StreamVirtualFormat,
|
||||
TransportType,
|
||||
ClockDomain,
|
||||
}
|
||||
@@ -328,6 +337,8 @@ impl From<Property> for AudioObjectPropertySelector {
|
||||
Property::DeviceSampleRates => kAudioDevicePropertyAvailableNominalSampleRates,
|
||||
Property::DeviceSource => kAudioDevicePropertyDataSource,
|
||||
Property::DeviceSourceName => kAudioDevicePropertyDataSourceNameForIDCFString,
|
||||
Property::DeviceStreamConfiguration => kAudioDevicePropertyStreamConfiguration,
|
||||
Property::DeviceStreamFormat => kAudioDevicePropertyStreamFormat,
|
||||
Property::DeviceStreams => kAudioDevicePropertyStreams,
|
||||
Property::DeviceUID => kAudioDevicePropertyDeviceUID,
|
||||
Property::HardwareDefaultInputDevice => kAudioHardwarePropertyDefaultInputDevice,
|
||||
@@ -335,8 +346,6 @@ impl From<Property> for AudioObjectPropertySelector {
|
||||
Property::HardwareDevices => kAudioHardwarePropertyDevices,
|
||||
Property::ModelUID => kAudioDevicePropertyModelUID,
|
||||
Property::StreamLatency => kAudioStreamPropertyLatency,
|
||||
Property::StreamTerminalType => kAudioStreamPropertyTerminalType,
|
||||
Property::StreamVirtualFormat => kAudioStreamPropertyVirtualFormat,
|
||||
Property::TransportType => kAudioDevicePropertyTransportType,
|
||||
Property::ClockDomain => kAudioDevicePropertyClockDomain,
|
||||
}
|
||||
|
||||
791
third_party/rust/cubeb-coreaudio/src/backend/mod.rs
vendored
791
third_party/rust/cubeb-coreaudio/src/backend/mod.rs
vendored
File diff suppressed because it is too large
Load Diff
@@ -19,13 +19,15 @@ impl Resampler {
|
||||
reclock: ffi::cubeb_resampler_reclock,
|
||||
) -> Self {
|
||||
let raw_resampler = unsafe {
|
||||
let in_params = match &mut input_params {
|
||||
Some(p) => p,
|
||||
None => ptr::null_mut(),
|
||||
let in_params = if input_params.is_some() {
|
||||
input_params.as_mut().unwrap() as *mut ffi::cubeb_stream_params
|
||||
} else {
|
||||
ptr::null_mut()
|
||||
};
|
||||
let out_params = match &mut output_params {
|
||||
Some(p) => p,
|
||||
None => ptr::null_mut(),
|
||||
let out_params = if output_params.is_some() {
|
||||
output_params.as_mut().unwrap() as *mut ffi::cubeb_stream_params
|
||||
} else {
|
||||
ptr::null_mut()
|
||||
};
|
||||
ffi::cubeb_resampler_create(
|
||||
stream,
|
||||
|
||||
@@ -42,7 +42,7 @@ fn test_aggregate_set_sub_devices_for_unknown_devices() {
|
||||
// application and print out the sub devices of them!
|
||||
#[test]
|
||||
fn test_aggregate_get_sub_devices() {
|
||||
let devices = test_get_all_devices(DeviceFilter::ExcludeCubebAggregateAndVPIO);
|
||||
let devices = test_get_all_devices(DeviceFilter::ExcludeCubebAggregate);
|
||||
for device in devices {
|
||||
// `AggregateDevice::get_sub_devices(device)` will return a single-element vector
|
||||
// containing `device` itself if it's not an aggregate device. This test assumes devices
|
||||
@@ -108,7 +108,7 @@ fn test_aggregate_create_blank_device() {
|
||||
// TODO: Test this when there is no available devices.
|
||||
let plugin = AggregateDevice::get_system_plugin_id().unwrap();
|
||||
let device = AggregateDevice::create_blank_device_sync(plugin).unwrap();
|
||||
let devices = test_get_all_devices(DeviceFilter::IncludeAll);
|
||||
let devices = test_get_all_devices(DeviceFilter::IncludeCubebAggregate);
|
||||
let device = devices.into_iter().find(|dev| dev == &device).unwrap();
|
||||
let uid = get_device_global_uid(device).unwrap().into_string();
|
||||
assert!(uid.contains(PRIVATE_AGGREGATE_DEVICE_NAME));
|
||||
|
||||
@@ -45,8 +45,8 @@ fn test_increase_and_decrease_context_streams() {
|
||||
for i in 0..STREAMS {
|
||||
join_handles.push(thread::spawn(move || {
|
||||
let context = unsafe { &*(context_ptr_value as *const AudioUnitContext) };
|
||||
|
||||
context.update_latency_by_adding_stream(i)
|
||||
let global_latency = context.update_latency_by_adding_stream(i);
|
||||
global_latency
|
||||
}));
|
||||
}
|
||||
let mut latencies = vec![];
|
||||
@@ -227,11 +227,10 @@ fn test_add_listener_unknown_device() {
|
||||
),
|
||||
callback,
|
||||
);
|
||||
let mut res: OSStatus = 0;
|
||||
stream
|
||||
.queue
|
||||
.run_sync(|| res = stream.add_device_listener(&listener));
|
||||
assert_eq!(res, kAudioHardwareBadObjectError as OSStatus);
|
||||
assert_eq!(
|
||||
stream.add_device_listener(&listener),
|
||||
kAudioHardwareBadObjectError as OSStatus
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -258,15 +257,8 @@ fn test_add_listener_then_remove_system_device() {
|
||||
),
|
||||
callback,
|
||||
);
|
||||
let mut res: OSStatus = 0;
|
||||
stream
|
||||
.queue
|
||||
.run_sync(|| res = stream.add_device_listener(&listener));
|
||||
assert_eq!(res, NO_ERR);
|
||||
stream
|
||||
.queue
|
||||
.run_sync(|| res = stream.remove_device_listener(&listener));
|
||||
assert_eq!(res, NO_ERR);
|
||||
assert_eq!(stream.add_device_listener(&listener), NO_ERR);
|
||||
assert_eq!(stream.remove_device_listener(&listener), NO_ERR);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -291,11 +283,7 @@ fn test_remove_listener_without_adding_any_listener_before_system_device() {
|
||||
),
|
||||
callback,
|
||||
);
|
||||
let mut res: OSStatus = 0;
|
||||
stream
|
||||
.queue
|
||||
.run_sync(|| res = stream.remove_device_listener(&listener));
|
||||
assert_eq!(res, NO_ERR);
|
||||
assert_eq!(stream.remove_device_listener(&listener), NO_ERR);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -320,11 +308,10 @@ fn test_remove_listener_unknown_device() {
|
||||
),
|
||||
callback,
|
||||
);
|
||||
let mut res: OSStatus = 0;
|
||||
stream
|
||||
.queue
|
||||
.run_sync(|| res = stream.remove_device_listener(&listener));
|
||||
assert_eq!(res, kAudioHardwareBadObjectError as OSStatus);
|
||||
assert_eq!(
|
||||
stream.remove_device_listener(&listener),
|
||||
kAudioHardwareBadObjectError as OSStatus
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -713,7 +700,7 @@ fn test_convert_channel_layout() {
|
||||
}
|
||||
let layout_ref = unsafe { &(*(&layout as *const TestLayout as *const AudioChannelLayout)) };
|
||||
assert_eq!(
|
||||
&audiounit_convert_channel_layout(layout_ref).unwrap(),
|
||||
&audiounit_convert_channel_layout(layout_ref),
|
||||
expected_layout
|
||||
);
|
||||
}
|
||||
@@ -724,9 +711,7 @@ fn test_convert_channel_layout() {
|
||||
#[test]
|
||||
fn test_get_preferred_channel_layout_output() {
|
||||
match test_get_default_audiounit(Scope::Output) {
|
||||
Some(unit) => assert!(!audiounit_get_preferred_channel_layout(unit.get_inner())
|
||||
.unwrap()
|
||||
.is_empty()),
|
||||
Some(unit) => assert!(!audiounit_get_preferred_channel_layout(unit.get_inner()).is_empty()),
|
||||
None => println!("No output audiounit for test."),
|
||||
}
|
||||
}
|
||||
@@ -736,9 +721,7 @@ fn test_get_preferred_channel_layout_output() {
|
||||
#[test]
|
||||
fn test_get_current_channel_layout_output() {
|
||||
match test_get_default_audiounit(Scope::Output) {
|
||||
Some(unit) => assert!(!audiounit_get_current_channel_layout(unit.get_inner())
|
||||
.unwrap()
|
||||
.is_empty()),
|
||||
Some(unit) => assert!(!audiounit_get_current_channel_layout(unit.get_inner()).is_empty()),
|
||||
None => println!("No output audiounit for test."),
|
||||
}
|
||||
}
|
||||
@@ -867,7 +850,7 @@ fn test_for_create_audiounit() {
|
||||
|
||||
// Check the output scope is enabled.
|
||||
if device.flags.contains(device_flags::DEV_OUTPUT) && default_output.is_some() {
|
||||
device.id = default_output.unwrap();
|
||||
device.id = default_output.clone().unwrap();
|
||||
let unit = create_audiounit(&device).unwrap();
|
||||
assert!(!unit.is_null());
|
||||
assert!(test_audiounit_scope_is_enabled(unit, Scope::Output));
|
||||
@@ -881,7 +864,7 @@ fn test_for_create_audiounit() {
|
||||
|
||||
// Check the input scope is enabled.
|
||||
if device.flags.contains(device_flags::DEV_INPUT) && default_input.is_some() {
|
||||
let device_id = default_input.unwrap();
|
||||
let device_id = default_input.clone().unwrap();
|
||||
device.id = device_id;
|
||||
let unit = create_audiounit(&device).unwrap();
|
||||
assert!(!unit.is_null());
|
||||
@@ -1064,12 +1047,8 @@ fn test_get_channel_count_of_inout_type() {
|
||||
fn test_channel_count(scope: Scope) {
|
||||
if let Some(device) = test_get_default_device(scope.clone()) {
|
||||
assert_eq!(
|
||||
get_channel_count(device, DeviceType::INPUT | DeviceType::OUTPUT),
|
||||
get_channel_count(device, DeviceType::INPUT).map(|c| c + get_channel_count(
|
||||
device,
|
||||
DeviceType::OUTPUT
|
||||
)
|
||||
.unwrap_or(0))
|
||||
get_channel_count(device, DeviceType::INPUT | DeviceType::OUTPUT).unwrap_err(),
|
||||
kAudioHardwareUnknownPropertyError as OSStatus
|
||||
);
|
||||
} else {
|
||||
println!("No device for {:?}.", scope);
|
||||
@@ -1387,6 +1366,7 @@ fn test_create_device_info_by_unknown_device() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_create_device_info_with_unknown_type() {
|
||||
test_create_device_info_with_unknown_type_by_scope(Scope::Input);
|
||||
test_create_device_info_with_unknown_type_by_scope(Scope::Output);
|
||||
@@ -1394,6 +1374,8 @@ fn test_create_device_info_with_unknown_type() {
|
||||
fn test_create_device_info_with_unknown_type_by_scope(scope: Scope) {
|
||||
if let Some(device) = test_get_default_device(scope.clone()) {
|
||||
assert!(create_cubeb_device_info(device, DeviceType::UNKNOWN).is_err());
|
||||
} else {
|
||||
panic!("Panic by default: No device for {:?}.", scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1434,6 +1416,23 @@ fn test_create_device_from_hwdev_with_inout_type() {
|
||||
}
|
||||
}
|
||||
|
||||
// is_aggregate_device
|
||||
// ------------------------------------
|
||||
#[test]
|
||||
fn test_is_aggregate_device() {
|
||||
let mut aggregate_name = String::from(PRIVATE_AGGREGATE_DEVICE_NAME);
|
||||
aggregate_name.push_str("_something");
|
||||
let aggregate_name_cstring = CString::new(aggregate_name).unwrap();
|
||||
|
||||
let mut info = ffi::cubeb_device_info::default();
|
||||
info.friendly_name = aggregate_name_cstring.as_ptr();
|
||||
assert!(is_aggregate_device(&info));
|
||||
|
||||
let non_aggregate_name_cstring = CString::new("Hello World!").unwrap();
|
||||
info.friendly_name = non_aggregate_name_cstring.as_ptr();
|
||||
assert!(!is_aggregate_device(&info));
|
||||
}
|
||||
|
||||
// get_devices_of_type
|
||||
// ------------------------------------
|
||||
#[test]
|
||||
@@ -1444,7 +1443,7 @@ fn test_get_devices_of_type() {
|
||||
let input_devices = audiounit_get_devices_of_type(DeviceType::INPUT);
|
||||
let output_devices = audiounit_get_devices_of_type(DeviceType::OUTPUT);
|
||||
|
||||
let mut expected_all = test_get_all_devices(DeviceFilter::ExcludeCubebAggregateAndVPIO);
|
||||
let mut expected_all = test_get_all_devices(DeviceFilter::ExcludeCubebAggregate);
|
||||
expected_all.sort();
|
||||
assert_eq!(all_devices, expected_all);
|
||||
for device in all_devices.iter() {
|
||||
|
||||
@@ -21,7 +21,8 @@ use super::utils::{
|
||||
test_set_default_device, Scope, StreamType, TestDevicePlugger, TestDeviceSwitcher,
|
||||
};
|
||||
use super::*;
|
||||
use std::sync::{LockResult, MutexGuard, WaitTimeoutResult};
|
||||
use std::fmt::Debug;
|
||||
use std::thread;
|
||||
|
||||
// Switch default devices used by the active streams, to test stream reinitialization
|
||||
// ================================================================================================
|
||||
@@ -47,25 +48,22 @@ fn test_switch_device_in_scope(scope: Scope) {
|
||||
|
||||
let mut device_switcher = TestDeviceSwitcher::new(scope.clone());
|
||||
|
||||
let notifier = Arc::new(Notifier::new(0));
|
||||
let also_notifier = notifier.clone();
|
||||
let count = Arc::new(Mutex::new(0));
|
||||
let also_count = Arc::clone(&count);
|
||||
let listener = test_create_device_change_listener(scope.clone(), move |_addresses| {
|
||||
let mut cnt = notifier.lock().unwrap();
|
||||
let mut cnt = also_count.lock().unwrap();
|
||||
*cnt += 1;
|
||||
notifier.notify(cnt);
|
||||
NO_ERR
|
||||
});
|
||||
listener.start();
|
||||
|
||||
let changed_watcher = Watcher::new(&also_notifier);
|
||||
let mut changed_watcher = Watcher::new(&count);
|
||||
test_get_started_stream_in_scope(scope.clone(), move |_stream| loop {
|
||||
let mut guard = changed_watcher.lock().unwrap();
|
||||
let start_cnt = guard.clone();
|
||||
thread::sleep(Duration::from_millis(500));
|
||||
changed_watcher.prepare();
|
||||
device_switcher.next();
|
||||
guard = changed_watcher
|
||||
.wait_while(guard, |cnt| *cnt == start_cnt)
|
||||
.unwrap();
|
||||
if *guard >= devices.len() {
|
||||
changed_watcher.wait_for_change();
|
||||
if changed_watcher.current_result() >= devices.len() {
|
||||
break;
|
||||
}
|
||||
});
|
||||
@@ -206,90 +204,77 @@ fn test_plug_and_unplug_device_in_scope(scope: Scope) {
|
||||
let mut context = AudioUnitContext::new();
|
||||
|
||||
// Register the devices-changed callbacks.
|
||||
#[derive(Clone, PartialEq)]
|
||||
struct Counts {
|
||||
input: u32,
|
||||
output: u32,
|
||||
}
|
||||
impl Counts {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
input: 0,
|
||||
output: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
let counts = Arc::new(Notifier::new(Counts::new()));
|
||||
let counts_notifier_ptr = counts.as_ref() as *const Notifier<Counts>;
|
||||
let input_count = Arc::new(Mutex::new(0u32));
|
||||
let also_input_count = Arc::clone(&input_count);
|
||||
let input_mtx_ptr = also_input_count.as_ref() as *const Mutex<u32>;
|
||||
|
||||
assert!(context
|
||||
.register_device_collection_changed(
|
||||
DeviceType::INPUT,
|
||||
Some(input_changed_callback),
|
||||
counts_notifier_ptr as *mut c_void,
|
||||
input_mtx_ptr as *mut c_void,
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
let output_count = Arc::new(Mutex::new(0u32));
|
||||
let also_output_count = Arc::clone(&output_count);
|
||||
let output_mtx_ptr = also_output_count.as_ref() as *const Mutex<u32>;
|
||||
|
||||
assert!(context
|
||||
.register_device_collection_changed(
|
||||
DeviceType::OUTPUT,
|
||||
Some(output_changed_callback),
|
||||
counts_notifier_ptr as *mut c_void,
|
||||
output_mtx_ptr as *mut c_void,
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
let counts_watcher = Watcher::new(&counts);
|
||||
let mut input_watcher = Watcher::new(&input_count);
|
||||
let mut output_watcher = Watcher::new(&output_count);
|
||||
|
||||
let mut device_plugger = TestDevicePlugger::new(scope).unwrap();
|
||||
|
||||
{
|
||||
// Simulate adding devices and monitor the devices-changed callbacks.
|
||||
let mut counts_guard = counts.lock().unwrap();
|
||||
let counts_start = counts_guard.clone();
|
||||
// Simulate adding devices and monitor the devices-changed callbacks.
|
||||
input_watcher.prepare();
|
||||
output_watcher.prepare();
|
||||
|
||||
assert!(device_plugger.plug().is_ok());
|
||||
assert!(device_plugger.plug().is_ok());
|
||||
|
||||
counts_guard = counts_watcher
|
||||
.wait_while(counts_guard, |counts| {
|
||||
(is_input && counts.input == counts_start.input)
|
||||
|| (is_output && counts.output == counts_start.output)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
// Check changed count.
|
||||
assert_eq!(counts_guard.input, if is_input { 1 } else { 0 });
|
||||
assert_eq!(counts_guard.output, if is_output { 1 } else { 0 });
|
||||
if is_input {
|
||||
input_watcher.wait_for_change();
|
||||
}
|
||||
if is_output {
|
||||
output_watcher.wait_for_change();
|
||||
}
|
||||
|
||||
{
|
||||
// Simulate removing devices and monitor the devices-changed callbacks.
|
||||
let mut counts_guard = counts.lock().unwrap();
|
||||
let counts_start = counts_guard.clone();
|
||||
// Check changed count.
|
||||
check_result(is_input, (1, 0), &input_watcher);
|
||||
check_result(is_output, (1, 0), &output_watcher);
|
||||
|
||||
assert!(device_plugger.unplug().is_ok());
|
||||
// Simulate removing devices and monitor the devices-changed callbacks.
|
||||
input_watcher.prepare();
|
||||
output_watcher.prepare();
|
||||
|
||||
counts_guard = counts_watcher
|
||||
.wait_while(counts_guard, |counts| {
|
||||
(is_input && counts.input == counts_start.input)
|
||||
|| (is_output && counts.output == counts_start.output)
|
||||
})
|
||||
.unwrap();
|
||||
assert!(device_plugger.unplug().is_ok());
|
||||
|
||||
// Check changed count.
|
||||
assert_eq!(counts_guard.input, if is_input { 2 } else { 0 });
|
||||
assert_eq!(counts_guard.output, if is_output { 2 } else { 0 });
|
||||
if is_input {
|
||||
input_watcher.wait_for_change();
|
||||
}
|
||||
if is_output {
|
||||
output_watcher.wait_for_change();
|
||||
}
|
||||
|
||||
check_result(is_input, (2, 0), &input_watcher);
|
||||
check_result(is_output, (2, 0), &output_watcher);
|
||||
|
||||
extern "C" fn input_changed_callback(context: *mut ffi::cubeb, data: *mut c_void) {
|
||||
println!(
|
||||
"Input device collection @ {:p} is changed. Data @ {:p}",
|
||||
context, data
|
||||
);
|
||||
let notifier = unsafe { &*(data as *const Notifier<Counts>) };
|
||||
let count = unsafe { &*(data as *const Mutex<u32>) };
|
||||
{
|
||||
let mut counts = notifier.lock().unwrap();
|
||||
counts.input += 1;
|
||||
notifier.notify(counts);
|
||||
let mut guard = count.lock().unwrap();
|
||||
*guard += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,13 +283,23 @@ fn test_plug_and_unplug_device_in_scope(scope: Scope) {
|
||||
"output device collection @ {:p} is changed. Data @ {:p}",
|
||||
context, data
|
||||
);
|
||||
let notifier = unsafe { &*(data as *const Notifier<Counts>) };
|
||||
let count = unsafe { &*(data as *const Mutex<u32>) };
|
||||
{
|
||||
let mut counts = notifier.lock().unwrap();
|
||||
counts.output += 1;
|
||||
notifier.notify(counts);
|
||||
let mut guard = count.lock().unwrap();
|
||||
*guard += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn check_result<T: Clone + Debug + PartialEq>(
|
||||
in_scope: bool,
|
||||
expected: (T, T),
|
||||
watcher: &Watcher<T>,
|
||||
) {
|
||||
assert_eq!(
|
||||
watcher.current_result(),
|
||||
if in_scope { expected.0 } else { expected.1 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Switch default devices used by the active streams, to test device changed callback
|
||||
@@ -357,15 +352,16 @@ fn test_register_device_changed_callback_to_check_default_device_changed(stm_typ
|
||||
return;
|
||||
}
|
||||
|
||||
let changed_count = Arc::new(Notifier::new(0u32));
|
||||
let notifier_ptr = changed_count.as_ref() as *const Notifier<u32>;
|
||||
let changed_count = Arc::new(Mutex::new(0u32));
|
||||
let also_changed_count = Arc::clone(&changed_count);
|
||||
let mtx_ptr = also_changed_count.as_ref() as *const Mutex<u32>;
|
||||
|
||||
test_get_stream_with_device_changed_callback(
|
||||
"stream: test callback for default device changed",
|
||||
stm_type,
|
||||
None, // Use default input device.
|
||||
None, // Use default output device.
|
||||
notifier_ptr as *mut c_void,
|
||||
mtx_ptr as *mut c_void,
|
||||
state_callback,
|
||||
device_changed_callback,
|
||||
|stream| {
|
||||
@@ -375,22 +371,17 @@ fn test_register_device_changed_callback_to_check_default_device_changed(stm_typ
|
||||
// be assigned to the default device, since the device list for setting
|
||||
// default device is cached upon {input, output}_device_switcher is initialized.
|
||||
|
||||
let changed_watcher = Watcher::new(&changed_count);
|
||||
let mut changed_watcher = Watcher::new(&changed_count);
|
||||
|
||||
if let Some(devices) = inputs {
|
||||
let mut device_switcher = TestDeviceSwitcher::new(Scope::Input);
|
||||
for _ in 0..devices {
|
||||
// While the stream is re-initializing for the default device switch,
|
||||
// switching for the default device again will be ignored.
|
||||
while stream.switching_device.load(atomic::Ordering::SeqCst) {
|
||||
std::hint::spin_loop()
|
||||
}
|
||||
let guard = changed_watcher.lock().unwrap();
|
||||
let start_cnt = guard.clone();
|
||||
while stream.switching_device.load(atomic::Ordering::SeqCst) {}
|
||||
changed_watcher.prepare();
|
||||
device_switcher.next();
|
||||
changed_watcher
|
||||
.wait_while(guard, |cnt| *cnt == start_cnt)
|
||||
.unwrap();
|
||||
changed_watcher.wait_for_change();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -399,15 +390,10 @@ fn test_register_device_changed_callback_to_check_default_device_changed(stm_typ
|
||||
for _ in 0..devices {
|
||||
// While the stream is re-initializing for the default device switch,
|
||||
// switching for the default device again will be ignored.
|
||||
while stream.switching_device.load(atomic::Ordering::SeqCst) {
|
||||
std::hint::spin_loop()
|
||||
}
|
||||
let guard = changed_watcher.lock().unwrap();
|
||||
let start_cnt = guard.clone();
|
||||
while stream.switching_device.load(atomic::Ordering::SeqCst) {}
|
||||
changed_watcher.prepare();
|
||||
device_switcher.next();
|
||||
changed_watcher
|
||||
.wait_while(guard, |cnt| *cnt == start_cnt)
|
||||
.unwrap();
|
||||
changed_watcher.wait_for_change();
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -424,10 +410,11 @@ fn test_register_device_changed_callback_to_check_default_device_changed(stm_typ
|
||||
|
||||
extern "C" fn device_changed_callback(data: *mut c_void) {
|
||||
println!("Device change callback. data @ {:p}", data);
|
||||
let notifier = unsafe { &*(data as *const Notifier<u32>) };
|
||||
let mut count_guard = notifier.lock().unwrap();
|
||||
*count_guard += 1;
|
||||
notifier.notify(count_guard);
|
||||
let count = unsafe { &*(data as *const Mutex<u32>) };
|
||||
{
|
||||
let mut guard = count.lock().unwrap();
|
||||
*guard += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,7 +440,7 @@ fn test_destroy_input_stream_after_unplugging_a_nondefault_input_device() {
|
||||
#[test]
|
||||
fn test_suspend_input_stream_by_unplugging_a_nondefault_input_device() {
|
||||
// Expect to get an error state callback by device-changed event handler
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::INPUT, Scope::Input, false, 2000);
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::INPUT, Scope::Input, false, 500);
|
||||
}
|
||||
|
||||
// Unplug the default input device for an input stream
|
||||
@@ -472,7 +459,7 @@ fn test_destroy_input_stream_after_unplugging_a_default_input_device() {
|
||||
fn test_reinit_input_stream_by_unplugging_a_default_input_device() {
|
||||
// Expect to get an device-changed callback by device-changed event handler,
|
||||
// which will reinitialize the stream behind the scenes
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::INPUT, Scope::Input, true, 2000);
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::INPUT, Scope::Input, true, 500);
|
||||
}
|
||||
|
||||
// Output-only stream
|
||||
@@ -480,16 +467,18 @@ fn test_reinit_input_stream_by_unplugging_a_default_input_device() {
|
||||
|
||||
// Unplug the non-default output device for an output stream
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// FIXME: We don't monitor the alive-status for output device currently
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_destroy_output_stream_after_unplugging_a_nondefault_output_device() {
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::OUTPUT, Scope::Output, false, 0);
|
||||
}
|
||||
|
||||
// FIXME: We don't monitor the alive-status for output device currently
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_suspend_output_stream_by_unplugging_a_nondefault_output_device() {
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::OUTPUT, Scope::Output, false, 2000);
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::OUTPUT, Scope::Output, false, 500);
|
||||
}
|
||||
|
||||
// Unplug the default output device for an output stream
|
||||
@@ -509,7 +498,7 @@ fn test_destroy_output_stream_after_unplugging_a_default_output_device() {
|
||||
fn test_reinit_output_stream_by_unplugging_a_default_output_device() {
|
||||
// Expect to get an device-changed callback by device-changed event handler,
|
||||
// which will reinitialize the stream behind the scenes
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::OUTPUT, Scope::Output, true, 2000);
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::OUTPUT, Scope::Output, true, 500);
|
||||
}
|
||||
|
||||
// Duplex stream
|
||||
@@ -529,22 +518,24 @@ fn test_destroy_duplex_stream_after_unplugging_a_nondefault_input_device() {
|
||||
#[test]
|
||||
fn test_suspend_duplex_stream_by_unplugging_a_nondefault_input_device() {
|
||||
// Expect to get an error state callback by device-changed event handler
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::DUPLEX, Scope::Input, false, 2000);
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::DUPLEX, Scope::Input, false, 500);
|
||||
}
|
||||
|
||||
// Unplug the non-default output device for a duplex stream
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
// FIXME: We don't monitor the alive-status for output device currently
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_destroy_duplex_stream_after_unplugging_a_nondefault_output_device() {
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::DUPLEX, Scope::Output, false, 0);
|
||||
}
|
||||
|
||||
// FIXME: We don't monitor the alive-status for output device currently
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_suspend_duplex_stream_by_unplugging_a_nondefault_output_device() {
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::DUPLEX, Scope::Output, false, 2000);
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::DUPLEX, Scope::Output, false, 500);
|
||||
}
|
||||
|
||||
// Unplug the non-default in-out device for a duplex stream
|
||||
@@ -568,7 +559,7 @@ fn test_destroy_duplex_stream_after_unplugging_a_default_input_device() {
|
||||
fn test_reinit_duplex_stream_by_unplugging_a_default_input_device() {
|
||||
// Expect to get an device-changed callback by device-changed event handler,
|
||||
// which will reinitialize the stream behind the scenes
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::DUPLEX, Scope::Input, true, 2000);
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::DUPLEX, Scope::Input, true, 500);
|
||||
}
|
||||
|
||||
// Unplug the default ouput device for a duplex stream
|
||||
@@ -588,14 +579,14 @@ fn test_destroy_duplex_stream_after_unplugging_a_default_output_device() {
|
||||
fn test_reinit_duplex_stream_by_unplugging_a_default_output_device() {
|
||||
// Expect to get an device-changed callback by device-changed event handler,
|
||||
// which will reinitialize the stream behind the scenes
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::DUPLEX, Scope::Output, true, 2000);
|
||||
test_unplug_a_device_on_an_active_stream(StreamType::DUPLEX, Scope::Output, true, 500);
|
||||
}
|
||||
|
||||
fn test_unplug_a_device_on_an_active_stream(
|
||||
stream_type: StreamType,
|
||||
device_scope: Scope,
|
||||
set_device_to_default: bool,
|
||||
wait_up_to_ms: u64,
|
||||
sleep: u64,
|
||||
) {
|
||||
let has_input = test_get_default_device(Scope::Input).is_some();
|
||||
let has_output = test_get_default_device(Scope::Output).is_some();
|
||||
@@ -679,72 +670,62 @@ fn test_unplug_a_device_on_an_active_stream(
|
||||
),
|
||||
};
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
struct Data {
|
||||
changed_count: u32,
|
||||
states: Vec<ffi::cubeb_state>,
|
||||
struct SharedData {
|
||||
changed_count: Arc<Mutex<u32>>,
|
||||
states: Arc<Mutex<Vec<ffi::cubeb_state>>>,
|
||||
}
|
||||
|
||||
impl Data {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
changed_count: 0,
|
||||
states: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let notifier = Arc::new(Notifier::new(Data::new()));
|
||||
let notifier_ptr = notifier.as_ref() as *const Notifier<Data>;
|
||||
let mut shared_data = SharedData {
|
||||
changed_count: Arc::new(Mutex::new(0u32)),
|
||||
states: Arc::new(Mutex::new(vec![])),
|
||||
};
|
||||
|
||||
test_get_stream_with_device_changed_callback(
|
||||
"stream: test stream reinit/destroy after unplugging a device",
|
||||
stream_type,
|
||||
input_device,
|
||||
output_device,
|
||||
notifier_ptr as *mut c_void,
|
||||
&mut shared_data as *mut SharedData as *mut c_void,
|
||||
state_callback,
|
||||
device_changed_callback,
|
||||
|stream| {
|
||||
let mut changed_watcher = Watcher::new(&shared_data.changed_count);
|
||||
changed_watcher.prepare();
|
||||
stream.start();
|
||||
|
||||
let changed_watcher = Watcher::new(¬ifier);
|
||||
let mut data_guard = notifier.lock().unwrap();
|
||||
assert_eq!(data_guard.states.last().unwrap(), &ffi::CUBEB_STATE_STARTED);
|
||||
|
||||
// Wait for stream data callback.
|
||||
thread::sleep(Duration::from_millis(200));
|
||||
println!(
|
||||
"Stream runs on the device {} for {:?}",
|
||||
plugger.get_device_id(),
|
||||
device_scope
|
||||
);
|
||||
|
||||
let dev = plugger.get_device_id();
|
||||
let start_changed_count = data_guard.changed_count.clone();
|
||||
|
||||
assert!(plugger.unplug().is_ok());
|
||||
|
||||
if set_device_to_default {
|
||||
// The stream will be reinitialized if it follows the default input or output device.
|
||||
println!("Waiting for default device to change and reinit");
|
||||
data_guard = changed_watcher
|
||||
.wait_while(data_guard, |data| {
|
||||
data.changed_count == start_changed_count
|
||||
|| data.states.last().unwrap_or(&ffi::CUBEB_STATE_ERROR)
|
||||
!= &ffi::CUBEB_STATE_STARTED
|
||||
})
|
||||
.unwrap();
|
||||
} else if wait_up_to_ms > 0 {
|
||||
// stream can be dropped immediately before device-changed callback
|
||||
// so we only check the states if we wait for it explicitly.
|
||||
println!("Waiting for non-default device to enter error state");
|
||||
let (new_guard, timeout_res) = changed_watcher
|
||||
.wait_timeout_while(data_guard, Duration::from_millis(wait_up_to_ms), |data| {
|
||||
data.states.last().unwrap_or(&ffi::CUBEB_STATE_STARTED)
|
||||
!= &ffi::CUBEB_STATE_ERROR
|
||||
})
|
||||
.unwrap();
|
||||
assert!(!timeout_res.timed_out());
|
||||
data_guard = new_guard;
|
||||
changed_watcher.wait_for_change();
|
||||
}
|
||||
|
||||
if sleep > 0 {
|
||||
println!(
|
||||
"Wait {} ms for stream re-initialization, or state callback",
|
||||
sleep
|
||||
);
|
||||
thread::sleep(Duration::from_millis(sleep));
|
||||
|
||||
if !set_device_to_default {
|
||||
// stream can be dropped immediately before device-changed callback
|
||||
// so we only check the states if we wait for it explicitly.
|
||||
let guard = shared_data.states.lock().unwrap();
|
||||
assert!(guard.last().is_some());
|
||||
assert_eq!(guard.last().unwrap(), &ffi::CUBEB_STATE_ERROR);
|
||||
}
|
||||
} else {
|
||||
println!("Destroy the stream immediately");
|
||||
if set_device_to_default {
|
||||
println!("Stream re-initialization may run at the same time when stream is being destroyed");
|
||||
}
|
||||
}
|
||||
|
||||
println!(
|
||||
@@ -764,7 +745,6 @@ fn test_unplug_a_device_on_an_active_stream(
|
||||
user_ptr: *mut c_void,
|
||||
state: ffi::cubeb_state,
|
||||
) {
|
||||
println!("Device change callback. user_ptr @ {:p}", user_ptr);
|
||||
assert!(!stream.is_null());
|
||||
println!(
|
||||
"state: {}",
|
||||
@@ -776,79 +756,52 @@ fn test_unplug_a_device_on_an_active_stream(
|
||||
_ => "unknown",
|
||||
}
|
||||
);
|
||||
let notifier = unsafe { &mut *(user_ptr as *mut Notifier<Data>) };
|
||||
let mut data_guard = notifier.lock().unwrap();
|
||||
data_guard.states.push(state);
|
||||
notifier.notify(data_guard);
|
||||
}
|
||||
|
||||
extern "C" fn device_changed_callback(user_ptr: *mut c_void) {
|
||||
println!("Device change callback. user_ptr @ {:p}", user_ptr);
|
||||
let notifier = unsafe { &mut *(user_ptr as *mut Notifier<Data>) };
|
||||
let mut data_guard = notifier.lock().unwrap();
|
||||
data_guard.changed_count += 1;
|
||||
notifier.notify(data_guard);
|
||||
}
|
||||
}
|
||||
|
||||
struct Notifier<T> {
|
||||
value: Mutex<T>,
|
||||
cvar: Condvar,
|
||||
}
|
||||
|
||||
impl<T> Notifier<T> {
|
||||
fn new(value: T) -> Self {
|
||||
Self {
|
||||
value: Mutex::new(value),
|
||||
cvar: Condvar::new(),
|
||||
let shared_data = unsafe { &mut *(user_ptr as *mut SharedData) };
|
||||
{
|
||||
let mut guard = shared_data.states.lock().unwrap();
|
||||
guard.push(state);
|
||||
}
|
||||
}
|
||||
|
||||
fn lock(&self) -> LockResult<MutexGuard<'_, T>> {
|
||||
self.value.lock()
|
||||
}
|
||||
|
||||
fn notify(&self, _guard: MutexGuard<'_, T>) {
|
||||
self.cvar.notify_all();
|
||||
extern "C" fn device_changed_callback(data: *mut c_void) {
|
||||
println!("Device change callback. data @ {:p}", data);
|
||||
let shared_data = unsafe { &mut *(data as *mut SharedData) };
|
||||
{
|
||||
let mut guard = shared_data.changed_count.lock().unwrap();
|
||||
*guard += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Watcher<T: Clone + PartialEq> {
|
||||
notifier: Arc<Notifier<T>>,
|
||||
watching: Arc<Mutex<T>>,
|
||||
current: Option<T>,
|
||||
}
|
||||
|
||||
impl<T: Clone + PartialEq> Watcher<T> {
|
||||
fn new(value: &Arc<Notifier<T>>) -> Self {
|
||||
fn new(value: &Arc<Mutex<T>>) -> Self {
|
||||
Self {
|
||||
notifier: Arc::clone(value),
|
||||
watching: Arc::clone(value),
|
||||
current: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn lock(&self) -> LockResult<MutexGuard<'_, T>> {
|
||||
self.notifier.lock()
|
||||
fn prepare(&mut self) {
|
||||
self.current = Some(self.current_result());
|
||||
}
|
||||
|
||||
fn wait_while<'a, F>(
|
||||
&self,
|
||||
guard: MutexGuard<'a, T>,
|
||||
condition: F,
|
||||
) -> LockResult<MutexGuard<'a, T>>
|
||||
where
|
||||
F: FnMut(&mut T) -> bool,
|
||||
{
|
||||
self.notifier.cvar.wait_while(guard, condition)
|
||||
fn wait_for_change(&self) {
|
||||
loop {
|
||||
if self.current_result() != self.current.clone().unwrap() {
|
||||
break;
|
||||
}
|
||||
thread::sleep(Duration::from_millis(1));
|
||||
}
|
||||
}
|
||||
|
||||
fn wait_timeout_while<'a, F>(
|
||||
&self,
|
||||
guard: MutexGuard<'a, T>,
|
||||
dur: Duration,
|
||||
condition: F,
|
||||
) -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)>
|
||||
where
|
||||
F: FnMut(&mut T) -> bool,
|
||||
{
|
||||
self.notifier.cvar.wait_timeout_while(guard, dur, condition)
|
||||
fn current_result(&self) -> T {
|
||||
let guard = self.watching.lock().unwrap();
|
||||
guard.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -282,7 +282,6 @@ fn test_get_device_streams() {
|
||||
if let Some(device) = test_get_default_device(Scope::Input) {
|
||||
let streams = get_device_streams(device, DeviceType::INPUT).unwrap();
|
||||
println!("streams on the input device: {:?}", streams);
|
||||
assert!(!streams.is_empty());
|
||||
} else {
|
||||
println!("No input device.");
|
||||
}
|
||||
@@ -290,7 +289,6 @@ fn test_get_device_streams() {
|
||||
if let Some(device) = test_get_default_device(Scope::Output) {
|
||||
let streams = get_device_streams(device, DeviceType::OUTPUT).unwrap();
|
||||
println!("streams on the output device: {:?}", streams);
|
||||
assert!(!streams.is_empty());
|
||||
} else {
|
||||
println!("No output device.");
|
||||
}
|
||||
@@ -352,6 +350,56 @@ fn test_get_ranges_of_device_sample_rate_by_unknown_device() {
|
||||
assert!(get_ranges_of_device_sample_rate(kAudioObjectUnknown, DeviceType::INPUT).is_err());
|
||||
}
|
||||
|
||||
// get_device_stream_format
|
||||
// ------------------------------------
|
||||
#[test]
|
||||
fn test_get_device_stream_format() {
|
||||
if let Some(device) = test_get_default_device(Scope::Input) {
|
||||
let format = get_device_stream_format(device, DeviceType::INPUT).unwrap();
|
||||
println!("input stream format: {:?}", format);
|
||||
} else {
|
||||
println!("No input device.");
|
||||
}
|
||||
|
||||
if let Some(device) = test_get_default_device(Scope::Output) {
|
||||
let format = get_device_stream_format(device, DeviceType::OUTPUT).unwrap();
|
||||
println!("output stream format: {:?}", format);
|
||||
} else {
|
||||
println!("No output device.");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_get_device_stream_format_by_unknown_device() {
|
||||
assert!(get_device_stream_format(kAudioObjectUnknown, DeviceType::INPUT).is_err());
|
||||
}
|
||||
|
||||
// get_device_stream_configuration
|
||||
// ------------------------------------
|
||||
#[test]
|
||||
fn test_get_device_stream_configuration() {
|
||||
if let Some(device) = test_get_default_device(Scope::Input) {
|
||||
let buffers = get_device_stream_configuration(device, DeviceType::INPUT).unwrap();
|
||||
println!("input stream config: {:?}", buffers);
|
||||
} else {
|
||||
println!("No input device.");
|
||||
}
|
||||
|
||||
if let Some(device) = test_get_default_device(Scope::Output) {
|
||||
let buffers = get_device_stream_configuration(device, DeviceType::OUTPUT).unwrap();
|
||||
println!("output stream config: {:?}", buffers);
|
||||
} else {
|
||||
println!("No output device.");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_get_device_stream_configuration_by_unknown_device() {
|
||||
assert!(get_device_stream_configuration(kAudioObjectUnknown, DeviceType::INPUT).is_err());
|
||||
}
|
||||
|
||||
// get_stream_latency
|
||||
// ------------------------------------
|
||||
#[test]
|
||||
@@ -359,7 +407,7 @@ fn test_get_stream_latency() {
|
||||
if let Some(device) = test_get_default_device(Scope::Input) {
|
||||
let streams = get_device_streams(device, DeviceType::INPUT).unwrap();
|
||||
for stream in streams {
|
||||
let latency = get_stream_latency(stream).unwrap();
|
||||
let latency = get_stream_latency(stream, DeviceType::INPUT).unwrap();
|
||||
println!("latency of the input stream {} is {}", stream, latency);
|
||||
}
|
||||
} else {
|
||||
@@ -369,7 +417,7 @@ fn test_get_stream_latency() {
|
||||
if let Some(device) = test_get_default_device(Scope::Output) {
|
||||
let streams = get_device_streams(device, DeviceType::OUTPUT).unwrap();
|
||||
for stream in streams {
|
||||
let latency = get_stream_latency(stream).unwrap();
|
||||
let latency = get_stream_latency(stream, DeviceType::OUTPUT).unwrap();
|
||||
println!("latency of the output stream {} is {}", stream, latency);
|
||||
}
|
||||
} else {
|
||||
@@ -380,94 +428,5 @@ fn test_get_stream_latency() {
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_get_stream_latency_by_unknown_device() {
|
||||
assert!(get_stream_latency(kAudioObjectUnknown).is_err());
|
||||
}
|
||||
|
||||
// get_stream_virtual_format
|
||||
// ------------------------------------
|
||||
#[test]
|
||||
fn test_get_stream_virtual_format() {
|
||||
if let Some(device) = test_get_default_device(Scope::Input) {
|
||||
let streams = get_device_streams(device, DeviceType::INPUT).unwrap();
|
||||
let formats = streams
|
||||
.iter()
|
||||
.map(|s| get_stream_virtual_format(*s))
|
||||
.collect::<Vec<std::result::Result<AudioStreamBasicDescription, OSStatus>>>();
|
||||
println!("input stream formats: {:?}", formats);
|
||||
assert!(!formats.is_empty());
|
||||
} else {
|
||||
println!("No input device.");
|
||||
}
|
||||
|
||||
if let Some(device) = test_get_default_device(Scope::Output) {
|
||||
let streams = get_device_streams(device, DeviceType::OUTPUT).unwrap();
|
||||
let formats = streams
|
||||
.iter()
|
||||
.map(|s| get_stream_virtual_format(*s))
|
||||
.collect::<Vec<std::result::Result<AudioStreamBasicDescription, OSStatus>>>();
|
||||
println!("output stream formats: {:?}", formats);
|
||||
assert!(!formats.is_empty());
|
||||
} else {
|
||||
println!("No output device.");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_get_stream_virtual_format_by_unknown_stream() {
|
||||
assert!(get_stream_virtual_format(kAudioObjectUnknown).is_err());
|
||||
}
|
||||
|
||||
// get_stream_terminal_type
|
||||
// ------------------------------------
|
||||
|
||||
#[test]
|
||||
fn test_get_stream_terminal_type() {
|
||||
fn terminal_type_to_device_type(terminal_type: u32) -> Option<DeviceType> {
|
||||
#[allow(non_upper_case_globals)]
|
||||
match terminal_type {
|
||||
kAudioStreamTerminalTypeMicrophone
|
||||
| kAudioStreamTerminalTypeHeadsetMicrophone
|
||||
| kAudioStreamTerminalTypeReceiverMicrophone => Some(DeviceType::INPUT),
|
||||
kAudioStreamTerminalTypeSpeaker
|
||||
| kAudioStreamTerminalTypeHeadphones
|
||||
| kAudioStreamTerminalTypeLFESpeaker
|
||||
| kAudioStreamTerminalTypeReceiverSpeaker => Some(DeviceType::OUTPUT),
|
||||
t if t > INPUT_UNDEFINED && t < OUTPUT_UNDEFINED => Some(DeviceType::INPUT),
|
||||
t if t > OUTPUT_UNDEFINED && t < BIDIRECTIONAL_UNDEFINED => Some(DeviceType::OUTPUT),
|
||||
t => {
|
||||
println!("UNKNOWN TerminalType {:#06x}", t);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(device) = test_get_default_device(Scope::Input) {
|
||||
let streams = get_device_streams(device, DeviceType::INPUT).unwrap();
|
||||
for stream in streams {
|
||||
assert_eq!(
|
||||
terminal_type_to_device_type(get_stream_terminal_type(stream).unwrap()),
|
||||
Some(DeviceType::INPUT)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
println!("No input device.");
|
||||
}
|
||||
|
||||
if let Some(device) = test_get_default_device(Scope::Output) {
|
||||
let streams = get_device_streams(device, DeviceType::OUTPUT).unwrap();
|
||||
for stream in streams {
|
||||
assert_eq!(
|
||||
terminal_type_to_device_type(get_stream_terminal_type(stream).unwrap()),
|
||||
Some(DeviceType::OUTPUT)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
println!("No output device.");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_get_stream_terminal_type_by_unknown_stream() {
|
||||
assert!(get_stream_terminal_type(kAudioObjectUnknown).is_err());
|
||||
assert!(get_stream_latency(kAudioObjectUnknown, DeviceType::INPUT).is_err());
|
||||
}
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
extern crate itertools;
|
||||
|
||||
use self::itertools::iproduct;
|
||||
use super::utils::{
|
||||
noop_data_callback, test_get_default_device, test_ops_context_operation,
|
||||
test_ops_stream_operation, Scope,
|
||||
test_get_default_device, test_ops_context_operation, test_ops_stream_operation, Scope,
|
||||
};
|
||||
use super::*;
|
||||
|
||||
@@ -453,192 +449,6 @@ fn test_ops_context_register_device_collection_changed_manual() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ops_context_stream_init_no_stream_params() {
|
||||
let name = "context: stream_init with no stream params";
|
||||
test_ops_context_operation(name, |context_ptr| {
|
||||
let mut stream: *mut ffi::cubeb_stream = ptr::null_mut();
|
||||
let stream_name = CString::new(name).expect("Failed to create stream name");
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
OPS.stream_init.unwrap()(
|
||||
context_ptr,
|
||||
&mut stream,
|
||||
stream_name.as_ptr(),
|
||||
ptr::null_mut(), // Use default input device.
|
||||
ptr::null_mut(), // No input parameters.
|
||||
ptr::null_mut(), // Use default output device.
|
||||
ptr::null_mut(), // No output parameters.
|
||||
4096, // TODO: Get latency by get_min_latency instead ?
|
||||
Some(noop_data_callback),
|
||||
None, // No state callback.
|
||||
ptr::null_mut(), // No user data pointer.
|
||||
)
|
||||
},
|
||||
ffi::CUBEB_ERROR_INVALID_PARAMETER
|
||||
);
|
||||
assert!(stream.is_null());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ops_context_stream_init_no_input_stream_params() {
|
||||
let name = "context: stream_init with no input stream params";
|
||||
let input_device = test_get_default_device(Scope::Input);
|
||||
if input_device.is_none() {
|
||||
println!("No input device to perform input tests for \"{}\".", name);
|
||||
return;
|
||||
}
|
||||
test_ops_context_operation(name, |context_ptr| {
|
||||
let mut stream: *mut ffi::cubeb_stream = ptr::null_mut();
|
||||
let stream_name = CString::new(name).expect("Failed to create stream name");
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
OPS.stream_init.unwrap()(
|
||||
context_ptr,
|
||||
&mut stream,
|
||||
stream_name.as_ptr(),
|
||||
input_device.unwrap() as ffi::cubeb_devid,
|
||||
ptr::null_mut(), // No input parameters.
|
||||
ptr::null_mut(), // Use default output device.
|
||||
ptr::null_mut(), // No output parameters.
|
||||
4096, // TODO: Get latency by get_min_latency instead ?
|
||||
Some(noop_data_callback),
|
||||
None, // No state callback.
|
||||
ptr::null_mut(), // No user data pointer.
|
||||
)
|
||||
},
|
||||
ffi::CUBEB_ERROR_INVALID_PARAMETER
|
||||
);
|
||||
assert!(stream.is_null());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ops_context_stream_init_no_output_stream_params() {
|
||||
let name = "context: stream_init with no output stream params";
|
||||
let output_device = test_get_default_device(Scope::Output);
|
||||
if output_device.is_none() {
|
||||
println!("No output device to perform output tests for \"{}\".", name);
|
||||
return;
|
||||
}
|
||||
test_ops_context_operation(name, |context_ptr| {
|
||||
let mut stream: *mut ffi::cubeb_stream = ptr::null_mut();
|
||||
let stream_name = CString::new(name).expect("Failed to create stream name");
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
OPS.stream_init.unwrap()(
|
||||
context_ptr,
|
||||
&mut stream,
|
||||
stream_name.as_ptr(),
|
||||
ptr::null_mut(), // Use default input device.
|
||||
ptr::null_mut(), // No input parameters.
|
||||
output_device.unwrap() as ffi::cubeb_devid,
|
||||
ptr::null_mut(), // No output parameters.
|
||||
4096, // TODO: Get latency by get_min_latency instead ?
|
||||
Some(noop_data_callback),
|
||||
None, // No state callback.
|
||||
ptr::null_mut(), // No user data pointer.
|
||||
)
|
||||
},
|
||||
ffi::CUBEB_ERROR_INVALID_PARAMETER
|
||||
);
|
||||
assert!(stream.is_null());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ops_context_stream_init_no_data_callback() {
|
||||
let name = "context: stream_init with no data callback";
|
||||
test_ops_context_operation(name, |context_ptr| {
|
||||
let mut stream: *mut ffi::cubeb_stream = ptr::null_mut();
|
||||
let stream_name = CString::new(name).expect("Failed to create stream name");
|
||||
|
||||
let mut output_params = ffi::cubeb_stream_params::default();
|
||||
output_params.format = ffi::CUBEB_SAMPLE_FLOAT32NE;
|
||||
output_params.rate = 44100;
|
||||
output_params.channels = 2;
|
||||
output_params.layout = ffi::CUBEB_LAYOUT_UNDEFINED;
|
||||
output_params.prefs = ffi::CUBEB_STREAM_PREF_NONE;
|
||||
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
OPS.stream_init.unwrap()(
|
||||
context_ptr,
|
||||
&mut stream,
|
||||
stream_name.as_ptr(),
|
||||
ptr::null_mut(), // Use default input device.
|
||||
ptr::null_mut(), // No input parameters.
|
||||
ptr::null_mut(), // Use default output device.
|
||||
&mut output_params,
|
||||
4096, // TODO: Get latency by get_min_latency instead ?
|
||||
None, // No data callback.
|
||||
None, // No state callback.
|
||||
ptr::null_mut(), // No user data pointer.
|
||||
)
|
||||
},
|
||||
ffi::CUBEB_ERROR_INVALID_PARAMETER
|
||||
);
|
||||
assert!(stream.is_null());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ops_context_stream_init_channel_rate_combinations() {
|
||||
let name = "context: stream_init with various channels and rates";
|
||||
test_ops_context_operation(name, |context_ptr| {
|
||||
let mut stream: *mut ffi::cubeb_stream = ptr::null_mut();
|
||||
let stream_name = CString::new(name).expect("Failed to create stream name");
|
||||
|
||||
const MAX_NUM_CHANNELS: u32 = 32;
|
||||
let channel_values: Vec<u32> = vec![1, 2, 3, 4, 6];
|
||||
let freq_values: Vec<u32> = vec![16000, 24000, 44100, 48000];
|
||||
let is_float_values: Vec<bool> = vec![false, true];
|
||||
|
||||
for (channels, freq, is_float) in iproduct!(channel_values, freq_values, is_float_values) {
|
||||
assert!(channels < MAX_NUM_CHANNELS);
|
||||
println!("--------------------------");
|
||||
println!(
|
||||
"Testing {} channel(s), {} Hz, {}\n",
|
||||
channels,
|
||||
freq,
|
||||
if is_float { "float" } else { "short" }
|
||||
);
|
||||
|
||||
let mut output_params = ffi::cubeb_stream_params::default();
|
||||
output_params.format = if is_float {
|
||||
ffi::CUBEB_SAMPLE_FLOAT32NE
|
||||
} else {
|
||||
ffi::CUBEB_SAMPLE_S16NE
|
||||
};
|
||||
output_params.rate = freq;
|
||||
output_params.channels = channels;
|
||||
output_params.layout = ffi::CUBEB_LAYOUT_UNDEFINED;
|
||||
output_params.prefs = ffi::CUBEB_STREAM_PREF_NONE;
|
||||
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
OPS.stream_init.unwrap()(
|
||||
context_ptr,
|
||||
&mut stream,
|
||||
stream_name.as_ptr(),
|
||||
ptr::null_mut(), // Use default input device.
|
||||
ptr::null_mut(), // No input parameters.
|
||||
ptr::null_mut(), // Use default output device.
|
||||
&mut output_params,
|
||||
4096, // TODO: Get latency by get_min_latency instead ?
|
||||
Some(noop_data_callback), // No data callback.
|
||||
None, // No state callback.
|
||||
ptr::null_mut(), // No user data pointer.
|
||||
)
|
||||
},
|
||||
ffi::CUBEB_OK
|
||||
);
|
||||
assert!(!stream.is_null());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Stream Operations
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
fn test_default_output_stream_operation<F>(name: &'static str, operation: F)
|
||||
@@ -660,8 +470,8 @@ where
|
||||
ptr::null_mut(), // No input parameters.
|
||||
ptr::null_mut(), // Use default output device.
|
||||
&mut output_params,
|
||||
4096, // TODO: Get latency by get_min_latency instead ?
|
||||
Some(noop_data_callback),
|
||||
4096, // TODO: Get latency by get_min_latency instead ?
|
||||
None, // No data callback.
|
||||
None, // No state callback.
|
||||
ptr::null_mut(), // No user data pointer.
|
||||
operation,
|
||||
@@ -694,8 +504,8 @@ where
|
||||
&mut input_params,
|
||||
ptr::null_mut(), // Use default output device.
|
||||
&mut output_params,
|
||||
4096, // TODO: Get latency by get_min_latency instead ?
|
||||
Some(noop_data_callback),
|
||||
4096, // TODO: Get latency by get_min_latency instead ?
|
||||
None, // No data callback.
|
||||
None, // No state callback.
|
||||
ptr::null_mut(), // No user data pointer.
|
||||
operation,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::utils::{
|
||||
noop_data_callback, test_audiounit_get_buffer_frame_size, test_get_default_audiounit,
|
||||
test_get_default_device, test_ops_context_operation, PropertyScope, Scope,
|
||||
test_audiounit_get_buffer_frame_size, test_get_default_audiounit, test_get_default_device,
|
||||
test_ops_context_operation, PropertyScope, Scope,
|
||||
};
|
||||
use super::*;
|
||||
use std::thread;
|
||||
@@ -232,7 +232,7 @@ fn create_streams_by_ops_in_parallel_with_different_latency<F>(
|
||||
ptr::null_mut()
|
||||
},
|
||||
latency_frames,
|
||||
Some(noop_data_callback),
|
||||
None, // No data callback.
|
||||
None, // No state callback.
|
||||
ptr::null_mut(), // No user data pointer.
|
||||
)
|
||||
@@ -468,7 +468,7 @@ fn create_streams_in_parallel_with_different_latency<F>(
|
||||
None
|
||||
},
|
||||
latency_frames,
|
||||
Some(noop_data_callback),
|
||||
None, // No data callback.
|
||||
None, // No state callback.
|
||||
ptr::null_mut(), // No user data pointer.
|
||||
)
|
||||
|
||||
@@ -2,29 +2,6 @@ use super::*;
|
||||
|
||||
// Common Utils
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
pub extern "C" fn noop_data_callback(
|
||||
stream: *mut ffi::cubeb_stream,
|
||||
_user_ptr: *mut c_void,
|
||||
_input_buffer: *const c_void,
|
||||
output_buffer: *mut c_void,
|
||||
nframes: i64,
|
||||
) -> i64 {
|
||||
assert!(!stream.is_null());
|
||||
|
||||
// Feed silence data to output buffer
|
||||
if !output_buffer.is_null() {
|
||||
let stm = unsafe { &mut *(stream as *mut AudioUnitStream) };
|
||||
let channels = stm.core_stream_data.output_stream_params.channels();
|
||||
let samples = nframes as usize * channels as usize;
|
||||
let sample_size = cubeb_sample_size(stm.core_stream_data.output_stream_params.format());
|
||||
unsafe {
|
||||
ptr::write_bytes(output_buffer, 0, samples * sample_size);
|
||||
}
|
||||
}
|
||||
|
||||
nframes
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Scope {
|
||||
Input,
|
||||
@@ -212,7 +189,11 @@ fn test_enable_audiounit_in_scope(
|
||||
}
|
||||
|
||||
pub fn test_get_source_name(device: AudioObjectID, scope: Scope) -> Option<String> {
|
||||
test_get_source_data(device, scope).map(u32_to_string)
|
||||
if let Some(source) = test_get_source_data(device, scope) {
|
||||
Some(u32_to_string(source))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_get_source_data(device: AudioObjectID, scope: Scope) -> Option<u32> {
|
||||
@@ -257,8 +238,8 @@ fn u32_to_string(data: u32) -> String {
|
||||
}
|
||||
|
||||
pub enum DeviceFilter {
|
||||
ExcludeCubebAggregateAndVPIO,
|
||||
IncludeAll,
|
||||
ExcludeCubebAggregate,
|
||||
IncludeCubebAggregate,
|
||||
}
|
||||
pub fn test_get_all_devices(filter: DeviceFilter) -> Vec<AudioObjectID> {
|
||||
let mut devices = Vec::new();
|
||||
@@ -303,12 +284,11 @@ pub fn test_get_all_devices(filter: DeviceFilter) -> Vec<AudioObjectID> {
|
||||
}
|
||||
|
||||
match filter {
|
||||
DeviceFilter::ExcludeCubebAggregateAndVPIO => {
|
||||
DeviceFilter::ExcludeCubebAggregate => {
|
||||
devices.retain(|&device| {
|
||||
if let Ok(uid) = get_device_global_uid(device) {
|
||||
let uid = uid.into_string();
|
||||
!uid.contains(PRIVATE_AGGREGATE_DEVICE_NAME)
|
||||
&& !uid.contains(VOICEPROCESSING_AGGREGATE_DEVICE_NAME)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
@@ -321,7 +301,7 @@ pub fn test_get_all_devices(filter: DeviceFilter) -> Vec<AudioObjectID> {
|
||||
}
|
||||
|
||||
pub fn test_get_devices_in_scope(scope: Scope) -> Vec<AudioObjectID> {
|
||||
let mut devices = test_get_all_devices(DeviceFilter::ExcludeCubebAggregateAndVPIO);
|
||||
let mut devices = test_get_all_devices(DeviceFilter::ExcludeCubebAggregate);
|
||||
devices.retain(|device| test_device_in_scope(*device, scope.clone()));
|
||||
devices
|
||||
}
|
||||
@@ -343,7 +323,7 @@ pub fn get_devices_info_in_scope(scope: Scope) -> Vec<TestDeviceInfo> {
|
||||
infos.push(TestDeviceInfo::new(device, scope.clone()));
|
||||
print_info(infos.last().unwrap());
|
||||
}
|
||||
println!();
|
||||
println!("");
|
||||
|
||||
infos
|
||||
}
|
||||
@@ -625,10 +605,7 @@ pub fn test_set_default_device(
|
||||
&device as *const AudioObjectID as *const c_void,
|
||||
)
|
||||
};
|
||||
let new_default = test_get_default_device(scope.clone()).unwrap();
|
||||
if new_default == default {
|
||||
Err(-1)
|
||||
} else if status == NO_ERR {
|
||||
if status == NO_ERR {
|
||||
Ok(default)
|
||||
} else {
|
||||
Err(status)
|
||||
@@ -651,8 +628,8 @@ impl TestDeviceSwitcher {
|
||||
.position(|device| *device == current)
|
||||
.unwrap();
|
||||
Self {
|
||||
scope,
|
||||
devices,
|
||||
scope: scope,
|
||||
devices: devices,
|
||||
current_device_index: index,
|
||||
}
|
||||
}
|
||||
@@ -665,19 +642,9 @@ impl TestDeviceSwitcher {
|
||||
"Switch device for {:?}: {} -> {}",
|
||||
self.scope, current, next
|
||||
);
|
||||
match self.set_device(next) {
|
||||
Ok(prev) => {
|
||||
assert_eq!(prev, current);
|
||||
self.current_device_index = next_index;
|
||||
}
|
||||
_ => {
|
||||
self.devices.remove(next_index);
|
||||
if next_index < self.current_device_index {
|
||||
self.current_device_index -= 1;
|
||||
}
|
||||
self.next();
|
||||
}
|
||||
}
|
||||
let prev = self.set_device(next).unwrap();
|
||||
assert_eq!(prev, current);
|
||||
self.current_device_index = next_index;
|
||||
}
|
||||
|
||||
fn set_device(&self, device: AudioObjectID) -> std::result::Result<AudioObjectID, OSStatus> {
|
||||
@@ -921,9 +888,8 @@ impl TestDevicePlugger {
|
||||
);
|
||||
CFRelease(device_uid as *const c_void);
|
||||
|
||||
// Make this device NOT private to the process creating it.
|
||||
// On MacOS 14 devicechange events are not triggered when it is private.
|
||||
let private_value: i32 = 0;
|
||||
// This device is private to the process creating it.
|
||||
let private_value: i32 = 1;
|
||||
let device_private_key = CFNumberCreate(
|
||||
kCFAllocatorDefault,
|
||||
i64::from(kCFNumberIntType),
|
||||
@@ -1037,7 +1003,9 @@ impl TestDevicePlugger {
|
||||
// AggregateDevice::get_sub_devices and audiounit_set_aggregate_sub_device_list.
|
||||
fn get_sub_devices(scope: Scope) -> Option<CFArrayRef> {
|
||||
let device = test_get_default_device(scope);
|
||||
device?;
|
||||
if device.is_none() {
|
||||
return None;
|
||||
}
|
||||
let device = device.unwrap();
|
||||
let uid = get_device_global_uid(device);
|
||||
if uid.is_err() {
|
||||
@@ -1240,9 +1208,9 @@ pub fn test_get_stream_with_default_data_callback_by_type<F>(
|
||||
|
||||
bitflags! {
|
||||
pub struct StreamType: u8 {
|
||||
const INPUT = 0x01;
|
||||
const OUTPUT = 0x02;
|
||||
const DUPLEX = 0x03;
|
||||
const INPUT = 0b01;
|
||||
const OUTPUT = 0b10;
|
||||
const DUPLEX = Self::INPUT.bits | Self::OUTPUT.bits;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1284,9 +1252,32 @@ fn test_ops_stream_operation_with_default_data_callback<F>(
|
||||
output_device,
|
||||
output_stream_params,
|
||||
4096, // TODO: Get latency by get_min_latency instead ?
|
||||
Some(noop_data_callback),
|
||||
Some(data_callback),
|
||||
Some(state_callback),
|
||||
data,
|
||||
operation,
|
||||
);
|
||||
|
||||
extern "C" fn data_callback(
|
||||
stream: *mut ffi::cubeb_stream,
|
||||
_user_ptr: *mut c_void,
|
||||
_input_buffer: *const c_void,
|
||||
output_buffer: *mut c_void,
|
||||
nframes: i64,
|
||||
) -> i64 {
|
||||
assert!(!stream.is_null());
|
||||
|
||||
// Feed silence data to output buffer
|
||||
if !output_buffer.is_null() {
|
||||
let stm = unsafe { &mut *(stream as *mut AudioUnitStream) };
|
||||
let channels = stm.core_stream_data.output_stream_params.channels();
|
||||
let samples = nframes as usize * channels as usize;
|
||||
let sample_size = cubeb_sample_size(stm.core_stream_data.output_stream_params.format());
|
||||
unsafe {
|
||||
ptr::write_bytes(output_buffer, 0, samples * sample_size);
|
||||
}
|
||||
}
|
||||
|
||||
nframes
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ static_prefs = { path = "../../../../modules/libpref/init/static_prefs" }
|
||||
profiler_helper = { path = "../../../../tools/profiler/rust-helper", optional = true }
|
||||
mozurl = { path = "../../../../netwerk/base/mozurl" }
|
||||
webrender_bindings = { path = "../../../../gfx/webrender_bindings" }
|
||||
cubeb-coreaudio = { git = "https://github.com/mozilla/cubeb-coreaudio-rs", rev = "964e14628f285ad44522bdeeb566c1864ecd2fd8", optional = true }
|
||||
cubeb-coreaudio = { git = "https://github.com/mozilla/cubeb-coreaudio-rs", rev = "93b5c01a131f65c83c11aeb317f4583405c5eb79", optional = true }
|
||||
cubeb-pulse = { git = "https://github.com/mozilla/cubeb-pulse-rs", rev="cf48897be5cbe147d051ebbbe1eaf5fd8fb6bbc9", optional = true, features=["pulse-dlopen"] }
|
||||
cubeb-sys = { version = "0.10.3", optional = true, features=["gecko-in-tree"] }
|
||||
audioipc2-client = { git = "https://github.com/mozilla/audioipc", rev = "6be424d75f1367e70f2f5ddcacd6d0237e81a6a9", optional = true }
|
||||
|
||||
@@ -14,7 +14,7 @@ mozbuild = "0.1"
|
||||
|
||||
[build-dependencies]
|
||||
lazy_static = "1"
|
||||
bindgen = {version = "0.69", default-features = false}
|
||||
bindgen = {version = "0.68", default-features = false}
|
||||
mozbuild = "0.1"
|
||||
|
||||
[features]
|
||||
|
||||
Reference in New Issue
Block a user