### Start Awedio with CPAL Defaults Source: https://github.com/boppofun/awedio/blob/main/_autodocs/06-backend-cpal.md Use this top-level convenience function to start the Awedio backend with default settings. It returns a Manager and the CpalBackend. ```rust #[cfg(feature = "cpal")] pub fn start() -> Result<(Manager, CpalBackend), CpalBackendError> ``` ```rust let (mut manager, _backend) = awedio::start()?; manager.play(awedio::sounds::open_file("music.mp3")?); ``` -------------------------------- ### start Source: https://github.com/boppofun/awedio/blob/main/_autodocs/06-backend-cpal.md A top-level convenience function to start the CPAL backend with default settings. It returns a `Manager` and the `CpalBackend` instance. ```APIDOC ## start (root level) ### Description Top-level convenience function to start with defaults. ### Method Rust Function ### Signature ```rust #[cfg(feature = "cpal")] pub fn start() -> Result<(Manager, CpalBackend), CpalBackendError> ``` ### Returns - `Result<(Manager, CpalBackend), CpalBackendError>`: A result containing a tuple of `Manager` and `CpalBackend` on success, or a `CpalBackendError` on failure. ### Example ```rust let (mut manager, _backend) = awedio::start()?; manager.play(awedio::sounds::open_file("music.mp3")?); ``` ``` -------------------------------- ### start Source: https://github.com/boppofun/awedio/blob/main/_autodocs/02-manager.md Convenience function to start audio playback with the default backend, device, and configuration using cpal. Returns a Manager and the CpalBackend or an error. ```APIDOC ## start (Feature-gated) ### Description Convenience function to start audio playback with the default backend, device, and configuration using cpal. Returns a Manager and the CpalBackend or an error. ### Method Rust function call ### Signature `#[cfg(feature = "cpal")] pub fn start() -> Result<(Manager, CpalBackend), CpalBackendError>` ### Parameters #### Path Parameters - (none) ### Returns `Result<(Manager, CpalBackend), CpalBackendError>` — Manager and backend or error ### Errors - `CpalBackendError::NoDevice` — No audio device found ### Remarks Errors are printed to stderr automatically. For more control over error handling, create [CpalBackend](##cpalbackend) explicitly. ### Example ```rust let (mut manager, backend) = awedio::start()?; manager.play(awedio::sounds::open_file("test.mp3")?); ``` ``` -------------------------------- ### Decorator Pattern Example Chain Source: https://github.com/boppofun/awedio/blob/main/_autodocs/10-architecture.md Illustrates the chaining of sound wrappers using the decorator pattern, starting from an original sound and applying volume adjustment, pausing, and control functionalities. ```plaintext original_sound ↓ .with_adjustable_volume_of(0.5) ↓ .pausable() ↓ .controllable() ``` -------------------------------- ### Start Sound in Paused State Source: https://github.com/boppofun/awedio/blob/main/_autodocs/09-patterns.md Shows how to initialize a controllable sound to start in a paused state. Use the `.paused()` method during sound creation. ```rust let sound = SineWave::new(440.0) .paused() // Start paused .controllable(); ``` -------------------------------- ### start Source: https://github.com/boppofun/awedio/blob/main/_autodocs/06-backend-cpal.md Starts audio playback and returns a Manager for controlling sounds. It accepts a closure that will be called if any stream errors occur. ```APIDOC ## start ### Description Starts audio playback and returns a Manager for controlling sounds. It accepts a closure that will be called if any stream errors occur. ### Method Rust Function ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust let mut backend = CpalBackend::with_defaults()?; let manager = backend.start(|err| { eprintln!("Audio stream error: {}", err); })?; manager.play(Box::new(SineWave::new(440.0))); ``` ### Response #### Success Response - **Manager** (`Manager`) - A manager object to control sounds. #### Response Example ```rust // Returns a Result ``` ### Errors: - `CpalBackendError::BuildStream` — Failed to build audio stream - `CpalBackendError::PlayStream` — Failed to start stream playback ### Remarks: Only one stream can be active per CpalBackend at a time. ``` -------------------------------- ### Example: Controlling a Sound Remotely Source: https://github.com/boppofun/awedio/blob/main/_autodocs/04-wrappers.md Demonstrates how to create a controllable sound and use its controller to send commands like setting volume or pausing playback from another thread. ```rust let (sound, mut controller) = SineWave::new(440.0).controllable(); manager.play(Box::new(sound)); // Send commands from another thread controller.set_volume(0.5); controller.set_paused(true); ``` -------------------------------- ### Play an audio file Source: https://github.com/boppofun/awedio/blob/main/_autodocs/00-index.md Starts the Awedio manager and plays an audio file from disk. Ensure the audio file exists at the specified path. ```rust let (mut manager, _backend) = awedio::start()?; let sound = awedio::sounds::open_file("music.mp3")?; manager.play(sound); ``` -------------------------------- ### Control Command Pipeline Example Source: https://github.com/boppofun/awedio/blob/main/_autodocs/10-architecture.md Illustrates the flow of commands from application code to the audio thread for operations like setting volume. Commands are enqueued as closures and executed before the next audio batch, ensuring thread safety. ```text Application code: controller.set_volume(0.5) │ ↓ Command enqueued: Box::new(|sound| sound.set_volume(0.5)) │ ↓ Sent through mpsc::Sender │ ↓ Audio thread, on_start_of_batch(): command_receiver.try_recv() → execute closure │ ↓ Closure executes: sound.set_volume(0.5) │ ↓ Next next_sample() calls use new volume ``` -------------------------------- ### Example: Adding a Sound to a Controller Source: https://github.com/boppofun/awedio/blob/main/_autodocs/04-wrappers.md Shows how to add another sound, like a `SineWave`, to a controller that manages a collection of sounds. This is typically used with container-like sound types. ```rust // For SoundMixer or SoundList controller.add(Box::new(SineWave::new(880.0))); ``` -------------------------------- ### Start Audio Playback Source: https://github.com/boppofun/awedio/blob/main/_autodocs/06-backend-cpal.md Starts audio playback and returns a Manager for controlling sounds. The error callback is invoked when stream errors occur. Only one stream can be active per CpalBackend at a time. ```rust pub fn start(&mut self, error_callback: E) -> Result where E: FnMut(CpalError) + Send + 'static, ``` ```rust let mut backend = CpalBackend::with_defaults()?; let manager = backend.start(|err| { eprintln!("Audio stream error: {}", err); })?; manager.play(Box::new(SineWave::new(440.0))); ``` -------------------------------- ### Play a Single Sound File Source: https://github.com/boppofun/awedio/blob/main/README.md Demonstrates how to play a single audio file using the Awedio library. Requires starting the manager and backend first. ```rust let (mut manager, backend) = awedio::start()?; manager.play(awedio::sounds::open_file("test_files/stereo-test.mp3")?); # Ok::<(), Box>(()) ``` -------------------------------- ### Sync Example: Play sound with CompletionNotifier Source: https://github.com/boppofun/awedio/blob/main/_autodocs/04-wrappers.md Demonstrates playing a sound using CompletionNotifier and waiting for its completion using the receiver. The `rx.recv()` call will block until the sound finishes. ```rust let (sound, rx) = SineWave::new(440.0).with_completion_notifier(); manager.play(Box::new(sound)); rx.recv(); // Blocks until finished println!("Sound completed!"); ``` -------------------------------- ### Implement Custom Sound Source: https://github.com/boppofun/awedio/blob/main/_autodocs/09-patterns.md Implement the `Sound` trait to create custom audio sources. This example plays a constant sample for a specified duration. ```rust use awedio::{Sound, NextSample}; struct CustomSound { count: u32, max: u32, } impl Sound for CustomSound { fn channel_count(&self) -> u16 { 1 } fn sample_rate(&self) -> u32 { 48000 } fn next_sample(&mut self) -> Result { if self.count >= self.max { Ok(NextSample::Finished) } else { self.count += 1; Ok(NextSample::Sample(1000)) // Constant sample } } fn on_start_of_batch(&mut self) {} } let sound = CustomSound { count: 0, max: 48000 }; manager.play(Box::new(sound)); ``` -------------------------------- ### Catch Audio Stream Errors Source: https://github.com/boppofun/awedio/blob/main/_autodocs/09-patterns.md Demonstrates how to initialize the audio backend and start a playback manager, providing a closure to handle and log any audio stream errors. ```rust let backend = CpalBackend::with_defaults()?; let manager = backend.start(|error| { eprintln!("Audio stream error: {}", error); // Sound continues playing with other sounds })?; ``` -------------------------------- ### Async Example: Play sound with AsyncCompletionNotifier Source: https://github.com/boppofun/awedio/blob/main/_autodocs/04-wrappers.md Shows how to play a sound with AsyncCompletionNotifier and asynchronously wait for its completion using `rx.await`. This is suitable for non-blocking operations in an async context. ```rust let (sound, rx) = SineWave::new(440.0).with_async_completion_notifier(); manager.play(Box::new(sound)); rx.await; // Async wait println!("Sound completed!"); ``` -------------------------------- ### Example: Sending a Custom Command Source: https://github.com/boppofun/awedio/blob/main/_autodocs/04-wrappers.md Illustrates how to use `send_command` to apply a custom mutation to the controlled sound. The closure provided receives a mutable reference to the sound. ```rust controller.send_command(Box::new(|sound| { // Custom mutation })); ``` -------------------------------- ### Start Audio Playback with Default Backend Source: https://github.com/boppofun/awedio/blob/main/_autodocs/02-manager.md A convenience function to initialize audio playback using the default system backend, device, and configuration via cpal. It returns a Manager and the CpalBackend, or an error if no audio device is found. ```rust #[cfg(feature = "cpal")] pub fn start() -> Result<(Manager, CpalBackend), CpalBackendError> ``` ```rust let (mut manager, backend) = awedio::start()?; manager.play(awedio::sounds::open_file("test.mp3")?); ``` -------------------------------- ### Handle Backend Initialization Errors Source: https://github.com/boppofun/awedio/blob/main/_autodocs/07-errors.md Manages errors during CPAL backend initialization and stream starting. This includes cases where no audio device is found or stream creation/playback fails. ```rust use awedio::backends::{CpalBackend, CpalBackendError}; match CpalBackend::with_defaults() { Some(mut backend) => { match backend.start(|err| eprintln!("Stream error: {}", err)) { Ok(manager) => { /* use manager */ }, Err(CpalBackendError::NoDevice) => eprintln!("No audio device"), Err(CpalBackendError::BuildStream(e)) => eprintln!("Build failed: {}", e), Err(CpalBackendError::PlayStream(e)) => eprintln!("Play failed: {}", e), } } None => eprintln!("No audio device found"), } ``` -------------------------------- ### controllable Source: https://github.com/boppofun/awedio/blob/main/_autodocs/01-sound-trait.md Wraps the sound to allow control via a Controller after playback starts. This enables dynamic adjustments like volume or playback position. ```APIDOC ## controllable ### Description Wraps the sound to allow control via a [Controller](##controller) after playback starts. ### Method `controllable` ### Parameters (none) ### Returns Tuple of `(Controllable, Controller)` ### Example ```rust let (sound, mut controller) = SineWave::new(440.0).controllable(); manager.play(Box::new(sound)); // Later, can control via controller controller.set_volume(0.5); ``` ``` -------------------------------- ### Configure Cargo.toml for minimal binary size Source: https://github.com/boppofun/awedio/blob/main/_autodocs/05-file-decoders.md To reduce the size of your binary, disable default features and explicitly enable only the necessary ones in your `Cargo.toml` file. This example enables `cpal` and `symphonia-flac` features. ```toml [dependencies] awedio = { version = "0.8", default-features = false, features = ["cpal", "symphonia-flac"] } ``` -------------------------------- ### CpalBackend Structure Definition Source: https://github.com/boppofun/awedio/blob/main/_autodocs/08-types.md Represents an audio backend using the cpal library. Supports various construction methods and starting playback. ```rust pub struct CpalBackend { // Private fields } ``` -------------------------------- ### Wrap Sound for Adjustable Volume with Initial Value Source: https://github.com/boppofun/awedio/blob/main/_autodocs/01-sound-trait.md Allows volume adjustment with a specified initial multiplier. Use when the sound should start at a volume other than the default. ```rust pub fn with_adjustable_volume_of(self, volume_adjustment: f32) -> AdjustableVolume where Self: Sized, ``` ```rust let sound = SineWave::new(440.0).with_adjustable_volume_of(0.5); ``` -------------------------------- ### Adjust Volume Dynamically Source: https://github.com/boppofun/awedio/blob/main/_autodocs/09-patterns.md Starts playback with adjustable volume and modifies it during runtime. Allows for fading effects or dynamic volume changes. ```rust let (sound, mut controller) = SineWave::new(440.0) .with_adjustable_volume_of(1.0) .controllable(); manager.play(Box::new(sound)); // Later, from another thread or after delay std::thread::sleep(std::time::Duration::from_millis(500)); controller.set_volume(0.5); // Half volume std::thread::sleep(std::time::Duration::from_millis(500)); controller.set_volume(0.0); // Silence ``` -------------------------------- ### Callback for Start of Batch Processing Source: https://github.com/boppofun/awedio/blob/main/_autodocs/01-sound-trait.md A callback function invoked when the audio backend requests a new batch of samples. Use this for periodic updates that do not need to occur on every single sample. ```rust pub fn on_start_of_batch(&mut self) ``` ```rust impl Sound for CustomSound { fn on_start_of_batch(&mut self) { // Update internal state once per batch } } ``` -------------------------------- ### Create SoundsFromFn with a generator function Source: https://github.com/boppofun/awedio/blob/main/_autodocs/03-sound-types.md Initializes a SoundsFromFn sound generator using a closure that produces sounds. The generator is called repeatedly to get the next sound. Playback ends when the generator returns None. ```rust let generator = || Some(SineWave::new(440.0)); let sound = SoundsFromFn::new(Box::new(generator)); ``` ```rust // Load audio files one at a time let generator = || open_file("song.mp3").ok(); let sound = SoundsFromFn::new(Box::new(generator)); ``` -------------------------------- ### Wrap Sound for Controllable Playback Source: https://github.com/boppofun/awedio/blob/main/_autodocs/01-sound-trait.md Wraps a sound to allow control via a Controller after playback starts. Use when you need to dynamically adjust playback parameters like volume or pause/resume. ```rust pub fn controllable(self) -> (Controllable, Controller) where Self: Sized, ``` ```rust let (sound, mut controller) = SineWave::new(440.0).controllable(); manager.play(Box::new(sound)); // Later, can control via controller controller.set_volume(0.5); ``` -------------------------------- ### Notify on Sound Completion (Async) Source: https://github.com/boppofun/awedio/blob/main/_autodocs/01-sound-trait.md Use `with_async_completion_notifier` to get a wrapper that notifies an asynchronous `tokio::sync::oneshot::Receiver` when the sound finishes. Requires the `async` feature. ```rust #[cfg(feature = "async")] pub fn with_async_completion_notifier(self) -> (AsyncCompletionNotifier, tokio::sync::oneshot::Receiver<()>) where Self: Sized, ``` ```rust let (sound, rx) = SineWave::new(440.0).with_async_completion_notifier(); manager.play(Box::new(sound)); rx.await; // Async wait for completion ``` -------------------------------- ### Play Sound with Adjustable Volume and Pause Control Source: https://github.com/boppofun/awedio/blob/main/README.md Shows how to play a sound with adjustable volume and pausing capabilities. The volume can be changed dynamically after playback starts, and the sound can be paused and resumed. ```rust use awedio::Sound; let (mut manager, backend) = awedio::start()?; let (sound, mut controller) = awedio::sounds::SineWave::new(400.0) .with_adjustable_volume_of(0.25) .pausable() .controllable(); manager.play(Box::new(sound)); std::thread::sleep(std::time::Duration::from_millis(100)); controller.set_volume(0.5); std::thread::sleep(std::time::Duration::from_millis(100)); controller.set_paused(true); # Ok::<(), Box>(()) ``` -------------------------------- ### BackendSource Trait Source: https://github.com/boppofun/awedio/blob/main/_autodocs/08-types.md The BackendSource trait defines the interface for providing audio samples to a backend. Implementors must provide a method to get the next sample and a callback for the start of a batch. ```APIDOC ## BackendSource Trait for providing samples to a backend. ### Methods - `next_sample(&mut self) -> Result` - Description: Get the next audio sample from the source. - Returns: A `Result` containing the `NextSample` or an `Error`. - `on_start_of_batch(&mut self)` - Description: Callback invoked at the start of a batch of samples. ``` -------------------------------- ### Create CpalBackend with Defaults Source: https://github.com/boppofun/awedio/blob/main/_autodocs/06-backend-cpal.md Creates a backend using the system's default output device and its optimal configuration. Returns None if no audio device is found. ```rust match CpalBackend::with_defaults() { Some(mut backend) => { let manager = backend.start(|err| eprintln!("Audio error: {}", err))?; } None => eprintln!("No audio device found"), } ``` -------------------------------- ### Create CpalBackend with Default Host/Device and Custom Config Source: https://github.com/boppofun/awedio/blob/main/_autodocs/06-backend-cpal.md Creates a backend with the default host and device but allows for custom configuration of channels, sample rate, and buffer size. Returns None if no device is found or the configuration is unsupported. ```rust use awedio::backends::CpalBufferSize; let backend = CpalBackend::with_default_host_and_device( 2, // Stereo 48000, // 48kHz CpalBufferSize::Default, )?; ``` -------------------------------- ### Audio System Startup Source: https://github.com/boppofun/awedio/blob/main/_autodocs/_MANIFEST.txt Initializes the audio system. This function must be called before any other audio operations. ```APIDOC ## start() ### Description Initializes the audio system. This function must be called before any other audio operations. ### Method `start()` ### Endpoint `awedio::start()` ``` -------------------------------- ### Create Pausable Sound Source: https://github.com/boppofun/awedio/blob/main/_autodocs/04-wrappers.md Wraps a sound to make it pausable. Use `pausable()` to start unpaused or `paused()` to start paused. ```rust pub fn pausable(self) -> Pausable where Self: Sized, pub fn paused(self) -> Pausable where Self: Sized, ``` ```rust let sound = SineWave::new(440.0).pausable(); let paused_sound = SineWave::new(440.0).paused(); ``` -------------------------------- ### CpalBackend::with_defaults Source: https://github.com/boppofun/awedio/blob/main/_autodocs/06-backend-cpal.md Creates a CpalBackend instance using the system's default audio output device and its optimal configuration. It returns `None` if no suitable audio device is found. ```APIDOC ## CpalBackend::with_defaults ### Description Creates a backend with default device and configuration. ### Method `pub fn with_defaults() -> Option` ### Parameters (none) ### Returns `Option` — Backend or None if no device found ### Remarks Uses the system's default output device and its optimal configuration. ### Example ```rust match CpalBackend::with_defaults() { Some(mut backend) => { let manager = backend.start(|err| eprintln!("Audio error: {}", err))?; } None => eprintln!("No audio device found"), } ``` ``` -------------------------------- ### CpalBackend::with_default_host_and_device Source: https://github.com/boppofun/awedio/blob/main/_autodocs/06-backend-cpal.md Creates a CpalBackend instance using the default audio host and device, but allows for custom configuration of channel count, sample rate, and buffer size. Returns `None` if no device is found or the configuration is unsupported. ```APIDOC ## CpalBackend::with_default_host_and_device ### Description Creates a backend with the default host and device but custom configuration. ### Method `pub fn with_default_host_and_device( channel_count: u16, sample_rate: u32, buffer_size: CpalBufferSize, ) -> Option` ### Parameters #### Parameters - **channel_count** (`u16`) - Yes - Number of output channels (e.g., 1 or 2) - **sample_rate** (`u32`) - Yes - Sample rate in Hz (e.g., 48000) - **buffer_size** (`CpalBufferSize`) - Yes - Buffer size mode ### Returns `Option` — Backend or None if no device found or config unsupported ### Example ```rust use awedio::backends::CpalBufferSize; let backend = CpalBackend::with_default_host_and_device( 2, // Stereo 48000, // 48kHz CpalBufferSize::Default, )?; ``` ``` -------------------------------- ### Pausable & SetPaused Source: https://github.com/boppofun/awedio/blob/main/_autodocs/04-wrappers.md Makes a sound pausable. The `pausable()` function creates a pausable sound that starts unpaused, while `paused()` creates one that starts paused. ```APIDOC ## Pausable & SetPaused Makes a sound pausable. ### Creation ```rust pub fn pausable(self) -> Pausable where Self: Sized, pub fn paused(self) -> Pausable where Self: Sized, ``` **Returns:** `Pausable` — Wrapped sound **Remarks:** - `pausable()` — Starts unpaused - `paused()` — Starts paused ### Methods #### set_paused ```rust pub fn set_paused(&mut self, paused: bool) ``` Pauses or resumes the sound. | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | paused | `bool` | Yes | — | True to pause, false to resume | **Returns:** None #### paused ```rust pub fn paused(&self) -> bool ``` Returns whether the sound is currently paused. **Returns:** `bool` ``` -------------------------------- ### Create CpalBackend with Full Control Source: https://github.com/boppofun/awedio/blob/main/_autodocs/06-backend-cpal.md Creates a backend instance with complete control over all audio parameters including channels, sample rate, buffer size, device, and sample format. ```rust pub fn new( channel_count: u16, sample_rate: u32, buffer_size: CpalBufferSize, device: cpal::Device, sample_format: cpal::SampleFormat, ) -> CpalBackend ``` -------------------------------- ### Get SoundList Length Source: https://github.com/boppofun/awedio/blob/main/_autodocs/03-sound-types.md Returns the total number of sounds currently in the SoundList. ```rust pub fn len(&self) -> usize ``` -------------------------------- ### with_adjustable_volume_of Source: https://github.com/boppofun/awedio/blob/main/_autodocs/01-sound-trait.md Allows volume adjustment with a specified initial multiplier. This sets the starting volume level for the sound. ```APIDOC ## with_adjustable_volume_of ### Description Allows volume adjustment with initial multiplier. ### Method `with_adjustable_volume_of` ### Parameters #### Path Parameters - **volume_adjustment** (`f32`) - Yes - Initial volume multiplier (1.0 = normal) ### Returns `AdjustableVolume` — Wrapped sound with volume control ### Example ```rust let sound = SineWave::new(440.0).with_adjustable_volume_of(0.5); ``` ``` -------------------------------- ### paused Source: https://github.com/boppofun/awedio/blob/main/_autodocs/01-sound-trait.md Makes the sound pausable and starts it in a paused state. Useful for pre-loading sounds without immediate playback. ```APIDOC ## paused ### Description Makes the sound pausable and starts in paused state. ### Method `paused` ### Parameters (none) ### Returns `Pausable` — Wrapped sound, initially paused ### Example ```rust let sound = SineWave::new(440.0).paused(); ``` ``` -------------------------------- ### Handle UnsupportedMetadataChangeError Source: https://github.com/boppofun/awedio/blob/main/_autodocs/07-errors.md Example of matching and handling the UnsupportedMetadataChangeError, specifically when it's returned as an IoError with Kind::Other from MemorySound::from_sound. ```rust match MemorySound::from_sound(sound) { Err(Error::IoError(e)) if e.kind() == std::io::ErrorKind::Other => { eprintln!("Metadata changed during sound loading"); } Err(e) => eprintln!("Error: {}", e), Ok(mem_sound) => { /* use mem_sound */ } } ``` -------------------------------- ### Enumerate and Select CPAL Audio Devices Source: https://github.com/boppofun/awedio/blob/main/_autodocs/06-backend-cpal.md This snippet shows how to list available audio output devices using the CPAL library and then select a specific device to initialize the CpalBackend. ```rust use cpal::traits::{HostTrait, DeviceTrait}; let host = cpal::default_host(); for device in host.output_devices()? { println!("Device: {}", device.name()?); } // Select a specific device let device = host.output_devices()?.next().unwrap(); let backend = CpalBackend::new(2, 48000, CpalBufferSize::Default, device, cpal::SampleFormat::I16); ``` -------------------------------- ### Controllable & Controller Source: https://github.com/boppofun/awedio/blob/main/_autodocs/08-types.md Provides remote control capabilities for a sound after playback has started. The Controller allows sending commands to manipulate the sound. ```APIDOC ## Controllable & Controller ### Description Allows remote control of a sound after playback starts. ### Creation Via `Sound::controllable()` ### Controller Methods - `send_command(Box)` - `add(Box)` — When `S: AddSound` - `clear()` — When `S: ClearSounds` - `set_paused(bool)` — When `S: SetPaused` - `set_stopped()` — When `S: SetStopped` - `set_volume(f32)` — When `S: SetVolume` - `set_speed(f32)` — When `S: SetSpeed` ### Traits `Clone` (Controller) ``` -------------------------------- ### Adjust Speed Dynamically Source: https://github.com/boppofun/awedio/blob/main/_autodocs/09-patterns.md Allows for dynamic adjustment of playback speed after a sound has started. Useful for tempo changes or special effects. ```rust let (sound, mut controller) = open_file("song.mp3")? .with_adjustable_speed() .controllable(); manager.play(Box::new(sound)); // Increase speed controller.set_speed(1.5); // Return to normal controller.set_speed(1.0); // Slow down controller.set_speed(0.8); ``` -------------------------------- ### File Decoder Architecture Overview Source: https://github.com/boppofun/awedio/blob/main/_autodocs/10-architecture.md Illustrates the process of opening a file and creating an appropriate decoder based on its extension. Decoders utilize buffered I/O for efficiency. ```text open_file("audio.mp3") │ ├─ Read file extension │ ├─ Match extension or use symphonia default │ ├─ Create appropriate decoder: │ ├─ SymphoniaDecoder (generic, multiplex many formats) │ ├─ QoaDecoder (if feature enabled) │ └─ (others) │ └─ Return Box ``` -------------------------------- ### Wrap Sound for Paused Playback Source: https://github.com/boppofun/awedio/blob/main/_autodocs/01-sound-trait.md Makes a sound pausable and starts it in a paused state. Use when the sound should initially be paused and then explicitly unpaused. ```rust pub fn paused(self) -> Pausable where Self: Sized, ``` ```rust let sound = SineWave::new(440.0).paused(); ``` -------------------------------- ### Create New Manager and Renderer Source: https://github.com/boppofun/awedio/blob/main/_autodocs/02-manager.md Initializes a new Manager and its associated Renderer. This is the fundamental step to begin audio management. ```rust pub fn new() -> (Self, Renderer) ``` ```rust let (manager, renderer) = Manager::new(); ``` -------------------------------- ### Wrap Sound for Pausable Playback Source: https://github.com/boppofun/awedio/blob/main/_autodocs/01-sound-trait.md Makes a sound pausable, starting in an unpaused state. Use when the sound should be able to be paused and resumed during playback. ```rust pub fn pausable(self) -> Pausable where Self: Sized, ``` ```rust let sound = SineWave::new(440.0).pausable(); ``` -------------------------------- ### Basic Sound Playback and Control Source: https://github.com/boppofun/awedio/blob/main/_autodocs/00-index.md Initializes the audio manager, creates a controllable sine wave, plays it, and demonstrates modifying its volume and pause state. ```rust use awedio::{Sound, sounds::SineWave}; use std::time::Duration; fn main() -> Result<(), Box> { // Start audio system let (mut manager, _backend) = awedio::start()?; // Create a controlled sine wave let (sound, mut controller) = SineWave::new(440.0) .with_adjustable_volume_of(0.5) .pausable() .controllable(); // Play it manager.play(Box::new(sound)); // Modify it while playing std::thread::sleep(Duration::from_millis(500)); controller.set_volume(0.25); std::thread::sleep(Duration::from_millis(500)); controller.set_paused(true); std::thread::sleep(Duration::from_millis(500)); controller.set_paused(false); std::thread::sleep(Duration::from_millis(500)); Ok(()) } ``` -------------------------------- ### Get Next Audio Frame Source: https://github.com/boppofun/awedio/blob/main/_autodocs/01-sound-trait.md Retrieves the next sample frame for all channels in a single call. Use this when you need to process a complete frame at once. ```rust pub fn next_frame(&mut self) -> Result, Result> ``` ```rust let frame = sound.next_frame()?; println!("Frame has {} samples", frame.len()); ``` -------------------------------- ### Get Channel Count of a Sound Source: https://github.com/boppofun/awedio/blob/main/_autodocs/01-sound-trait.md Retrieves the number of audio channels for a given sound. This is useful for understanding the stereo or mono nature of the audio. ```rust pub fn channel_count(&self) -> u16 ``` ```rust let sound = SineWave::new(440.0); println!("Channels: {}", sound.channel_count()); // Output: Channels: 1 ``` -------------------------------- ### CpalBackend::new Source: https://github.com/boppofun/awedio/blob/main/_autodocs/06-backend-cpal.md Creates a CpalBackend instance with full control over all audio output parameters, including channel count, sample rate, buffer size, device, and sample format. This constructor provides the most flexibility. ```APIDOC ## CpalBackend::new ### Description Creates a backend with full control over all parameters. ### Method `pub fn new( channel_count: u16, sample_rate: u32, buffer_size: CpalBufferSize, device: cpal::Device, sample_format: cpal::SampleFormat, ) -> CpalBackend` ### Parameters #### Parameters - **channel_count** (`u16`) - Yes - Number of output channels - **sample_rate** (`u32`) - Yes - Sample rate in Hz - **buffer_size** (`CpalBufferSize`) - Yes - Buffer size mode - **device** (`cpal::Device`) - Yes - Output device - **sample_format** (`cpal::SampleFormat`) - Yes - Sample format (I16 or F32) ### Returns `CpalBackend` — Configured backend ``` -------------------------------- ### Manager::new Source: https://github.com/boppofun/awedio/blob/main/_autodocs/02-manager.md Creates a new Manager and its associated Renderer. The Manager handles sound playback, and the Renderer prepares samples for the audio backend. ```APIDOC ## Manager::new ### Description Creates a new Manager and its associated Renderer. The Manager handles sound playback, and the Renderer prepares samples for the audio backend. ### Method Rust function call ### Signature `pub fn new() -> (Self, Renderer)` ### Returns Tuple of `(Manager, Renderer)` — Manager for playing sounds and Renderer for backend processing ### Example ```rust let (manager, renderer) = Manager::new(); ``` ``` -------------------------------- ### Notify on Sound Completion (Sync) Source: https://github.com/boppofun/awedio/blob/main/_autodocs/01-sound-trait.md Use `with_completion_notifier` to get a wrapper that notifies a synchronous `mpsc::Receiver` when the sound finishes. This is useful for blocking operations. ```rust pub fn with_completion_notifier(self) -> (CompletionNotifier, std::sync::mpsc::Receiver<()>) where Self: Sized, ``` ```rust let (sound, rx) = SineWave::new(440.0).with_completion_notifier(); manager.play(Box::new(sound)); rx.recv(); // Blocks until sound finishes ``` -------------------------------- ### Get Sample Rate of a Sound Source: https://github.com/boppofun/awedio/blob/main/_autodocs/01-sound-trait.md Retrieves the sample rate (samples per second) for each channel of the sound. This determines the fidelity and playback speed of the audio. ```rust pub fn sample_rate(&self) -> u32 ``` ```rust let sound = SineWave::new(440.0); println!("Sample rate: {}", sound.sample_rate()); // Output: Sample rate: 48000 ``` -------------------------------- ### on_start_of_batch Source: https://github.com/boppofun/awedio/blob/main/_autodocs/01-sound-trait.md A callback method invoked at the beginning of each batch of audio samples requested by the backend. Useful for periodic updates. ```APIDOC ## on_start_of_batch ### Description Called when a new batch of audio samples is requested by the backend. Use this for periodic updates that should not happen per-sample. ### Method `on_start_of_batch(&mut self)` ### Parameters None ### Returns None ### Example ```rust impl Sound for CustomSound { fn on_start_of_batch(&mut self) { // Update internal state once per batch } } ``` ``` -------------------------------- ### Handle File Not Found Error Gracefully Source: https://github.com/boppofun/awedio/blob/main/_autodocs/09-patterns.md Illustrates how to use a `match` statement to specifically catch `ErrorKind::NotFound` when opening a file and play a fallback sound. ```rust use awedio::sounds::open_file; use awedio::Error; use std::io::ErrorKind; match open_file("missing.mp3") { Ok(sound) => manager.play(sound), Err(Error::IoError(e)) if e.kind() == ErrorKind::NotFound => { println!("File not found, playing fallback sound"); manager.play(Box::new(SineWave::new(440.0))); } Err(e) => eprintln!("Error: {}", e), } ``` -------------------------------- ### Sound Trait Methods Source: https://github.com/boppofun/awedio/blob/main/_autodocs/_MANIFEST.txt Defines the core interface for all sound types, including methods for getting channel count, sample rate, and the next sample. ```APIDOC ## Sound Trait ### Description Defines the core interface for all sound types, including methods for getting channel count, sample rate, and the next sample. ### Methods - `channel_count()`: Returns the number of audio channels. - `sample_rate()`: Returns the sample rate of the audio. - `next_sample()`: Returns the next audio sample. - `on_start_of_batch()`: Callback for the start of a sample batch. ``` -------------------------------- ### Create New SoundList Source: https://github.com/boppofun/awedio/blob/main/_autodocs/03-sound-types.md Creates a new, empty SoundList. Use this to begin building a sequence of sounds. ```rust pub fn new() -> Self ``` ```rust let list = SoundList::new(); ``` -------------------------------- ### Create a new SoundMixer Source: https://github.com/boppofun/awedio/blob/main/_autodocs/03-sound-types.md Initializes a SoundMixer with a specified output channel count and sample rate. All sounds added to the mixer will be converted to this format. ```rust let mixer = SoundMixer::new(2, 48000); // Stereo, 48kHz output ``` -------------------------------- ### controllable Source: https://github.com/boppofun/awedio/blob/main/_autodocs/04-wrappers.md Creates a wrappable sound with a remote controller, allowing for post-playback control. ```APIDOC ## controllable ### Description Creates a wrappable sound with a remote controller. ### Method `controllable(self) -> (Controllable, Controller)` ### Parameters None ### Returns Tuple of `(Controllable, Controller)` ### Example ```rust let (sound, mut controller) = SineWave::new(440.0).controllable(); manager.play(Box::new(sound)); // Send commands from another thread controller.set_volume(0.5); controller.set_paused(true); ``` ``` -------------------------------- ### SoundList::new Source: https://github.com/boppofun/awedio/blob/main/_autodocs/03-sound-types.md Creates a new, empty SoundList. This is the entry point for creating a new sound sequence. ```APIDOC ## SoundList::new ### Description Creates a new empty sound list. ### Method `new()` ### Returns `SoundList` — Empty sound list ### Example ```rust let list = SoundList::new(); ``` ``` -------------------------------- ### Share Samples Across MemorySound Instances Source: https://github.com/boppofun/awedio/blob/main/_autodocs/09-patterns.md Demonstrates sharing raw audio samples using `Arc` to create multiple `MemorySound` instances with minimal overhead. This is efficient when multiple sounds use the exact same audio data. ```rust use std::sync::Arc; use awedio::sounds::MemorySound; // Create from raw samples let samples = Arc::new(vec![/* samples */]); let sound1 = MemorySound::from_samples(samples.clone(), 1, 48000); let sound2 = MemorySound::from_samples(samples.clone(), 1, 48000); // Both reference the same Arc, minimal overhead ``` -------------------------------- ### Using Async Completion Notifier Source: https://github.com/boppofun/awedio/blob/main/_autodocs/09-patterns.md Utilize the async features of awedio to be notified when a sound has completed playing. Requires the 'async' feature to be enabled. ```rust #[tokio::main] async fn main() -> Result<()> { let (sound, rx) = SineWave::new(440.0) .with_async_completion_notifier(); manager.play(Box::new(sound)); tokio::select! { _ = rx => println!("Sound completed"), _ = tokio::time::sleep(Duration::from_secs(5)) => println!("Timeout"), } Ok(()) } ``` -------------------------------- ### Open File with Custom Buffer Capacity Source: https://github.com/boppofun/awedio/blob/main/_autodocs/05-file-decoders.md Creates a Sound object by reading from a file with a specified internal buffer capacity. Use larger buffers for faster I/O on slow storage, and smaller buffers for lower memory overhead. ```rust pub fn open_file_with_buffer_capacity>( path: P, buffer_capacity: usize, ) -> Result, crate::Error> // Use larger buffer for large files let sound = open_file_with_buffer_capacity("large_file.flac", 65536)?; ``` -------------------------------- ### Generate Sounds On-the-Fly Source: https://github.com/boppofun/awedio/blob/main/_autodocs/09-patterns.md Use `SoundsFromFn` to create sounds dynamically by providing a generator function. The generator can produce new sounds indefinitely. ```rust use awedio::sounds::SoundsFromFn; // Generate new sounds indefinitely let generator = || Some(SineWave::new(440.0)); let sound = SoundsFromFn::new(Box::new(generator)); manager.play(Box::new(sound)); ``` -------------------------------- ### Define Custom Backend Source Source: https://github.com/boppofun/awedio/blob/main/_autodocs/10-architecture.md Implement the `BackendSource` trait to create custom audio backends. This trait requires implementing `next_sample` to provide audio data and `on_start_of_batch` for batch processing. ```rust pub trait BackendSource { fn next_sample(&mut self) -> Result; fn on_start_of_batch(&mut self); } ``` -------------------------------- ### Enable QOA Decoding via qoaudio Crate Source: https://github.com/boppofun/awedio/blob/main/_autodocs/05-file-decoders.md This configuration enables QOA (Quite OK Audio) decoding using the qoaudio crate. QOA is a modern lossy format optimized for low resource usage. ```rust #[cfg(feature = "qoa")] // Enabled via qoaudio crate ``` -------------------------------- ### Create MemorySound from Samples Source: https://github.com/boppofun/awedio/blob/main/_autodocs/03-sound-types.md Use MemorySound::from_samples to create a sound directly from raw interleaved sample data. Provide the sample data, channel count, and sample rate. ```rust let samples = Arc::new(vec![1000, 2000, 3000]); let sound = MemorySound::from_samples(samples, 1, 48000) ``` -------------------------------- ### Configure Specific Audio Device and Settings Source: https://github.com/boppofun/awedio/blob/main/_autodocs/09-patterns.md Configure the CPAL backend to use a specific audio device and settings like channel count, sample rate, buffer size, and sample format. ```rust use awedio::backends::{CpalBackend, CpalBufferSize}; use cpal::traits::HostTrait; let host = cpal::default_host(); let device = host.output_devices()? .find(|d| d.name().unwrap().contains("USB")) .unwrap(); let mut backend = CpalBackend::new( 2, // Stereo 48000, // 48 kHz CpalBufferSize::Set(256), // 256 frame buffer device, cpal::SampleFormat::F32, ); let manager = backend.start(|err| eprintln!("Audio error: {}", err))?; ``` -------------------------------- ### open_file Source: https://github.com/boppofun/awedio/blob/main/_autodocs/05-file-decoders.md Creates a Sound that reads from a file with automatic format detection based on extension. It supports various audio formats like MP3, WAV, QOA, and more, depending on enabled features. ```APIDOC ## open_file ### Description Creates a Sound that reads from a file with automatic format detection based on extension. ### Function Signature ```rust pub fn open_file>(path: P) -> Result, crate::Error> ``` ### Parameters #### Path Parameters - **path** (`AsRef`) - Required - File path ### Returns - `Result, crate::Error>` - Sound object or error ### Errors - `crate::Error::IoError(std::io::ErrorKind::NotFound)` - File not found - `crate::Error::IoError(std::io::ErrorKind::Unsupported)` - File format not supported - `crate::Error::FormatError` - Decoding error ### Supported Formats - **MP3** — If `rmp3-mp3` feature is enabled - **WAV** — If `hound-wav` feature is enabled or via symphonia - **QOA** — If `qoa` feature is enabled - **AAC, ALAC, FLAC, MKV, Ogg, ISO MP4, ADPCM, VorbisComment, MPA** — Via symphonia (enabled by default with `symphonia-all`) ### Remarks Uses `BufReader` internally. File reads occur on the current thread; consider converting to `MemorySound` if reading from the renderer thread. ### Example ```rust let sound = awedio::sounds::open_file("background.mp3")?; manager.play(sound); // Load a file into memory for efficient looping let loop_sound = open_file("effect.wav")? .into_memory_sound()?; let (sound, ctrl) = loop_sound.with_adjustable_volume().controllable(); manager.play(Box::new(sound)); ``` ``` -------------------------------- ### Create Empty Sound Source: https://github.com/boppofun/awedio/blob/main/_autodocs/03-sound-types.md Use Empty::new to create a sound that immediately returns Finished. Specify the number of channels and the sample rate. ```rust let empty = Empty::new(1, 48000); // Mono empty sound ``` -------------------------------- ### Play a sound with volume control Source: https://github.com/boppofun/awedio/blob/main/_autodocs/00-index.md Creates a controllable sine wave sound, plays it, and then adjusts its volume. Use this for dynamic volume adjustments during playback. ```rust let (sound, mut controller) = awedio::sounds::SineWave::new(440.0) .with_adjustable_volume_of(0.5) .controllable(); manager.play(Box::new(sound)); controller.set_volume(0.25); ``` -------------------------------- ### Handle Unsupported Audio Format Error Source: https://github.com/boppofun/awedio/blob/main/_autodocs/09-patterns.md Shows how to catch `ErrorKind::Unsupported` when opening a file with an unsupported audio format and provide a user-friendly message. ```rust match open_file("audio.opus") { Ok(sound) => manager.play(sound), Err(Error::IoError(e)) if e.kind() == ErrorKind::Unsupported => { eprintln!("Format not supported; convert to MP3 or WAV"); } Err(e) => eprintln!("Error: {}", e), } ``` -------------------------------- ### Build Complex Sound Sequences with Builder Pattern Source: https://github.com/boppofun/awedio/blob/main/_autodocs/00-index.md Chain methods to construct sound objects, such as loading a file, converting it to memory sound, and setting a duration limit. This pattern simplifies the creation of intricate sound configurations. ```rust let sound = open_file("song.mp3")? .into_memory_sound()? .finish_after(Duration::from_secs(30)); ``` -------------------------------- ### Control Playback with Command Pattern Source: https://github.com/boppofun/awedio/blob/main/_autodocs/00-index.md Utilize a `Controller` to send commands for playback control, such as setting volume or pause state. Commands are queued and processed on the audio thread, enabling remote management of sound playback. ```rust controller.set_volume(0.5); controller.set_paused(true); ``` -------------------------------- ### open_file_with_buffer_capacity Source: https://github.com/boppofun/awedio/blob/main/_autodocs/05-file-decoders.md Creates a Sound object that reads from a file with a user-defined buffer capacity. This allows for optimization based on storage speed and memory constraints. ```APIDOC ## open_file_with_buffer_capacity ### Description Creates a Sound that reads from a file with a custom buffer capacity. Use larger buffers for faster I/O on slow storage, smaller for lower memory overhead. ### Function Signature ```rust pub fn open_file_with_buffer_capacity>( path: P, buffer_capacity: usize, ) -> Result, crate::Error> ``` ### Parameters #### Path Parameters - **path** (`AsRef`) - Required - File path - **buffer_capacity** (`usize`) - Required - Size of internal BufReader buffer ### Returns - `Result, crate::Error>` - Sound object or error ### Example ```rust // Use larger buffer for large files let sound = open_file_with_buffer_capacity("large_file.flac", 65536)?; ``` ``` -------------------------------- ### Sound Trait next_sample() Control Flow Source: https://github.com/boppofun/awedio/blob/main/_autodocs/10-architecture.md Illustrates the control flow when processing samples from a Sound trait. Handles different sample types including raw samples, metadata changes, pauses, and finished states. ```rust loop { match sound.next_sample()? { NextSample::Sample(i16) => { // Process sample } NextSample::MetadataChanged => { // Handle channel count or sample rate change } NextSample::Paused => { // Sound paused; don't call again this batch } NextSample::Finished => { // Remove sound from active list } } } ``` -------------------------------- ### Sound with Completion Notification Source: https://github.com/boppofun/awedio/blob/main/_autodocs/09-patterns.md Load a file into memory, apply volume adjustment, and attach a completion notifier. The program waits for the sound to finish playing before proceeding. ```rust let (sound, rx) = open_file("one_shot.wav")? .into_memory_sound()? .with_adjustable_volume_of(0.8) .with_completion_notifier(); manager.play(Box::new(sound)); // Wait for completion rx.recv()?; println!("Sound effect finished!"); ``` -------------------------------- ### Convert File to Memory Sound Source: https://github.com/boppofun/awedio/blob/main/_autodocs/09-patterns.md Explains how to convert a file-based sound into a `MemorySound` for efficient reuse. This avoids repeated disk reads, especially useful for short effects played multiple times. ```rust // Reading from disk is slow; convert to memory let file_sound = open_file("effect.wav")?; let memory_sound = file_sound.into_memory_sound()?; // Can now clone cheaply for multiple uses let effect1 = memory_sound.clone(); let effect2 = memory_sound.clone(); manager.play(Box::new(effect1)); manager.play(Box::new(effect2)); ```