rill_core/traits/buffer_view.rs
1//! # BufferView — backend-specific accessor for I/O ring buffers
2//!
3//! A `BufferView` encapsulates per-backend rules (interleave/deinterleave,
4//! stride, alignment) for reading input samples from and writing output
5//! samples to cross-thread ring buffers or DMA windows.
6//!
7//! Used internally by `rill-io` backends (`DirectView`, `DeinterleavedView`).
8//! Graph nodes access I/O through `IoCapture::read_input()` and
9//! `IoPlayback::write_output()` — they do not use `BufferView` directly.
10
11/// Backend-specific accessor for I/O ring buffers.
12///
13/// Encapsulates per-backend rules (interleave/deinterleave) for reading
14/// input samples from and writing output samples to cross-thread ring buffers.
15/// Each backend provides its own implementation.
16pub trait BufferView: Send + Sync {
17 /// Number of input (capture) channels.
18 fn num_input_channels(&self) -> usize;
19
20 /// Number of output (playback) channels.
21 fn num_output_channels(&self) -> usize;
22
23 /// Read available input samples for one channel into `dst`.
24 ///
25 /// Returns the number of samples actually read (may be less than `dst.len()`
26 /// if insufficient data is available).
27 fn read_input(&self, channel: usize, dst: &mut [f32]) -> usize;
28
29 /// Write output samples for one channel from `src`.
30 ///
31 /// Returns the number of samples actually written (may be less than `src.len()`
32 /// if insufficient space is available).
33 fn write_output(&self, channel: usize, src: &[f32]) -> usize;
34}
35
36/// No-op BufferView for testing and default initialization.
37///
38/// Fills input with zeros and discards output.
39pub struct NullBufferView {
40 num_input_channels: usize,
41 num_output_channels: usize,
42}
43
44impl NullBufferView {
45 /// Create a new null view with the given channel counts.
46 pub fn new(num_input_channels: usize, num_output_channels: usize) -> Self {
47 Self {
48 num_input_channels,
49 num_output_channels,
50 }
51 }
52}
53
54impl BufferView for NullBufferView {
55 fn num_input_channels(&self) -> usize {
56 self.num_input_channels
57 }
58
59 fn num_output_channels(&self) -> usize {
60 self.num_output_channels
61 }
62
63 fn read_input(&self, _channel: usize, dst: &mut [f32]) -> usize {
64 let n = dst.len();
65 dst.fill(0.0);
66 n
67 }
68
69 fn write_output(&self, _channel: usize, _src: &[f32]) -> usize {
70 _src.len()
71 }
72}