rill_lofi/
lofi_chip_source.rs1use std::marker::PhantomData;
7
8use rill_core::{
9 time::{ClockTick, RenderContext},
10 traits::{
11 algorithm::Algorithm, parameter_write::ParameterWrite, Node, NodeCategory, NodeId,
12 NodeMetadata, NodeState, ParamValue, ParameterId, Port, ProcessResult, Source,
13 },
14};
15
16use crate::chip_emulator::ChipEmulator;
17use crate::config::LofiConfig;
18use crate::lofi_processor::LofiProcessor;
19
20pub struct LofiChipSource<C: Algorithm<f32> + ChipEmulator + ParameterWrite, const BUF_SIZE: usize>
26{
27 id: NodeId,
28 metadata: NodeMetadata,
29 chip: C,
30 lofi: LofiProcessor<BUF_SIZE>,
31 outputs: Vec<Port<f32, BUF_SIZE>>,
32 state: NodeState<f32, BUF_SIZE>,
33 _phantom: PhantomData<[f32; BUF_SIZE]>,
34}
35
36impl<C: Algorithm<f32> + ChipEmulator + ParameterWrite, const BUF_SIZE: usize>
37 LofiChipSource<C, BUF_SIZE>
38{
39 pub fn new(chip: C, lofi_config: LofiConfig, num_channels: usize) -> Self {
41 let mut metadata = NodeMetadata::new("LofiChip", NodeCategory::Source);
42 metadata.signal_inputs = 0;
43 metadata.signal_outputs = num_channels;
44 let outputs = (0..num_channels)
45 .map(|i| {
46 Port::output(
47 NodeId(0),
48 i as u16,
49 &if num_channels == 1 {
50 "out".into()
51 } else {
52 format!("ch_{i}")
53 },
54 )
55 })
56 .collect();
57 Self {
58 id: NodeId(0),
59 metadata,
60 chip,
61 lofi: LofiProcessor::new(lofi_config),
62 outputs,
63 state: NodeState::new(44100.0),
64 _phantom: PhantomData,
65 }
66 }
67}
68
69impl<C: Algorithm<f32> + ChipEmulator + ParameterWrite, const BUF_SIZE: usize> Node<f32, BUF_SIZE>
70 for LofiChipSource<C, BUF_SIZE>
71{
72 fn node_type_id(&self) -> rill_core::NodeTypeId
73 where
74 Self: 'static + Sized,
75 {
76 rill_core::NodeTypeId::of::<Self>()
77 }
78
79 fn id(&self) -> NodeId {
80 self.id
81 }
82
83 fn set_id(&mut self, id: NodeId) {
84 self.id = id;
85 }
86
87 fn metadata(&self) -> NodeMetadata {
88 self.metadata.clone()
89 }
90
91 fn init(&mut self, sample_rate: f32) {
92 self.chip.init(sample_rate);
93 self.lofi.init(sample_rate);
94 self.state.sample_rate = sample_rate;
95 }
96
97 fn reset(&mut self) {
98 self.chip.reset();
99 self.lofi.reset();
100 self.state.reset();
101 }
102
103 fn get_parameter(&self, id: &ParameterId) -> Option<ParamValue> {
104 self.lofi.get_parameter(id)
105 }
106
107 fn set_parameter(&mut self, id: &ParameterId, value: ParamValue) -> ProcessResult<()> {
108 if self
110 .chip
111 .write_parameter(id.as_str(), value.clone())
112 .is_ok()
113 {
114 return Ok(());
115 }
116 Node::<f32, BUF_SIZE>::set_parameter(&mut self.lofi, id, value)
118 }
119
120 fn input_port(&self, _index: usize) -> Option<&Port<f32, BUF_SIZE>> {
121 None
122 }
123
124 fn input_port_mut(&mut self, _index: usize) -> Option<&mut Port<f32, BUF_SIZE>> {
125 None
126 }
127
128 fn output_port(&self, index: usize) -> Option<&Port<f32, BUF_SIZE>> {
129 self.outputs.get(index)
130 }
131
132 fn output_port_mut(&mut self, index: usize) -> Option<&mut Port<f32, BUF_SIZE>> {
133 self.outputs.get_mut(index)
134 }
135
136 fn control_port(&self, _index: usize) -> Option<&Port<f32, BUF_SIZE>> {
137 None
138 }
139
140 fn control_port_mut(&mut self, _index: usize) -> Option<&mut Port<f32, BUF_SIZE>> {
141 None
142 }
143
144 fn num_signal_inputs(&self) -> usize {
145 0
146 }
147
148 fn num_signal_outputs(&self) -> usize {
149 self.outputs.len()
150 }
151
152 fn state(&self) -> &NodeState<f32, BUF_SIZE> {
153 &self.state
154 }
155
156 fn state_mut(&mut self) -> &mut NodeState<f32, BUF_SIZE> {
157 &mut self.state
158 }
159}
160
161impl<C: Algorithm<f32> + ChipEmulator + ParameterWrite, const BUF_SIZE: usize> Source<f32, BUF_SIZE>
162 for LofiChipSource<C, BUF_SIZE>
163{
164 fn generate(
165 &mut self,
166 _ctx: &RenderContext,
167 _control_inputs: &[f32],
168 _clock_inputs: &[RenderContext],
169 _tick: &ClockTick,
170 ) -> ProcessResult<()> {
171 let mut raw = [0.0f32; BUF_SIZE];
173 self.chip.process(None, &mut raw)?;
174
175 let out0 = self.outputs[0].write();
177 for (j, s) in out0.iter_mut().enumerate() {
178 *s = self.lofi.process_sample(raw[j]);
179 }
180 let out0_copy = *self.outputs[0].read();
182 for port in self.outputs.iter_mut().skip(1) {
183 port.write().copy_from_slice(&out0_copy);
184 }
185
186 self.state.advance();
187 Ok(())
188 }
189}