diff --git a/.gitmodules b/.gitmodules index 871e5f3..d5a7d9b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "libcubeb-sys/libcubeb"] - path = cubeb-api/libcubeb-sys/libcubeb +[submodule "cubeb-sys/libcubeb"] + path = cubeb-sys/libcubeb url = https://github.com/kinetiknz/cubeb diff --git a/Cargo.toml b/Cargo.toml index 252338f..f6f16ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,5 +2,6 @@ members = [ "cubeb-core", "cubeb-api", - "cubeb-backend" + "cubeb-backend", + "cubeb-sys" ] \ No newline at end of file diff --git a/cubeb-api/Cargo.toml b/cubeb-api/Cargo.toml index 2703dd3..1c23db1 100644 --- a/cubeb-api/Cargo.toml +++ b/cubeb-api/Cargo.toml @@ -19,4 +19,3 @@ appveyor = { repository = "djg/cubeb-rs" } [dependencies] cubeb-core = { path = "../cubeb-core" } -libcubeb-sys = { path = "libcubeb-sys" } diff --git a/cubeb-api/libcubeb-sys/lib.rs b/cubeb-api/libcubeb-sys/lib.rs deleted file mode 100644 index 43415d5..0000000 --- a/cubeb-api/libcubeb-sys/lib.rs +++ /dev/null @@ -1,105 +0,0 @@ -#![allow(non_camel_case_types)] - -extern crate cubeb_core; - -use cubeb_core::ffi::{cubeb, cubeb_channel_layout, cubeb_data_callback, - cubeb_device, cubeb_device_changed_callback, - cubeb_device_collection, - cubeb_device_collection_changed_callback, cubeb_device_type, - cubeb_devid, cubeb_log_callback, cubeb_log_level, - cubeb_state_callback, cubeb_stream, cubeb_stream_params}; -use std::os::raw::{c_char, c_float, c_int, c_uint, c_void}; - -extern "C" { - pub fn cubeb_init( - context: *mut *mut cubeb, - context_name: *const c_char, - backend_name: *const c_char, - ) -> c_int; - pub fn cubeb_get_backend_id(context: *mut cubeb) -> *const c_char; - pub fn cubeb_get_max_channel_count( - context: *mut cubeb, - max_channels: *mut c_uint, - ) -> c_int; - pub fn cubeb_get_min_latency( - context: *mut cubeb, - params: *const cubeb_stream_params, - latency_frames: *mut c_uint, - ) -> c_int; - pub fn cubeb_get_preferred_sample_rate( - context: *mut cubeb, - rate: *mut c_uint, - ) -> c_int; - pub fn cubeb_get_preferred_channel_layout( - context: *mut cubeb, - layout: *mut cubeb_channel_layout, - ) -> c_int; - pub fn cubeb_destroy(context: *mut cubeb); - pub fn cubeb_stream_init( - context: *mut cubeb, - stream: *mut *mut cubeb_stream, - stream_name: *const c_char, - input_device: cubeb_devid, - input_stream_params: *const cubeb_stream_params, - output_device: cubeb_devid, - output_stream_params: *const cubeb_stream_params, - latency_frames: c_uint, - data_callback: cubeb_data_callback, - state_callback: cubeb_state_callback, - user_ptr: *mut c_void, - ) -> c_int; - pub fn cubeb_stream_destroy(stream: *mut cubeb_stream); - pub fn cubeb_stream_start(stream: *mut cubeb_stream) -> c_int; - pub fn cubeb_stream_stop(stream: *mut cubeb_stream) -> c_int; - pub fn cubeb_stream_reset_default_device(stream: *mut cubeb_stream) -> c_int; - pub fn cubeb_stream_get_position( - stream: *mut cubeb_stream, - position: *mut u64, - ) -> c_int; - pub fn cubeb_stream_get_latency( - stream: *mut cubeb_stream, - latency: *mut c_uint, - ) -> c_int; - pub fn cubeb_stream_set_volume( - stream: *mut cubeb_stream, - volume: c_float, - ) -> c_int; - pub fn cubeb_stream_set_panning( - stream: *mut cubeb_stream, - panning: c_float, - ) -> c_int; - pub fn cubeb_stream_get_current_device( - stream: *mut cubeb_stream, - device: *mut *const cubeb_device, - ) -> c_int; - pub fn cubeb_stream_device_destroy( - stream: *mut cubeb_stream, - devices: *const cubeb_device, - ) -> c_int; - pub fn cubeb_stream_register_device_changed_callback( - stream: *mut cubeb_stream, - device_changed_callback: cubeb_device_changed_callback, - ) -> c_int; - pub fn cubeb_enumerate_devices( - context: *mut cubeb, - devtype: cubeb_device_type, - collection: *mut cubeb_device_collection, - ) -> c_int; - pub fn cubeb_device_collection_destroy( - context: *mut cubeb, - collection: *mut cubeb_device_collection, - ) -> c_int; - pub fn cubeb_register_device_collection_changed( - context: *mut cubeb, - devtype: cubeb_device_type, - callback: cubeb_device_collection_changed_callback, - user_ptr: *mut c_void, - ) -> c_int; - pub fn cubeb_set_log_callback( - log_level: cubeb_log_level, - log_callback: cubeb_log_callback, - ) -> c_int; - - pub static g_cubeb_log_level: cubeb_log_level; - pub static g_cubeb_log_callback: Option; -} diff --git a/cubeb-api/libcubeb-sys/libcubeb b/cubeb-api/libcubeb-sys/libcubeb deleted file mode 160000 index 4c18a84..0000000 --- a/cubeb-api/libcubeb-sys/libcubeb +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4c18a84a4573a23a1c39ccf6c70f1a6c328cb110 diff --git a/cubeb-api/libcubeb-sys/Cargo.toml b/cubeb-sys/Cargo.toml similarity index 66% rename from cubeb-api/libcubeb-sys/Cargo.toml rename to cubeb-sys/Cargo.toml index 523c352..95cab0c 100644 --- a/cubeb-api/libcubeb-sys/Cargo.toml +++ b/cubeb-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "libcubeb-sys" -version = "0.1.0" +name = "cubeb-sys" +version = "0.4.0" authors = ["Dan Glastonbury "] repository = "https://github.com/djg/cubeb-rs" license = "ISC" @@ -9,13 +9,6 @@ description = "Native bindings to the cubeb library" links = "cubeb" build = "build.rs" -[lib] -name = "libcubeb_sys" -path = "lib.rs" - -[dependencies] -cubeb-core = { path = "../../cubeb-core" } - [build-dependencies] pkg-config = "0.3" cmake = "0.1.2" diff --git a/cubeb-api/libcubeb-sys/build.rs b/cubeb-sys/build.rs similarity index 93% rename from cubeb-api/libcubeb-sys/build.rs rename to cubeb-sys/build.rs index 6d1c3a5..2f85876 100644 --- a/cubeb-api/libcubeb-sys/build.rs +++ b/cubeb-sys/build.rs @@ -1,3 +1,8 @@ +// Copyright © 2018 Mozilla Foundation +// +// This program is made available under an ISC-style license. See the +// accompanying file LICENSE for details. + extern crate cmake; extern crate gcc; extern crate pkg_config; diff --git a/cubeb-sys/libcubeb b/cubeb-sys/libcubeb new file mode 160000 index 0000000..5f59ea5 --- /dev/null +++ b/cubeb-sys/libcubeb @@ -0,0 +1 @@ +Subproject commit 5f59ea59ac90f93c2bc10b4f1c3697275ac227cf diff --git a/cubeb-sys/src/callbacks.rs b/cubeb-sys/src/callbacks.rs new file mode 100644 index 0000000..551ad6e --- /dev/null +++ b/cubeb-sys/src/callbacks.rs @@ -0,0 +1,20 @@ +// Copyright © 2017-2018 Mozilla Foundation +// +// This program is made available under an ISC-style license. See the +// accompanying file LICENSE for details. + +use context::cubeb; +use std::os::raw::{c_long, c_void}; +use stream::{cubeb_state, cubeb_stream}; + +pub type cubeb_data_callback = Option< + unsafe extern fn(*mut cubeb_stream, *mut c_void, *const c_void, *mut c_void, c_long) + -> c_long, +>; +pub type cubeb_state_callback = Option< + unsafe extern fn(*mut cubeb_stream, *mut c_void, cubeb_state), +>; +pub type cubeb_device_changed_callback = Option; +pub type cubeb_device_collection_changed_callback = Option< + unsafe extern fn(*mut cubeb, *mut c_void), +>; diff --git a/cubeb-sys/src/channel.rs b/cubeb-sys/src/channel.rs new file mode 100644 index 0000000..c9cadbf --- /dev/null +++ b/cubeb-sys/src/channel.rs @@ -0,0 +1,78 @@ +// Copyright © 2017-2018 Mozilla Foundation +// +// This program is made available under an ISC-style license. See the +// accompanying file LICENSE for details. + +use std::{fmt, mem}; +use std::os::raw::{c_int, c_uint}; + +cubeb_enum! { + pub enum cubeb_channel : c_int { + CHANNEL_INVALID = -1, + CHANNEL_MONO = 0, + CHANNEL_LEFT, + CHANNEL_RIGHT, + CHANNEL_CENTER, + CHANNEL_LS, + CHANNEL_RS, + CHANNEL_RLS, + CHANNEL_RCENTER, + CHANNEL_RRS, + CHANNEL_LFE, + CHANNEL_UNMAPPED, + CHANNEL_MAX = 256, + } +} + +cubeb_enum! { + pub enum cubeb_channel_layout { + CUBEB_LAYOUT_UNDEFINED, + + CUBEB_LAYOUT_DUAL_MONO, + CUBEB_LAYOUT_DUAL_MONO_LFE, + CUBEB_LAYOUT_MONO, + CUBEB_LAYOUT_MONO_LFE, + CUBEB_LAYOUT_STEREO, + CUBEB_LAYOUT_STEREO_LFE, + CUBEB_LAYOUT_3F, + CUBEB_LAYOUT_3F_LFE, + CUBEB_LAYOUT_2F1, + CUBEB_LAYOUT_2F1_LFE, + CUBEB_LAYOUT_3F1, + CUBEB_LAYOUT_3F1_LFE, + CUBEB_LAYOUT_2F2, + CUBEB_LAYOUT_2F2_LFE, + CUBEB_LAYOUT_3F2, + CUBEB_LAYOUT_3F2_LFE, + CUBEB_LAYOUT_3F3R_LFE, + CUBEB_LAYOUT_3F4_LFE, + CUBEB_LAYOUT_MAX, + } +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct cubeb_channel_map { + pub channels: c_uint, + pub map: [cubeb_channel; CHANNEL_MAX as usize], +} + +impl Default for cubeb_channel_map { + fn default() -> Self { unsafe { mem::zeroed() } } +} + +// Explicit Debug impl to work around bug in ctest +impl fmt::Debug for cubeb_channel_map { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("cubeb_channel_map") + .field("channels", &self.channels) + .field("map", &self.map.iter().take(self.channels as usize)) + .finish() + } +} + +extern { + pub fn cubeb_channel_map_to_layout( + channel_map: *const cubeb_channel_map, + ) -> cubeb_channel_layout; +} diff --git a/cubeb-sys/src/context.rs b/cubeb-sys/src/context.rs new file mode 100644 index 0000000..a522946 --- /dev/null +++ b/cubeb-sys/src/context.rs @@ -0,0 +1,49 @@ +// Copyright © 2017-2018 Mozilla Foundation +// +// This program is made available under an ISC-style license. See the +// accompanying file LICENSE for details. + +use callbacks::{cubeb_data_callback, cubeb_state_callback}; +use channel::cubeb_channel_layout; +use device::cubeb_devid; +use std::os::raw::{c_char, c_int, c_uint, c_void}; +use stream::{cubeb_stream, cubeb_stream_params}; + +pub enum cubeb {} + +extern { + pub fn cubeb_init( + context: *mut *mut cubeb, + context_name: *const c_char, + backend_name: *const c_char, + ) -> c_int; + pub fn cubeb_get_backend_id(context: *mut cubeb) -> *const c_char; + pub fn cubeb_get_max_channel_count( + context: *mut cubeb, + max_channels: *mut c_uint, + ) -> c_int; + pub fn cubeb_get_min_latency( + context: *mut cubeb, + params: *mut cubeb_stream_params, + latency_frames: *mut c_uint, + ) -> c_int; + pub fn cubeb_get_preferred_sample_rate(context: *mut cubeb, rate: *mut c_uint) -> c_int; + pub fn cubeb_get_preferred_channel_layout( + context: *mut cubeb, + layout: *mut cubeb_channel_layout, + ) -> c_int; + pub fn cubeb_destroy(context: *mut cubeb); + pub fn cubeb_stream_init( + context: *mut cubeb, + stream: *mut *mut cubeb_stream, + stream_name: *const c_char, + input_device: cubeb_devid, + input_stream_params: *mut cubeb_stream_params, + output_device: cubeb_devid, + output_stream_params: *mut cubeb_stream_params, + latency_frames: c_uint, + data_callback: cubeb_data_callback, + state_callback: cubeb_state_callback, + user_ptr: *mut c_void, + ) -> c_int; +} diff --git a/cubeb-sys/src/device.rs b/cubeb-sys/src/device.rs new file mode 100644 index 0000000..708b725 --- /dev/null +++ b/cubeb-sys/src/device.rs @@ -0,0 +1,168 @@ +// Copyright © 2017-2018 Mozilla Foundation +// +// This program is made available under an ISC-style license. See the +// accompanying file LICENSE for details. + +use callbacks::cubeb_device_collection_changed_callback; +use context::cubeb; +use std::{fmt,mem}; +use std::os::raw::{c_char, c_int, c_uint, c_void}; + +cubeb_enum! { + pub enum cubeb_device_fmt { + CUBEB_DEVICE_FMT_S16LE = 0x0010, + CUBEB_DEVICE_FMT_S16BE = 0x0020, + CUBEB_DEVICE_FMT_F32LE = 0x1000, + CUBEB_DEVICE_FMT_F32BE = 0x2000, + } +} + +#[cfg(target_endian = "big")] +pub const CUBEB_DEVICE_FMT_S16NE: cubeb_device_fmt = CUBEB_DEVICE_FMT_S16BE; +#[cfg(target_endian = "big")] +pub const CUBEB_DEVICE_FMT_F32NE: cubeb_device_fmt = CUBEB_DEVICE_FMT_F32BE; +#[cfg(target_endian = "little")] +pub const CUBEB_DEVICE_FMT_S16NE: cubeb_device_fmt = CUBEB_DEVICE_FMT_S16LE; +#[cfg(target_endian = "little")] +pub const CUBEB_DEVICE_FMT_F32NE: cubeb_device_fmt = CUBEB_DEVICE_FMT_F32LE; + +pub const CUBEB_DEVICE_FMT_S16_MASK: cubeb_device_fmt = + (CUBEB_DEVICE_FMT_S16LE | CUBEB_DEVICE_FMT_S16BE); +pub const CUBEB_DEVICE_FMT_F32_MASK: cubeb_device_fmt = + (CUBEB_DEVICE_FMT_F32LE | CUBEB_DEVICE_FMT_F32BE); +pub const CUBEB_DEVICE_FMT_ALL: cubeb_device_fmt = + (CUBEB_DEVICE_FMT_S16_MASK | CUBEB_DEVICE_FMT_F32_MASK); + +cubeb_enum! { + pub enum cubeb_device_pref { + CUBEB_DEVICE_PREF_NONE = 0x00, + CUBEB_DEVICE_PREF_MULTIMEDIA = 0x01, + CUBEB_DEVICE_PREF_VOICE = 0x02, + CUBEB_DEVICE_PREF_NOTIFICATION = 0x04, + CUBEB_DEVICE_PREF_ALL = 0x0F, + } +} + +cubeb_enum! { + pub enum cubeb_device_state { + CUBEB_DEVICE_STATE_DISABLED, + CUBEB_DEVICE_STATE_UNPLUGGED, + CUBEB_DEVICE_STATE_ENABLED, + } +} +cubeb_enum! { + pub enum cubeb_device_type { + CUBEB_DEVICE_TYPE_UNKNOWN, + CUBEB_DEVICE_TYPE_INPUT, + CUBEB_DEVICE_TYPE_OUTPUT, + } +} + +pub type cubeb_devid = *const c_void; + +#[repr(C)] +pub struct cubeb_device { + pub output_name: *mut c_char, + pub input_name: *mut c_char, +} + +// Explicit Debug impl to work around bug in ctest +impl Default for cubeb_device { + fn default() -> Self { unsafe { mem::zeroed() } } +} + +impl fmt::Debug for cubeb_device { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("cubeb_device") + .field("output_name", &self.output_name) + .field("input_name", &self.input_name) + .finish() + } +} + +#[repr(C)] +pub struct cubeb_device_collection { + pub device: *mut cubeb_device_info, + pub count: usize, +} + +impl Default for cubeb_device_collection { + fn default() -> Self { unsafe { mem::zeroed() } } +} + +impl fmt::Debug for cubeb_device_collection { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("cubeb_device_collection") + .field("device", &self.device) + .field("count", &self.count) + .finish() + } +} + +#[repr(C)] +pub struct cubeb_device_info { + pub devid: cubeb_devid, + pub device_id: *const c_char, + pub friendly_name: *const c_char, + pub group_id: *const c_char, + pub vendor_name: *const c_char, + + pub device_type: cubeb_device_type, + pub state: cubeb_device_state, + pub preferred: cubeb_device_pref, + + pub format: cubeb_device_fmt, + pub default_format: cubeb_device_fmt, + pub max_channels: c_uint, + pub default_rate: c_uint, + pub max_rate: c_uint, + pub min_rate: c_uint, + + pub latency_lo: c_uint, + pub latency_hi: c_uint, +} + +impl Default for cubeb_device_info { + fn default() -> Self { unsafe { mem::zeroed() } } +} + +impl fmt::Debug for cubeb_device_info { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("cubeb_device_info") + .field("devid", &self.devid) + .field("device_id", &self.device_id) + .field("friendly_name", &self.friendly_name) + .field("group_id", &self.group_id) + .field("vendor_name", &self.vendor_name) + .field("device_type", &self.device_type) + .field("state", &self.state) + .field("preferred", &self.preferred) + .field("format", &self.format) + .field("default_format", &self.default_format) + .field("max_channels", &self.max_channels) + .field("default_rate", &self.default_rate) + .field("max_rate", &self.max_rate) + .field("min_rate", &self.min_rate) + .field("latency_lo", &self.latency_lo) + .field("latency_hi", &self.latency_hi) + .finish() + } +} + +extern { + pub fn cubeb_enumerate_devices( + context: *mut cubeb, + devtype: cubeb_device_type, + collection: *mut cubeb_device_collection, + ) -> c_int; + pub fn cubeb_device_collection_destroy( + context: *mut cubeb, + collection: *mut cubeb_device_collection, + ) -> c_int; + pub fn cubeb_register_device_collection_changed( + context: *mut cubeb, + devtype: cubeb_device_type, + callback: cubeb_device_collection_changed_callback, + user_ptr: *mut c_void, + ) -> c_int; +} diff --git a/cubeb-sys/src/error.rs b/cubeb-sys/src/error.rs new file mode 100644 index 0000000..5b93604 --- /dev/null +++ b/cubeb-sys/src/error.rs @@ -0,0 +1,13 @@ +// Copyright © 2017-2018 Mozilla Foundation +// +// This program is made available under an ISC-style license. See the +// accompanying file LICENSE for details. + +use std::os::raw::c_int; + +pub const CUBEB_OK: c_int = 0; +pub const CUBEB_ERROR: c_int = -1; +pub const CUBEB_ERROR_INVALID_FORMAT: c_int = -2; +pub const CUBEB_ERROR_INVALID_PARAMETER: c_int = -3; +pub const CUBEB_ERROR_NOT_SUPPORTED: c_int = -4; +pub const CUBEB_ERROR_DEVICE_UNAVAILABLE: c_int = -5; diff --git a/cubeb-sys/src/format.rs b/cubeb-sys/src/format.rs new file mode 100644 index 0000000..f9ae7d5 --- /dev/null +++ b/cubeb-sys/src/format.rs @@ -0,0 +1,22 @@ +// Copyright © 2017-2018 Mozilla Foundation +// +// This program is made available under an ISC-style license. See the +// accompanying file LICENSE for details. + +cubeb_enum! { + pub enum cubeb_sample_format { + CUBEB_SAMPLE_S16LE, + CUBEB_SAMPLE_S16BE, + CUBEB_SAMPLE_FLOAT32LE, + CUBEB_SAMPLE_FLOAT32BE, + } +} + +#[cfg(target_endian = "big")] +pub const CUBEB_SAMPLE_S16NE: cubeb_sample_format = CUBEB_SAMPLE_S16BE; +#[cfg(target_endian = "big")] +pub const CUBEB_SAMPLE_FLOAT32NE: cubeb_sample_format = CUBEB_SAMPLE_FLOAT32BE; +#[cfg(target_endian = "little")] +pub const CUBEB_SAMPLE_S16NE: cubeb_sample_format = CUBEB_SAMPLE_S16LE; +#[cfg(target_endian = "little")] +pub const CUBEB_SAMPLE_FLOAT32NE: cubeb_sample_format = CUBEB_SAMPLE_FLOAT32LE; diff --git a/cubeb-sys/src/internal.rs b/cubeb-sys/src/internal.rs new file mode 100644 index 0000000..92c90a2 --- /dev/null +++ b/cubeb-sys/src/internal.rs @@ -0,0 +1,29 @@ +// Copyright © 2017-2018 Mozilla Foundation +// +// This program is made available under an ISC-style license. See the +// accompanying file LICENSE for details. + +use std::{fmt, mem}; +use std::os::raw::{c_char, c_uint}; + +#[repr(C)] +pub struct cubeb_layout_map { + name: *const c_char, + channels: c_uint, + layout: cubeb_channel_layout, +} + +impl Default for cubeb_layout_map { + fn default() -> Self { unsafe { mem::zeroed() } } +} + +// Explicit Debug impl to work around bug in ctest +impl fmt::Debug for cubeb_layout_map { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("cubeb_layout_map") + .field("name", &self.name) + .field("channels", &self.channels) + .field("layout", &self.layout) + .finish() + } +} diff --git a/cubeb-sys/src/lib.rs b/cubeb-sys/src/lib.rs new file mode 100644 index 0000000..5fcdc57 --- /dev/null +++ b/cubeb-sys/src/lib.rs @@ -0,0 +1,33 @@ +// Copyright © 2017-2018 Mozilla Foundation +// +// This program is made available under an ISC-style license. See the +// accompanying file LICENSE for details. + +#![allow(non_camel_case_types)] + +#[macro_use] +mod macros; + +mod callbacks; +mod channel; +mod context; +mod device; +mod error; +mod format; +mod log; +mod mixer; +mod panner; +mod resampler; +mod stream; + +pub use callbacks::*; +pub use channel::*; +pub use context::*; +pub use device::*; +pub use error::*; +pub use format::*; +pub use log::*; +pub use mixer::*; +pub use panner::*; +pub use resampler::*; +pub use stream::*; diff --git a/cubeb-sys/src/log.rs b/cubeb-sys/src/log.rs new file mode 100644 index 0000000..a38c55e --- /dev/null +++ b/cubeb-sys/src/log.rs @@ -0,0 +1,26 @@ +// Copyright © 2017-2018 Mozilla Foundation +// +// This program is made available under an ISC-style license. See the +// accompanying file LICENSE for details. + +use std::os::raw::{c_char, c_int}; + +cubeb_enum! { + pub enum cubeb_log_level { + CUBEB_LOG_DISABLED = 0, + CUBEB_LOG_NORMAL = 1, + CUBEB_LOG_VERBOSE = 2, + } +} + +pub type cubeb_log_callback = Option; + +extern { + pub fn cubeb_set_log_callback( + log_level: cubeb_log_level, + log_callback: cubeb_log_callback, + ) -> c_int; + + pub static g_cubeb_log_level: cubeb_log_level; + pub static g_cubeb_log_callback: cubeb_log_callback; +} diff --git a/cubeb-sys/src/macros.rs b/cubeb-sys/src/macros.rs new file mode 100644 index 0000000..02f1b7a --- /dev/null +++ b/cubeb-sys/src/macros.rs @@ -0,0 +1,27 @@ +// Copyright © 2017-2018 Mozilla Foundation +// +// This program is made available under an ISC-style license. See the +// accompanying file LICENSE for details. + +macro_rules! cubeb_enum { + (pub enum $name:ident { $($variants:tt)* }) => { + #[cfg(target_env = "msvc")] + pub type $name = i32; + #[cfg(not(target_env = "msvc"))] + pub type $name = u32; + cubeb_enum!(gen, $name, 0, $($variants)*); + }; + (pub enum $name:ident: $t:ty { $($variants:tt)* }) => { + pub type $name = $t; + cubeb_enum!(gen, $name, 0, $($variants)*); + }; + (gen, $name:ident, $val:expr, $variant:ident, $($rest:tt)*) => { + pub const $variant: $name = $val; + cubeb_enum!(gen, $name, $val+1, $($rest)*); + }; + (gen, $name:ident, $val:expr, $variant:ident = $e:expr, $($rest:tt)*) => { + pub const $variant: $name = $e; + cubeb_enum!(gen, $name, $e+1, $($rest)*); + }; + (gen, $name:ident, $val:expr, ) => {} +} diff --git a/cubeb-sys/src/mixer.rs b/cubeb-sys/src/mixer.rs new file mode 100644 index 0000000..591e948 --- /dev/null +++ b/cubeb-sys/src/mixer.rs @@ -0,0 +1,47 @@ +// Copyright © 2017-2018 Mozilla Foundation +// +// This program is made available under an ISC-style license. See the +// accompanying file LICENSE for details. + +use channel::{cubeb_channel, CHANNEL_MAX, CUBEB_LAYOUT_MAX}; +use format::cubeb_sample_format; +use std::os::raw::{c_long, c_uchar, c_ulong, c_void}; +use stream::cubeb_stream_params; + +cubeb_enum! { + pub enum cubeb_mixer_direction { + CUBEB_MIXER_DIRECTION_DOWNMIX = 0x01, + CUBEB_MIXER_DIRECTION_UPMIX = 0x02, + } +} + +pub enum cubeb_mixer {} + +extern { + pub fn cubeb_should_upmix(stream: *const cubeb_stream_params, + mixer: *const cubeb_stream_params) + -> bool; + pub fn cubeb_should_downmix(stream: *const cubeb_stream_params, + mixer: *const cubeb_stream_params) + -> bool; + pub fn cubeb_should_mix(stream: *const cubeb_stream_params, + mixer: *const cubeb_stream_params) + -> bool; + + pub fn cubeb_mixer_create(format: cubeb_sample_format, + direction: c_uchar) + -> *mut cubeb_mixer; + pub fn cubeb_mixer_destroy(mixer: *mut cubeb_mixer); + pub fn cubeb_mixer_mix(mixer: *mut cubeb_mixer, + frames: c_long, + input_buffer: *mut c_void, + input_buffer_length: c_ulong, + output_buffer: *mut c_void, + output_buffer_length: c_ulong, + stream_params: *const cubeb_stream_params, + mixer_params: *const cubeb_stream_params); + + + pub static CHANNEL_INDEX_TO_ORDER: + [[cubeb_channel; CHANNEL_MAX as usize]; CUBEB_LAYOUT_MAX as usize]; +} diff --git a/cubeb-sys/src/panner.rs b/cubeb-sys/src/panner.rs new file mode 100644 index 0000000..74fa84e --- /dev/null +++ b/cubeb-sys/src/panner.rs @@ -0,0 +1,15 @@ +// Copyright © 2017-2018 Mozilla Foundation +// +// This program is made available under an ISC-style license. See the +// accompanying file LICENSE for details. + +use std::os::raw::{c_float, c_short}; + +extern { + pub fn cubeb_pan_stereo_buffer_float(buf: *mut c_float, + frames: u32, + pan: c_float); + pub fn cubeb_pan_stereo_buffer_int(buf: *mut c_short, + frames: u32, + pan: c_float); +} diff --git a/cubeb-sys/src/resampler.rs b/cubeb-sys/src/resampler.rs new file mode 100644 index 0000000..cf74c35 --- /dev/null +++ b/cubeb-sys/src/resampler.rs @@ -0,0 +1,39 @@ +// Copyright © 2017-2018 Mozilla Foundation +// +// This program is made available under an ISC-style license. See the +// accompanying file LICENSE for details. + +use callbacks::cubeb_data_callback; +use std::os::raw::{c_long, c_uint, c_void}; +use stream::{cubeb_stream, cubeb_stream_params}; + +pub enum cubeb_resampler {} + +cubeb_enum! { + pub enum cubeb_resampler_quality { + CUBEB_RESAMPLER_QUALITY_VOIP, + CUBEB_RESAMPLER_QUALITY_DEFAULT, + CUBEB_RESAMPLER_QUALITY_DESKTOP, + } +} + +extern { + pub fn cubeb_resampler_create(stream: *mut cubeb_stream, + input_params: *mut cubeb_stream_params, + output_params: *mut cubeb_stream_params, + target_rate: c_uint, + callback: cubeb_data_callback, + user_ptr: *mut c_void, + quality: cubeb_resampler_quality) + -> *mut cubeb_resampler; + + pub fn cubeb_resampler_fill(resampler: *mut cubeb_resampler, + input_buffer: *mut c_void, + input_frame_count: *mut c_long, + output_buffer: *mut c_void, + output_frames_needed: c_long) + -> c_long; + + pub fn cubeb_resampler_destroy(resampler: *mut cubeb_resampler); + pub fn cubeb_resampler_latency(resampler: *mut cubeb_resampler) -> c_long; +} diff --git a/cubeb-sys/src/stream.rs b/cubeb-sys/src/stream.rs new file mode 100644 index 0000000..e1f4357 --- /dev/null +++ b/cubeb-sys/src/stream.rs @@ -0,0 +1,80 @@ +// Copyright © 2017-2018 Mozilla Foundation +// +// This program is made available under an ISC-style license. See the +// accompanying file LICENSE for details. + +use callbacks::cubeb_device_changed_callback; +use channel::cubeb_channel_layout; +use device::cubeb_device; +use format::cubeb_sample_format; +use std::{fmt, mem}; +use std::os::raw::{c_float, c_int, c_uint, c_void}; + +cubeb_enum! { + pub enum cubeb_stream_prefs { + CUBEB_STREAM_PREF_NONE = 0x00, + CUBEB_STREAM_PREF_LOOPBACK = 0x01, + } +} + +cubeb_enum! { + pub enum cubeb_state { + CUBEB_STATE_STARTED, + CUBEB_STATE_STOPPED, + CUBEB_STATE_DRAINED, + CUBEB_STATE_ERROR, + } +} + +pub enum cubeb_stream {} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct cubeb_stream_params { + pub format: cubeb_sample_format, + pub rate: c_uint, + pub channels: c_uint, + pub layout: cubeb_channel_layout, + pub prefs: cubeb_stream_prefs, +} + +impl Default for cubeb_stream_params { + fn default() -> Self { unsafe { mem::zeroed() } } +} + +// Explicit Debug impl to work around bug in ctest +impl fmt::Debug for cubeb_stream_params { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("cubeb_stream_params") + .field("format", &self.format) + .field("rate", &self.rate) + .field("channels", &self.channels) + .field("layout", &self.layout) + .field("prefs", &self.prefs) + .finish() + } +} + +extern { + pub fn cubeb_stream_destroy(stream: *mut cubeb_stream); + pub fn cubeb_stream_start(stream: *mut cubeb_stream) -> c_int; + pub fn cubeb_stream_stop(stream: *mut cubeb_stream) -> c_int; + pub fn cubeb_stream_reset_default_device(stream: *mut cubeb_stream) -> c_int; + pub fn cubeb_stream_get_position(stream: *mut cubeb_stream, position: *mut u64) -> c_int; + pub fn cubeb_stream_get_latency(stream: *mut cubeb_stream, latency: *mut c_uint) -> c_int; + pub fn cubeb_stream_set_volume(stream: *mut cubeb_stream, volume: c_float) -> c_int; + pub fn cubeb_stream_set_panning(stream: *mut cubeb_stream, panning: c_float) -> c_int; + pub fn cubeb_stream_get_current_device( + stream: *mut cubeb_stream, + device: *mut *mut cubeb_device, + ) -> c_int; + pub fn cubeb_stream_device_destroy( + stream: *mut cubeb_stream, + devices: *mut cubeb_device, + ) -> c_int; + pub fn cubeb_stream_register_device_changed_callback( + stream: *mut cubeb_stream, + device_changed_callback: cubeb_device_changed_callback, + ) -> c_int; + pub fn cubeb_stream_user_ptr(stream: *mut cubeb_stream) -> *mut c_void; +}