///|
/// Block-boundary mono graph hot-swap wrapper for `CompiledDsp`.
///
/// Public facade wrapper; implementation lives in `graph/internal/staging`.
struct CompiledDspHotSwap(@staging.CompiledDspHotSwap)
///|
/// Block-boundary stereo graph hot-swap wrapper for `CompiledStereoDsp`.
///
/// Public facade wrapper; implementation lives in `graph/internal/staging`.
struct CompiledStereoDspHotSwap(@staging.CompiledStereoDspHotSwap)
///|
/// Failure reason for result-typed hot-swap queue APIs.
pub(all) enum HotSwapQueueError {
SampleRateMismatch(Double, Double)
BlockCapacityMismatch(Int, Int)
} derive(Debug)
///|
pub impl Show for HotSwapQueueError with fn output(self, logger) {
logger.write_string(@debug.to_string(self))
}
///|
fn hot_swap_queue_error_from_staging(
error : @staging.HotSwapQueueError,
) -> HotSwapQueueError {
match error {
@staging.HotSwapQueueError::SampleRateMismatch(active_rate, next_rate) =>
HotSwapQueueError::SampleRateMismatch(active_rate, next_rate)
@staging.HotSwapQueueError::BlockCapacityMismatch(
active_capacity,
next_capacity
) =>
HotSwapQueueError::BlockCapacityMismatch(active_capacity, next_capacity)
}
}
///|
fn hot_swap_queue_result_from_staging(
result : Result[Unit, @staging.HotSwapQueueError],
) -> Result[Unit, HotSwapQueueError] {
match result {
Ok(_) => Ok(())
Err(error) => Err(hot_swap_queue_error_from_staging(error))
}
}
///|
/// Create a hot-swap wrapper around an active mono compiled graph.
pub fn CompiledDspHotSwap::from_graph(
active : CompiledDsp,
crossfade_samples? : Int = 0,
) -> CompiledDspHotSwap {
CompiledDspHotSwap(
@staging.CompiledDspHotSwap::from_graph(active.raw(), crossfade_samples~),
)
}
///|
/// Queue a replacement graph for the next `process(...)` call.
///
/// Returns an error when the replacement graph is incompatible with the active
/// graph's compile-time sample rate or block capacity.
pub fn CompiledDspHotSwap::queue_swap(
self : CompiledDspHotSwap,
next : CompiledDsp,
) -> Result[Unit, HotSwapQueueError] {
hot_swap_queue_result_from_staging(self.0.queue_swap(next.raw()))
}
///|
/// Process one block, crossfading between the active and pending graphs when a
/// swap is in flight.
pub fn CompiledDspHotSwap::process(
self : CompiledDspHotSwap,
context : DspContext,
output : AudioBuffer,
) -> Unit {
self.0.process(context, output)
}
///|
/// Create a hot-swap wrapper around an active stereo compiled graph.
pub fn CompiledStereoDspHotSwap::from_graph(
active : CompiledStereoDsp,
crossfade_samples? : Int = 0,
) -> CompiledStereoDspHotSwap {
CompiledStereoDspHotSwap(
@staging.CompiledStereoDspHotSwap::from_graph(
active.raw(),
crossfade_samples~,
),
)
}
///|
/// Queue a replacement stereo graph for the next `process(...)` call.
///
/// Returns an error when the replacement graph is incompatible with the active
/// graph's compile-time sample rate or block capacity.
pub fn CompiledStereoDspHotSwap::queue_swap(
self : CompiledStereoDspHotSwap,
next : CompiledStereoDsp,
) -> Result[Unit, HotSwapQueueError] {
hot_swap_queue_result_from_staging(self.0.queue_swap(next.raw()))
}
///|
/// Process one block, crossfading between the active and pending stereo graphs
/// when a swap is in flight.
pub fn CompiledStereoDspHotSwap::process(
self : CompiledStereoDspHotSwap,
context : DspContext,
left_output : AudioBuffer,
right_output : AudioBuffer,
) -> Unit {
self.0.process(context, left_output, right_output)
}