1use std::time::Duration;
2
3use dasp_sample::Sample as DaspSample;
4
5use super::SeekError;
6use crate::common::{ChannelCount, SampleRate};
7use crate::{Sample, Source};
8
9#[derive(Copy, Clone, Debug)]
13pub struct Zero {
14 channels: ChannelCount,
15 sample_rate: SampleRate,
16 total_samples: Option<usize>,
17 position: usize,
18}
19
20impl Zero {
21 #[inline]
23 pub fn new(channels: ChannelCount, sample_rate: SampleRate) -> Self {
24 Self {
25 channels,
26 sample_rate,
27 total_samples: None,
28 position: 0,
29 }
30 }
31
32 #[inline]
34 pub fn new_samples(
35 channels: ChannelCount,
36 sample_rate: SampleRate,
37 num_samples: usize,
38 ) -> Self {
39 Self {
40 channels,
41 sample_rate,
42 total_samples: Some(num_samples),
43 position: 0,
44 }
45 }
46}
47
48impl Iterator for Zero {
49 type Item = Sample;
50
51 #[inline]
52 fn next(&mut self) -> Option<Self::Item> {
53 if let Some(total_samples) = self.total_samples {
54 if self.position < total_samples {
55 self.position += 1;
56 } else {
57 return None;
58 }
59 }
60
61 Some(Sample::EQUILIBRIUM)
62 }
63
64 #[inline]
65 fn size_hint(&self) -> (usize, Option<usize>) {
66 match self.total_samples {
67 Some(total_samples) => {
68 let remaining = total_samples - self.position;
69 (remaining, Some(remaining))
70 }
71 None => (usize::MAX, None),
72 }
73 }
74}
75
76impl Source for Zero {
77 #[inline]
78 fn current_span_len(&self) -> Option<usize> {
79 self.total_samples
80 }
81
82 #[inline]
83 fn channels(&self) -> ChannelCount {
84 self.channels
85 }
86
87 #[inline]
88 fn sample_rate(&self) -> SampleRate {
89 self.sample_rate
90 }
91
92 fn total_duration(&self) -> Option<Duration> {
93 self.total_samples.map(|total| {
94 let sample_rate = self.sample_rate.get() as u64;
95 let frames = total / self.channels.get() as usize;
96 let secs = frames as u64 / sample_rate;
97 let nanos = ((frames as u64 % sample_rate) * 1_000_000_000) / sample_rate;
98 Duration::new(secs, nanos as u32)
99 })
100 }
101
102 fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
103 if let (Some(total_samples), Some(total_duration)) =
104 (self.total_samples, self.total_duration())
105 {
106 let mut target = pos;
107 if target > total_duration {
108 target = total_duration;
109 }
110
111 let target_samples = (target.as_secs_f32()
112 * self.sample_rate.get() as f32
113 * self.channels.get() as f32) as usize;
114 let target_samples = target_samples.min(total_samples);
115
116 self.position = target_samples;
117 }
118
119 Ok(())
120 }
121}