firewheel_graph/backend.rs
1use core::error::Error;
2use core::time::Duration;
3
4#[cfg(not(feature = "std"))]
5use bevy_platform::prelude::{String, Vec};
6
7use firewheel_core::{node::StreamStatus, StreamInfo};
8
9use crate::processor::FirewheelProcessor;
10
11/// A trait describing an audio backend.
12///
13/// When an instance is dropped, then it must automatically stop its
14/// corresponding audio stream.
15///
16/// All methods in this trait are only ever invoked from the main
17/// thread (the thread where the [`crate::context::FirewheelCtx`]
18/// lives).
19pub trait AudioBackend: Sized {
20 /// The configuration of the audio stream.
21 type Config;
22 /// An error when starting a new audio stream.
23 type StartStreamError: Error;
24 /// An error that has caused the audio stream to stop.
25 type StreamError: Error;
26
27 /// A type describing an instant in time.
28 type Instant: Send + Clone;
29
30 /// Return a list of the available input devices.
31 fn available_input_devices() -> Vec<DeviceInfo> {
32 Vec::new()
33 }
34 /// Return a list of the available output devices.
35 fn available_output_devices() -> Vec<DeviceInfo> {
36 Vec::new()
37 }
38
39 /// Start the audio stream with the given configuration, and return
40 /// a handle for the audio stream.
41 fn start_stream(config: Self::Config) -> Result<(Self, StreamInfo), Self::StartStreamError>;
42
43 /// Send the given processor to the audio thread for processing.
44 fn set_processor(&mut self, processor: FirewheelProcessor<Self>);
45
46 /// Poll the status of the running audio stream. Return an error if the
47 /// audio stream has stopped for any reason.
48 fn poll_status(&mut self) -> Result<(), Self::StreamError>;
49
50 /// Return the amount of time that has elapsed from the instant
51 /// [`FirewheelProcessor::process_interleaved`] was last called and now.
52 ///
53 /// The given `process_timestamp` is the `Self::Instant` that was passed
54 /// to the latest call to [`FirewheelProcessor::process_interleaved`].
55 /// This can be used to calculate the delay if needed.
56 ///
57 /// If for any reason the delay could not be determined, return `None`.
58 fn delay_from_last_process(&self, process_timestamp: Self::Instant) -> Option<Duration>;
59}
60
61/// Information about an audio device.
62#[derive(Debug, Clone, PartialEq)]
63pub struct DeviceInfo {
64 pub name: String,
65 pub num_channels: u16,
66 pub is_default: bool,
67}
68
69#[derive(Debug, Clone, PartialEq, Eq)]
70pub struct BackendProcessInfo<B: AudioBackend> {
71 pub num_in_channels: usize,
72 pub num_out_channels: usize,
73 pub frames: usize,
74 pub process_timestamp: B::Instant,
75 pub duration_since_stream_start: Duration,
76 pub input_stream_status: StreamStatus,
77 pub output_stream_status: StreamStatus,
78 pub dropped_frames: u32,
79}