Skip to main content

dspk_core/buffer/
layout.rs

1use serde::{Deserialize, Serialize};
2
3/// Memory ordering convention for multi-channel signal data.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
5pub enum MemoryOrder {
6    /// Channel-major: [channel_0_samples..., channel_1_samples...]
7    /// Optimal for per-channel filtering and separable 1D convolution.
8    ChannelMajor,
9
10    /// Time-major (Interleaved): [c0_t0, c1_t0, ..., cN_t0, c0_t1, c1_t1, ...]
11    /// The usual order written by multi-channel acquisition hardware.
12    TimeMajor,
13}
14
15/// Striding and layout descriptor for multi-dimensional buffers.
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
17pub struct BufferLayout {
18    pub channels: usize,
19    pub samples: usize,
20    pub order: MemoryOrder,
21}
22
23impl BufferLayout {
24    pub fn new(channels: usize, samples: usize, order: MemoryOrder) -> Self {
25        Self {
26            channels,
27            samples,
28            order,
29        }
30    }
31
32    pub fn total_elements(&self) -> usize {
33        self.channels * self.samples
34    }
35
36    /// Compute linear index into the underlying flat storage.
37    #[inline(always)]
38    pub fn linear_index(&self, channel: usize, sample: usize) -> usize {
39        match self.order {
40            MemoryOrder::ChannelMajor => channel * self.samples + sample,
41            MemoryOrder::TimeMajor => sample * self.channels + channel,
42        }
43    }
44}