dspk_core/buffer/
chunk.rs1use crate::error::{DspError, DspResult};
2use crate::time::{RationalTime, SampleRate};
3use super::layout::{BufferLayout, MemoryOrder};
4
5#[derive(Debug, Clone, PartialEq)]
7pub struct SignalChunk {
8 layout: BufferLayout,
9 sample_rate: SampleRate,
10 start_time: RationalTime,
11 data: Vec<f32>,
12}
13
14impl SignalChunk {
15 pub fn new(
16 channels: usize,
17 samples: usize,
18 sample_rate: SampleRate,
19 start_time: RationalTime,
20 order: MemoryOrder,
21 data: Vec<f32>,
22 ) -> DspResult<Self> {
23 let expected_len = channels * samples;
24 if data.len() != expected_len {
25 return Err(DspError::ShapeMismatch {
26 expected: vec![expected_len],
27 actual: vec![data.len()],
28 });
29 }
30
31 Ok(Self {
32 layout: BufferLayout::new(channels, samples, order),
33 sample_rate,
34 start_time,
35 data,
36 })
37 }
38
39 pub fn zeros(
40 channels: usize,
41 samples: usize,
42 sample_rate: SampleRate,
43 start_time: RationalTime,
44 order: MemoryOrder,
45 ) -> Self {
46 let data = vec![0.0f32; channels * samples];
47 Self {
48 layout: BufferLayout::new(channels, samples, order),
49 sample_rate,
50 start_time,
51 data,
52 }
53 }
54
55 pub fn layout(&self) -> &BufferLayout {
56 &self.layout
57 }
58
59 pub fn channels(&self) -> usize {
60 self.layout.channels
61 }
62
63 pub fn samples(&self) -> usize {
64 self.layout.samples
65 }
66
67 pub fn sample_rate(&self) -> SampleRate {
68 self.sample_rate
69 }
70
71 pub fn start_time(&self) -> RationalTime {
72 self.start_time
73 }
74
75 pub fn as_slice(&self) -> &[f32] {
76 &self.data
77 }
78
79 pub fn as_mut_slice(&mut self) -> &mut [f32] {
80 &mut self.data
81 }
82
83 fn check(&self, channel: usize, sample: usize) -> DspResult<()> {
84 if channel >= self.layout.channels {
85 return Err(DspError::InvalidChannel { channel, total: self.layout.channels });
86 }
87 if sample >= self.layout.samples {
88 return Err(DspError::SampleRange {
89 start: sample as u64,
90 end: sample as u64 + 1,
91 total: self.layout.samples as u64,
92 });
93 }
94 Ok(())
95 }
96
97 #[inline(always)]
98 pub fn get(&self, channel: usize, sample: usize) -> DspResult<f32> {
99 self.check(channel, sample)?;
100 let idx = self.layout.linear_index(channel, sample);
101 Ok(self.data[idx])
102 }
103
104 #[inline(always)]
105 pub fn set(&mut self, channel: usize, sample: usize, value: f32) -> DspResult<()> {
106 self.check(channel, sample)?;
107 let idx = self.layout.linear_index(channel, sample);
108 self.data[idx] = value;
109 Ok(())
110 }
111}