### Cubeb StreamBuilder Example: Sine Wave Generation Source: https://docs.rs/cubeb/0.33.0/src/cubeb/stream.rs_search=std%3A%3Avec This example demonstrates the initialization of a Cubeb context and the setup of an audio stream using `StreamBuilder`. It configures parameters for a mono, 16-bit signed little-endian output stream and sets up a sine wave generation callback. ```rust use cubeb::{Context, MonoFrame, Sample}; use std::f32::consts::PI; use std::thread; use std::time::Duration; const SAMPLE_FREQUENCY: u32 = 48_000; const STREAM_FORMAT: cubeb::SampleFormat = cubeb::SampleFormat::S16LE; type Frame = MonoFrame; let ctx = Context::init(None, None).unwrap(); let params = cubeb::StreamParamsBuilder::new() .format(STREAM_FORMAT) .rate(SAMPLE_FREQUENCY) .channels(1) .layout(cubeb::ChannelLayout::MONO) .prefs(cubeb::StreamPrefs::DUCKING) .take(); let freq = 440.0; let mut phase = 0.0f32; let phase_inc = freq / SAMPLE_FREQUENCY as f32; let volume = 0.25; let mut builder = cubeb::StreamBuilder::::new(); builder .name("Cubeb Sine Wave") .output(&ctx, ¶ms) .data_callback(move |_, output| { for x in output.iter_mut() { x.m = ( (phase * 2.0 * PI).sin() * volume * (i16::MAX as f32) ) as i16; phase = (phase + phase_inc) % 1.0; } output.len() as isize }) .state_callback(|state| { println!("Stream state: {:?}", state); }); let stream = builder.init(&ctx).expect("Failed to initialize stream"); stream.start().unwrap(); thread::sleep(Duration::from_secs(1)); stream.stop().unwrap(); ``` -------------------------------- ### Cubeb Stream Builder Example Source: https://docs.rs/cubeb/0.33.0/src/cubeb/stream.rs_search=u32+-%3E+bool Illustrates the initialization of a cubeb audio context and the setup of stream parameters using `StreamParamsBuilder`. This code snippet sets the sample format, rate, channels, and layout for an audio stream. ```rust /// Stream builder /// /// ```no_run /// use cubeb::{Context, MonoFrame, Sample}; /// use std::f32::consts::PI; /// use std::thread; /// use std::time::Duration; /// /// const SAMPLE_FREQUENCY: u32 = 48_000; /// const STREAM_FORMAT: cubeb::SampleFormat = cubeb::SampleFormat::S16LE; /// type Frame = MonoFrame; /// /// let ctx = Context::init(None, None).unwrap(); ``` -------------------------------- ### Control Audio Stream Playback in Rust Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.StreamRef_search=std%3A%3Avec Demonstrates how to start and stop an audio stream using the StreamRef. It includes a complete example of initializing a cubeb context, setting up stream parameters, defining a data callback to generate audio data, and then starting and stopping the stream playback. ```rust pub fn start(&self) -> Result<(), Error> pub fn stop(&self) -> Result<(), Error> ``` ```rust fn main() { let ctx = common::init("Cubeb tone example").expect("Failed to create cubeb context"); let params = cubeb::StreamParamsBuilder::new() .format(STREAM_FORMAT) .rate(SAMPLE_FREQUENCY) .channels(1) .layout(cubeb::ChannelLayout::MONO) .take(); let mut position = 0u32; let mut builder = cubeb::StreamBuilder::::new(); builder .name("Cubeb tone (mono)") .default_output(¶ms) .latency(0x1000) .data_callback(move |_, output| { // generate our test tone on the fly for f in output.iter_mut() { // North American dial tone let t1 = (2.0 * PI * 350.0 * position as f32 / SAMPLE_FREQUENCY as f32).sin(); let t2 = (2.0 * PI * 440.0 * position as f32 / SAMPLE_FREQUENCY as f32).sin(); f.m = i16::from_float(0.5 * (t1 + t2)); position += 1; } output.len() as isize }) .state_callback(|state| { println!("stream {:?}", state); }); let stream = builder.init(&ctx).expect("Failed to create cubeb stream"); stream.start().unwrap(); thread::sleep(Duration::from_millis(500)); stream.stop().unwrap(); } ``` -------------------------------- ### Start Audio Stream Playback (Rust) Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.StreamRef_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Initiates playback for an audio stream. This function returns a Result, indicating success or an Error if the stream fails to start. The example demonstrates starting a tone generation stream. ```rust pub fn start(&self) -> Result<(), Error> ``` ```rust 57 stream.start().unwrap(); ``` -------------------------------- ### Stream Creation and Playback Example Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.Stream_search= This example demonstrates how to initialize a Cubeb stream, configure its parameters, generate audio data (a square wave in this case), and control playback. ```APIDOC ## Stream ### Description Represents an audio input/output stream. ### Methods #### `as_ptr(&self) -> *mut cubeb_stream` Returns a raw pointer to the underlying `cubeb_stream`. ### Example ```rust extern crate cubeb; use std::thread; use std::time::Duration; type Frame = cubeb::MonoFrame; fn main() { let ctx = cubeb::init("Cubeb tone example").unwrap(); let params = cubeb::StreamParamsBuilder::new() .format(cubeb::SampleFormat::Float32LE) .rate(44_100) .channels(1) .layout(cubeb::ChannelLayout::MONO) .prefs(cubeb::StreamPrefs::NONE) .take(); let phase_inc = 440.0 / 44_100.0; let mut phase = 0.0; let volume = 0.25; let mut builder = cubeb::StreamBuilder::::new(); builder .name("Cubeb Square Wave") .default_output(¶ms) .latency(0x1000) .data_callback(move |_, output| { // Generate a square wave for x in output.iter_mut() { x.m = if phase < 0.5 { volume } else { -volume }; phase = (phase + phase_inc) % 1.0; } output.len() as isize }) .state_callback(|state| { println!("stream {:?}", state); }); let stream = builder.init(&ctx).expect("Failed to create stream."); // Start playback stream.start().unwrap(); // Play for 1/2 second thread::sleep(Duration::from_millis(500)); // Shutdown stream.stop().unwrap(); } ``` ``` -------------------------------- ### Example: Checking Device Capabilities with DeviceFormat (Rust) Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.DeviceFormat_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Demonstrates how to use the `contains()` method of `DeviceFormat` to check for specific audio sample formats supported by a device. This example iterates through available formats and prints them, along with other device information. ```rust fn print_device_info(info: &cubeb::DeviceInfo) { let devtype = if info.device_type().contains(DeviceType::INPUT) { "input" } else if info.device_type().contains(DeviceType::OUTPUT) { "output" } else { "unknown?" }; let devstate = match info.state() { cubeb::DeviceState::Disabled => "disabled", cubeb::DeviceState::Unplugged => "unplugged", cubeb::DeviceState::Enabled => "enabled", }; let devdeffmt = match info.default_format() { DeviceFormat::S16LE => "S16LE", DeviceFormat::S16BE => "S16BE", DeviceFormat::F32LE => "F32LE", DeviceFormat::F32BE => "F32BE", _ => "unknown?", }; let mut devfmts = "".to_string(); if info.format().contains(DeviceFormat::S16LE) { devfmts = format!("{} S16LE", devfmts); } if info.format().contains(DeviceFormat::S16BE) { devfmts = format!("{} S16BE", devfmts); } if info.format().contains(DeviceFormat::F32LE) { devfmts = format!("{} F32LE", devfmts); } if info.format().contains(DeviceFormat::F32BE) { devfmts = format!("{} F32BE", devfmts); } if let Some(device_id) = info.device_id() { let preferred = if info.preferred().is_empty() { "" } else { " (PREFERRED)" }; println!("dev: \"{{}}\"{{}}", device_id, preferred); } if let Some(friendly_name) = info.friendly_name() { println!("\tName: \"{{}}\"", friendly_name); } if let Some(group_id) = info.group_id() { println!("\tGroup: \"{{}}\"", group_id); } if let Some(vendor_name) = info.vendor_name() { println!("\tVendor: \"{{}}\"", vendor_name); } println!("\tType: {{}}", devtype); println!("\tState: {{}}", devstate); println!("\tCh: {{}}", info.max_channels()); println!( "\tFormat: {{}} (0x{{:x}}) (default: {{}})", &devfmts[1..], info.format(), devdeffmt ); println!( "\tRate: {{}} - {{}} (default: {{}})", info.min_rate(), info.max_rate(), info.default_rate() ); println!( "\tLatency: lo {{}} frames, hi {{}} frames", info.latency_lo(), info.latency_hi() ); } ``` -------------------------------- ### Stream Example Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.Stream_search=std%3A%3Avec An example demonstrating the creation and playback of a simple audio tone using the cubeb Stream API. ```APIDOC ## §Example ```rust extern crate cubeb; use std::thread; use std::time::Duration; type Frame = cubeb::MonoFrame; fn main() { let ctx = cubeb::init("Cubeb tone example").unwrap(); let params = cubeb::StreamParamsBuilder::new() .format(cubeb::SampleFormat::Float32LE) .rate(44_100) .channels(1) .layout(cubeb::ChannelLayout::MONO) .prefs(cubeb::StreamPrefs::NONE) .take(); let phase_inc = 440.0 / 44_100.0; let mut phase = 0.0; let volume = 0.25; let mut builder = cubeb::StreamBuilder::::new(); builder .name("Cubeb Square Wave") .default_output(¶ms) .latency(0x1000) .data_callback(move |_, output| { // Generate a square wave for x in output.iter_mut() { x.m = if phase < 0.5 { volume } else { -volume }; phase = (phase + phase_inc) % 1.0; } output.len() as isize }) .state_callback(|state| { println!("stream {:?}", state); }); let stream = builder.init(&ctx).expect("Failed to create stream."); // Start playback stream.start().unwrap(); // Play for 1/2 second thread::sleep(Duration::from_millis(500)); // Shutdown stream.stop().unwrap(); } ``` ``` -------------------------------- ### Print Device Information (Example) Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.DeviceInfo An example function demonstrating how to iterate through and print various properties of a cubeb::DeviceInfo object. It showcases how to interpret device types, states, formats, and other attributes. ```rust fn print_device_info(info: &cubeb::DeviceInfo) { let devtype = if info.device_type().contains(DeviceType::INPUT) { "input" } else if info.device_type().contains(DeviceType::OUTPUT) { "output" } else { "unknown?" }; let devstate = match info.state() { cubeb::DeviceState::Disabled => "disabled", cubeb::DeviceState::Unplugged => "unplugged", cubeb::DeviceState::Enabled => "enabled", }; let devdeffmt = match info.default_format() { DeviceFormat::S16LE => "S16LE", DeviceFormat::S16BE => "S16BE", DeviceFormat::F32LE => "F32LE", DeviceFormat::F32BE => "F32BE", _ => "unknown?", }; let mut devfmts = "".to_string(); if info.format().contains(DeviceFormat::S16LE) { devfmts = format!("{} S16LE", devfmts); } if info.format().contains(DeviceFormat::S16BE) { devfmts = format!("{} S16BE", devfmts); } if info.format().contains(DeviceFormat::F32LE) { devfmts = format!("{} F32LE", devfmts); } if info.format().contains(DeviceFormat::F32BE) { devfmts = format!("{} F32BE", devfmts); } if let Some(device_id) = info.device_id() { let preferred = if info.preferred().is_empty() { "" } else { " (PREFERRED)" }; println!("dev: \"{}\" {}{}", device_id, preferred); } if let Some(friendly_name) = info.friendly_name() { println!("\tName: \"{}\"", friendly_name); } if let Some(group_id) = info.group_id() { println!("\tGroup: \"{}\"", group_id); } if let Some(vendor_name) = info.vendor_name() { println!("\tVendor: \"{}\"", vendor_name); } println!("\tType: {}", devtype); println!("\tState: {}", devstate); println!("\tCh: {}", info.max_channels()); println!( "\tFormat: {} (0x{:x}) (default: {})", &devfmts[1..], info.format(), devdeffmt ); println!( "\tRate: {} - {} (default: {})", info.min_rate(), info.max_rate(), info.default_rate() ); println!( "\tLatency: lo {} frames, hi {} frames", info.latency_lo(), info.latency_hi() ); } ``` -------------------------------- ### Example: Print Audio Device Information in Rust Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.DeviceInfo_search=u32+-%3E+bool This example demonstrates how to iterate through audio devices and print detailed information for each. It utilizes various methods of the `DeviceInfo` struct to display device type, state, supported formats, rates, latency, and identifiers. ```rust 15fn print_device_info(info: &cubeb::DeviceInfo) { 16 let devtype = if info.device_type().contains(DeviceType::INPUT) { 17 "input" 18 } else if info.device_type().contains(DeviceType::OUTPUT) { 19 "output" 20 } else { 21 "unknown?" 22 }; 23 24 let devstate = match info.state() { 25 cubeb::DeviceState::Disabled => "disabled", 26 cubeb::DeviceState::Unplugged => "unplugged", 27 cubeb::DeviceState::Enabled => "enabled", 28 }; 29 30 let devdeffmt = match info.default_format() { 31 DeviceFormat::S16LE => "S16LE", 32 DeviceFormat::S16BE => "S16BE", 33 DeviceFormat::F32LE => "F32LE", 34 DeviceFormat::F32BE => "F32BE", 35 _ => "unknown?", 36 }; 37 38 let mut devfmts = "".to_string(); 39 if info.format().contains(DeviceFormat::S16LE) { 40 devfmts = format!("{} S16LE", devfmts); 41 } 42 if info.format().contains(DeviceFormat::S16BE) { 43 devfmts = format!("{} S16BE", devfmts); 44 } 45 if info.format().contains(DeviceFormat::F32LE) { 46 devfmts = format!("{} F32LE", devfmts); 47 } 48 if info.format().contains(DeviceFormat::F32BE) { 49 devfmts = format!("{} F32BE", devfmts); 50 } 51 52 if let Some(device_id) = info.device_id() { 53 let preferred = if info.preferred().is_empty() { 54 "" 55 } else { 56 " (PREFERRED)" 57 }; 58 println!("dev: \"{}\"", device_id, preferred); 59 } 60 if let Some(friendly_name) = info.friendly_name() { 61 println!("\tName: \"{}\"", friendly_name); 62 } 63 if let Some(group_id) = info.group_id() { 64 println!("\tGroup: \"{}\"", group_id); 65 } 66 if let Some(vendor_name) = info.vendor_name() { 67 println!("\tVendor: \"{}\"", vendor_name); 68 } 69 println!("\tType: {}", devtype); 70 println!("\tState: {}", devstate); 71 println!("\tCh: {}", info.max_channels()); 72 println!( 73 "\tFormat: {} (0x{{:x}}) (default: {{}})", 74 &devfmts[1..], 75 info.format(), 76 devdeffmt 77 ); 78 println!( 79 "\tRate: {} - {} (default: {{}}))", 80 info.min_rate(), 81 info.max_rate(), 82 info.default_rate() 83 ); 84 println!( 85 "\tLatency: lo {} frames, hi {} frames", 86 info.latency_lo(), 87 info.latency_hi() 88 ); 89} ``` -------------------------------- ### Stream Start API Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.Stream_search=u32+-%3E+bool Starts audio playback for the stream. ```APIDOC ## pub fn start(&self) -> Result<(), Error> ### Description Start playback. ### Method GET ### Endpoint N/A (Method on Stream object) ### Parameters None ### Request Body None ### Response #### Success Response (200) `()` #### Response Example None (Success is unit type) ### Error Handling Returns `Err` if playback cannot be started. ``` -------------------------------- ### Enable Rustdoc Example Scraping with Cargo Source: https://docs.rs/cubeb/0.33.0/scrape-examples-help Shows the command to enable Rustdoc's unstable feature for scraping examples. This command analyzes documented crates and includes source code snippets of item usages in the generated documentation. ```bash cargo doc -Zunstable-options -Zrustdoc-scrape-examples ``` -------------------------------- ### Create and Play Audio Stream with Dial Tone Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.Stream Demonstrates creating an audio stream and generating a North American dial tone. It configures the stream and uses a data callback to synthesize the two frequencies that constitute the dial tone. The example includes starting and stopping the stream after a brief delay. ```rust fn main() { let ctx = common::init("Cubeb tone example").expect("Failed to create cubeb context"); let params = cubeb::StreamParamsBuilder::new() .format(STREAM_FORMAT) .rate(SAMPLE_FREQUENCY) .channels(1) .layout(cubeb::ChannelLayout::MONO) .take(); let mut position = 0u32; let mut builder = cubeb::StreamBuilder::::new(); builder .name("Cubeb tone (mono)") .default_output(¶ms) .latency(0x1000) .data_callback(move |_, output| { // generate our test tone on the fly for f in output.iter_mut() { // North American dial tone let t1 = (2.0 * PI * 350.0 * position as f32 / SAMPLE_FREQUENCY as f32).sin(); let t2 = (2.0 * PI * 440.0 * position as f32 / SAMPLE_FREQUENCY as f32).sin(); f.m = i16::from_float(0.5 * (t1 + t2)); position += 1; } output.len() as isize }) .state_callback(|state| { println!("stream {:?}", state); }); let stream = builder.init(&ctx).expect("Failed to create cubeb stream"); stream.start().unwrap(); thread::sleep(Duration::from_millis(500)); stream.stop().unwrap(); } ``` -------------------------------- ### Start Cubeb Stream Source: https://docs.rs/cubeb/0.33.0/cubeb/ffi/fn.cubeb_stream_start_search=std%3A%3Avec Starts an audio stream using the cubeb library. This function is part of the cubeb::ffi module. ```APIDOC ## cubeb_stream_start ### Description Starts an audio stream. ### Method `unsafe extern "C"` ### Endpoint N/A (C function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body * **stream** (*mut cubeb_stream*) - Required - A pointer to the cubeb_stream structure to start. ### Request Example N/A (C function signature) ### Response #### Success Response (0) Returns 0 on success. #### Error Response (-1) Returns -1 on failure. #### Response Example `0` (on success) `-1` (on failure) ``` -------------------------------- ### cubeb_audio_dump_start Source: https://docs.rs/cubeb/0.33.0/cubeb/ffi/fn.cubeb_audio_dump_start_search=std%3A%3Avec Starts an audio dump session. This function is marked as unsafe, indicating that it requires careful handling by the caller. ```APIDOC ## cubeb_audio_dump_start ### Description Starts an audio dump session using the provided session pointer. ### Method ``` pub unsafe extern "C" fn cubeb_audio_dump_start( session: *mut cubeb_audio_dump_session, ) -> i32 ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **session** (*mut cubeb_audio_dump_session) - Required - A mutable pointer to a `cubeb_audio_dump_session` structure that will be used to manage the audio dump. ### Request Example This function does not have a request body in the typical HTTP sense. It operates on a C-style pointer passed directly. ### Response #### Success Response (0) Returns `0` on success. #### Error Response (Non-zero) Returns a non-zero value on failure. The specific error codes are not detailed in this documentation. #### Response Example ``` 0 // Success -1 // Failure (example) ``` ``` -------------------------------- ### Print Formatted Device Information in Rust Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.DeviceInfo_search= An example function demonstrating how to print detailed information about a cubeb::DeviceInfo object. It includes device type, state, supported formats, ID, name, vendor, and latency. This code snippet is extracted from the repository's examples. ```rust 15fn print_device_info(info: &cubeb::DeviceInfo) { 16 let devtype = if info.device_type().contains(DeviceType::INPUT) { 17 "input" 18 } else if info.device_type().contains(DeviceType::OUTPUT) { 19 "output" 20 } else { 21 "unknown?" 22 }; 23 24 let devstate = match info.state() { 25 cubeb::DeviceState::Disabled => "disabled", 26 cubeb::DeviceState::Unplugged => "unplugged", 27 cubeb::DeviceState::Enabled => "enabled", 28 }; 29 30 let devdeffmt = match info.default_format() { 31 DeviceFormat::S16LE => "S16LE", 32 DeviceFormat::S16BE => "S16BE", 33 DeviceFormat::F32LE => "F32LE", 34 DeviceFormat::F32BE => "F32BE", 35 _ => "unknown?", 36 }; 37 38 let mut devfmts = "".to_string(); 39 if info.format().contains(DeviceFormat::S16LE) { 40 devfmts = format!("{} S16LE", devfmts); 41 } 42 if info.format().contains(DeviceFormat::S16BE) { 43 devfmts = format!("{} S16BE", devfmts); 44 } 45 if info.format().contains(DeviceFormat::F32LE) { 46 devfmts = format!("{} F32LE", devfmts); 47 } 48 if info.format().contains(DeviceFormat::F32BE) { 49 devfmts = format!("{} F32BE", devfmts); 50 } 51 52 if let Some(device_id) = info.device_id() { 53 let preferred = if info.preferred().is_empty() { 54 "" 55 } else { 56 " (PREFERRED)" 57 }; 58 println!("dev: \"{}\"", device_id, preferred); 59 } 60 if let Some(friendly_name) = info.friendly_name() { 61 println!("\tName: \"{}\"", friendly_name); 62 } 63 if let Some(group_id) = info.group_id() { 64 println!("\tGroup: \"{}\"", group_id); 65 } 66 if let Some(vendor_name) = info.vendor_name() { 67 println!("\tVendor: \"{}\"", vendor_name); 68 } 69 println!("\tType: ", devtype); 70 println!("\tState: ", devstate); 71 println!("\tCh: ", info.max_channels()); 72 println!( 73 "\tFormat: {} (0x{:x}) (default: )", 74 &devfmts[1..], 75 info.format(), 76 devdeffmt 77 ); 78 println!( 79 "\tRate: {} - {} (default: )", 80 info.min_rate(), 81 info.max_rate(), 82 info.default_rate() 83 ); 84 println!( 85 "\tLatency: lo {} frames, hi {} frames", 86 info.latency_lo(), 87 info.latency_hi() 88 ); 89} ``` -------------------------------- ### Example cubeb Initialization Helper Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.Context A helper function to initialize a cubeb context, demonstrating how to handle environment variables for backend selection and string conversion. It also includes logic for checking if the requested backend matches the one provided by cubeb. ```Rust pub fn init>>(ctx_name: T) -> Result { let backend = match env::var("CUBEB_BACKEND") { Ok(s) => Some(s), Err(_) => None, }; let ctx_name = CString::new(ctx_name).unwrap(); let ctx = Context::init(Some(ctx_name.as_c_str()), None); if let Ok(ref ctx) = ctx { if let Some(ref backend) = backend { let ctx_backend = ctx.backend_id(); if backend != ctx_backend { let stderr = io::stderr(); let mut handle = stderr.lock(); writeln!( handle, "Requested backend `{{}}', got `{}`", backend, ctx_backend ) .unwrap(); } } } ctx } ``` -------------------------------- ### libcubeb Bindings for Rust Source: https://docs.rs/cubeb/0.33.0/cubeb/index_search=u32+-%3E+bool This library contains bindings to the cubeb C library which is used to interact with system audio. The library itself is a work in progress and is likely lacking documentation and test. The cubeb-rs library exposes the user API of libcubeb. It doesn’t expose the internal interfaces, so isn’t suitable for extending libcubeb. See cubeb-pulse-rs for an example of extending libcubeb via implementing a cubeb backend in rust. To get started, have a look at the `StreamBuilder`. ```APIDOC ## Crate cubeb ### Description This library contains bindings to the cubeb C library which is used to interact with system audio. The library itself is a work in progress and is likely lacking documentation and test. The cubeb-rs library exposes the user API of libcubeb. It doesn’t expose the internal interfaces, so isn’t suitable for extending libcubeb. See cubeb-pulse-rs for an example of extending libcubeb via implementing a cubeb backend in rust. To get started, have a look at the `StreamBuilder`. ### Modules - `ffi` ### Structs - **ChannelLayout**: Some common layout definitions - **Context** - **ContextRef** - **Device** - **DeviceCollection** - **DeviceCollectionRef** - **DeviceFormat**: Architecture specific sample type. - **DeviceInfo** - **DeviceInfoRef** - **DeviceRef** - **DeviceType**: Whether a particular device is an input device (e.g. a microphone), or an output device (e.g. headphones). - **MonoFrame**: A monaural frame. - **StereoFrame**: A stereo frame. - **Stream**: Audio input/output stream - **StreamBuilder**: Stream builder - **StreamCallbacks** - **StreamParams** - **StreamParamsBuilder** - **StreamParamsRef** - **StreamPrefs**: Miscellaneous stream preferences. - **StreamRef ### Enums - **DeviceState**: The state of a device. - **Error**: An enumeration of possible errors that can happen when working with cubeb. - **LogLevel**: Level (verbosity) of logging for a particular cubeb context. - **SampleFormat** - **State**: Stream states signaled via `state_callback`. ### Traits - **Frame**: A `Frame` is a collection of samples which have a a specific layout represented by `ChannelLayout` - **Sample**: An extension trait which allows the implementation of converting void* buffers from libcubeb-sys into rust slices of the appropriate type. ### Functions - **init**: Initialize a new cubeb `Context` ### Type Aliases - **DataCallback**: User supplied data callback. - **DeviceChangedCallback**: User supplied callback called when the underlying device changed. - **DeviceId**: An opaque handle used to refer to a particular input or output device across calls. - **Result** - **StateCallback**: User supplied state callback. ``` -------------------------------- ### Example: Enumerate Input and Output Devices in Rust Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.ContextRef_search= Shows how to initialize a cubeb context and then enumerate both input and output audio devices. It handles the `NotSupported` error for device enumeration and prints the number of found devices. ```rust 91fn main() { let ctx = common::init("Cubeb audio test").expect("Failed to create cubeb context"); println!("Enumerating input devices for backend {}", ctx.backend_id()); let devices = match ctx.enumerate_devices(DeviceType::INPUT) { Ok(devices) => devices, Err(cubeb::Error::NotSupported) => { println!("Device enumeration not support for this backend."); return; } Err(e) => { println!("Error enumerating devices: {}", e); return; } }; println!("Found {} input devices", devices.len()); for d in devices.iter() { print_device_info(d); } println!( "Enumerating output devices for backend " ); let devices = match ctx.enumerate_devices(DeviceType::OUTPUT) { Ok(devices) => devices, Err(e) => { println!("Error enumerating devices: {}", e); return; } }; println!("Found {} output devices", devices.len()); for d in devices.iter() { print_device_info(d); } } ``` -------------------------------- ### Cubeb Initialization API Source: https://docs.rs/cubeb/0.33.0/cubeb/index This section describes the process of initializing a new cubeb context, which is the entry point for interacting with the system audio. ```APIDOC ## init ### Description Initializes a new cubeb `Context`. ### Method GET ### Endpoint /init ### Parameters #### Query Parameters - **log_level** (LogLevel) - Optional - Specifies the verbosity level for logging within the cubeb context. ### Response #### Success Response (200) - **context** (ContextRef) - A reference to the newly created cubeb context. #### Response Example { "context": "" } ``` -------------------------------- ### Get Element or Subslice by Index (Rust) Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.DeviceCollectionRef_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E The `get` method allows accessing elements or subslices using various index types. It returns `Some` with the requested item if the index is valid, and `None` otherwise. Examples demonstrate accessing single elements and ranges. ```rust pub fn get(&self, index: I) -> Option<&>::Output> where I: SliceIndex<[T]> // Examples: let v = [10, 40, 30]; assert_eq!(Some(&40), v.get(1)); assert_eq!(Some(&[10, 40][..]), v.get(0..2)); assert_eq!(None, v.get(3)); assert_eq!(None, v.get(0..4)); ``` -------------------------------- ### Example: Initialize Cubeb Context and Backend ID (Rust) Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.ContextRef Demonstrates initializing a cubeb context with a given name and optionally checking if the requested backend matches the one provided by cubeb. It also shows how to retrieve and print the backend ID. ```rust 6pub fn init>>(ctx_name: T) -> Result { let backend = match env::var("CUBEB_BACKEND") { Ok(s) => Some(s), Err(_) => None, }; let ctx_name = CString::new(ctx_name).unwrap(); let ctx = Context::init(Some(ctx_name.as_c_str()), None); if let Ok(ref ctx) = ctx { if let Some(ref backend) = backend { let ctx_backend = ctx.backend_id(); if backend != ctx_backend { let stderr = io::stderr(); let mut handle = stderr.lock(); writeln!( handle, "Requested backend `{}', got `{}'", backend, ctx_backend ) .unwrap(); } } } ctx } ``` -------------------------------- ### Get Slice Length (Rust) Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.DeviceCollectionRef_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E The `len` method returns the number of elements in a slice, which is a fundamental operation for collections. An example is provided demonstrating its usage. ```rust pub fn len(&self) -> usize // Example: let a = [1, 2, 3]; assert_eq!(a.len(), 3); ``` -------------------------------- ### Example Device Enumeration and Output Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.Context Demonstrates how to enumerate input and output audio devices using a cubeb context and print their information. It includes error handling for unsupported device enumeration. ```Rust fn main() { let ctx = common::init("Cubeb audio test").expect("Failed to create cubeb context"); println!("Enumerating input devices for backend {}", ctx.backend_id()); let devices = match ctx.enumerate_devices(DeviceType::INPUT) { Ok(devices) => devices, Err(cubeb::Error::NotSupported) => { println!("Device enumeration not support for this backend."); return; } Err(e) => { println!("Error enumerating devices: {}", e); return; } }; println!("Found {} input devices", devices.len()); for d in devices.iter() { print_device_info(d); } println!( "Enumerating output devices for backend {}", ctx.backend_id() ); let devices = match ctx.enumerate_devices(DeviceType::OUTPUT) { Ok(devices) => devices, Err(e) => { println!("Error enumerating devices: {}", e); return; } }; println!("Found {} output devices", devices.len()); for d in devices.iter() { print_device_info(d); } } ``` -------------------------------- ### Get Metadata of Path with Error Handling in Rust Source: https://docs.rs/cubeb/0.33.0/cubeb/type.Result_search= Shows how to get file metadata using `Path::metadata()` and handle potential errors using `and_then`. This example illustrates a common pattern for interacting with the file system where operations can fail due to non-existent paths or permission issues. ```rust use std::{io::ErrorKind, path::Path}; // Note: on Windows "/" maps to "C:\" let root_modified_time = Path::new("/").metadata().and_then(|md| md.modified()); assert!(root_modified_time.is_ok()); let should_fail = Path::new("/bad/path").metadata().and_then(|md| md.modified()); assert!(should_fail.is_err()); assert_eq!(should_fail.unwrap_err().kind(), ErrorKind::NotFound); ``` -------------------------------- ### Example: Print Audio Device Information in Rust Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.DeviceInfo_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Demonstrates how to use the `DeviceInfo` methods to print detailed information about an audio device. It covers device type, state, supported formats, rates, latency, and identifiers. ```rust fn print_device_info(info: &cubeb::DeviceInfo) { let devtype = if info.device_type().contains(DeviceType::INPUT) { "input" } else if info.device_type().contains(DeviceType::OUTPUT) { "output" } else { "unknown?" }; let devstate = match info.state() { cubeb::DeviceState::Disabled => "disabled", cubeb::DeviceState::Unplugged => "unplugged", cubeb::DeviceState::Enabled => "enabled", }; let devdeffmt = match info.default_format() { DeviceFormat::S16LE => "S16LE", DeviceFormat::S16BE => "S16BE", DeviceFormat::F32LE => "F32LE", DeviceFormat::F32BE => "F32BE", _ => "unknown?", }; let mut devfmts = "".to_string(); if info.format().contains(DeviceFormat::S16LE) { devfmts = format!("{} S16LE", devfmts); } if info.format().contains(DeviceFormat::S16BE) { devfmts = format!("{} S16BE", devfmts); } if info.format().contains(DeviceFormat::F32LE) { devfmts = format!("{} F32LE", devfmts); } if info.format().contains(DeviceFormat::F32BE) { devfmts = format!("{} F32BE", devfmts); } if let Some(device_id) = info.device_id() { let preferred = if info.preferred().is_empty() { "" } else { " (PREFERRED)" }; println!("dev: \"{}\"", device_id, preferred); } if let Some(friendly_name) = info.friendly_name() { println!("\tName: \"{}\"", friendly_name); } if let Some(group_id) = info.group_id() { println!("\tGroup: \"{}\"", group_id); } if let Some(vendor_name) = info.vendor_name() { println!("\tVendor: \"{}\"", vendor_name); } println!("\tType: {}", devtype); println!("\tState: {}", devstate); println!("\tCh: {}", info.max_channels()); println!( "\tFormat: {} (0x{{:x}}) (default: {})", &devfmts[1..], info.format(), devdeffmt ); println!( "\tRate: {} - {} (default: {})", info.min_rate(), info.max_rate(), info.default_rate() ); println!( "\tLatency: lo {} frames, hi {} frames", info.latency_lo(), info.latency_hi() ); } ``` -------------------------------- ### Get First Slice Element (Rust) Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.DeviceCollectionRef_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E The `first` method retrieves a reference to the first element of a slice. It returns `Some(&T)` if the slice is not empty, and `None` if it is empty. Examples show both scenarios. ```rust pub fn first(&self) -> Option<&T> // Examples: let v = [10, 40, 30]; assert_eq!(Some(&10), v.first()); let w: &[i32] = &[]; assert_eq!(None, w.first()); ``` -------------------------------- ### Get Last Slice Element (Rust) Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.DeviceCollectionRef_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E The `last` method returns a reference to the last element of a slice. It returns `Some(&T)` for non-empty slices and `None` for empty slices. Examples cover both outcomes. ```rust pub fn last(&self) -> Option<&T> // Examples: let v = [10, 40, 30]; assert_eq!(Some(&30), v.last()); let w: &[i32] = &[]; assert_eq!(None, w.last()); ``` -------------------------------- ### Initialize Cubeb Context Source: https://docs.rs/cubeb/0.33.0/cubeb/index_search= Initializes a new cubeb context, which is the entry point for interacting with the audio system. ```APIDOC ## POST /cubeb/init ### Description Initializes a new cubeb `Context`. ### Method POST ### Endpoint /cubeb/init ### Parameters #### Query Parameters - **log_level** (LogLevel) - Optional - The verbosity level for logging. #### Request Body This endpoint does not require a request body. ### Response #### Success Response (200) - **context_id** (string) - An opaque handle representing the initialized cubeb context. #### Response Example ```json { "context_id": "cubeb_context_12345" } ``` ``` -------------------------------- ### Rust: Get Cubeb Backend ID Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.Context_search= Retrieves the backend identifier string for an initialized Cubeb context. This is useful for debugging or verifying which audio backend is currently in use. The example demonstrates its usage after context initialization. ```rust 6pub fn init>>(ctx_name: T) -> Result { let backend = match env::var("CUBEB_BACKEND") { Ok(s) => Some(s), Err(_) => None, }; let ctx_name = CString::new(ctx_name).unwrap(); let ctx = Context::init(Some(ctx_name.as_c_str()), None); if let Ok(ref ctx) = ctx { if let Some(ref backend) = backend { let ctx_backend = ctx.backend_id(); if backend != ctx_backend { let stderr = io::stderr(); let mut handle = stderr.lock(); writeln!( handle, "Requested backend `{}', got `{}'", backend, ctx_backend ) .unwrap(); } } } ctx } ``` ```rust 91fn main() { 92 let ctx = common::init("Cubeb audio test").expect("Failed to create cubeb context"); 93 94 println!("Enumerating input devices for backend {}", ctx.backend_id()); 95 96 let devices = match ctx.enumerate_devices(DeviceType::INPUT) { 97 Ok(devices) => devices, 98 Err(cubeb::Error::NotSupported) => { 99 println!("Device enumeration not support for this backend."); 100 return; 101 } 102 Err(e) => { 103 println!("Error enumerating devices: {}", e); 104 return; 105 } 106 }; 107 108 println!("Found {} input devices", devices.len()); 109 for d in devices.iter() { 110 print_device_info(d); 111 } 112 113 println!( 114 "Enumerating output devices for backend " 115 , 116 ctx.backend_id() 117 ); 118 119 let devices = match ctx.enumerate_devices(DeviceType::OUTPUT) { 120 Ok(devices) => devices, 121 Err(e) => { 122 println!("Error enumerating devices: {}", e); 123 return; 124 } 125 }; 126 127 println!("Found {} output devices", devices.len()); 128 for d in devices.iter() { 129 print_device_info(d); 130 } 131} ``` -------------------------------- ### Get Element Index from Reference - Rust (Nightly) Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.DeviceCollectionRef_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Returns the index of an element reference within a slice. This method uses pointer arithmetic and does not compare elements. It returns `None` if the reference is not aligned with the start of an element. This is an experimental API. ```rust #![feature(substr_range)] pub fn element_offset(&self, element: &T) -> Option { // Implementation details omitted for brevity // Example usage: // let nums: &[u32] = &[1, 7, 1, 1]; // let num = &nums[2]; // assert_eq!(nums.element_offset(num), Some(2)); unimplemented!() } ``` -------------------------------- ### ChannelLayout Constructors and Utility Methods Source: https://docs.rs/cubeb/0.33.0/cubeb/struct.ChannelLayout_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Documentation for methods to create and check ChannelLayout instances. ```APIDOC ## ChannelLayout Constructors and Utility Methods ### Description Methods for creating and checking ChannelLayout instances. ### Methods * `empty() -> ChannelLayout`: Returns an empty set of flags. * `all() -> ChannelLayout`: Returns the set containing all flags. * `bits(&self) -> u32`: Returns the raw value of the flags currently stored. * `from_bits(bits: u32) -> Option`: Convert from underlying bit representation, unless that representation contains bits that do not correspond to a flag. * `from_bits_truncate(bits: u32) -> ChannelLayout`: Convert from underlying bit representation, dropping any bits that do not correspond to flags. * `from_bits_unchecked(bits: u32) -> ChannelLayout`: Convert from underlying bit representation, preserving all bits (even those not corresponding to a defined flag). This method is unsafe and requires the caller to ensure bit validity. * `is_empty(&self) -> bool`: Returns `true` if no flags are currently stored. * `is_all(&self) -> bool`: Returns `true` if all flags are currently set. ```