1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use crate::;
use Vec;
/// To implement [`Source`] means something can be a source of sound/voltage,
///
/// Two things are required by the trait:
///
/// 1) keeping track of what the source is using an unique `usize` id
/// 2) using the sample method to fill one or multiple [`Signal`] buffers with f32 data.
///
/// A very basic example might be to implement a DC offset module
///
/// ```
/// use screech::traits::{Tracker, Source};
/// use screech::{Screech, Input, Output};
///
/// struct Offset {
/// id: usize,
/// input: Input,
/// output: Output,
/// offset: f32,
/// }
///
/// impl Offset {
/// fn new(screech: &mut Screech, offset: f32) -> Self {
/// // obtain a unique identifier from the main sreech instance
/// let id = screech.create_source_id();
///
/// Offset {
/// id,
/// // initialize a new input to keep track of input connected to our source
/// input: screech.init_input(&id, "signal_in"),
/// // initialize a new output [`Signal`] buffer for our id and name
/// output: screech.init_output(&id, "signal_out"),
/// offset,
/// }
/// }
/// }
///
/// impl Source for Offset {
/// fn sample(&mut self, tracker: &mut dyn Tracker, sample_rate: usize) {
/// for i in 0..*tracker.get_buffer_size() {
/// // set offset as initial value
/// let mut signal = self.offset;
///
/// // add all inputs to the signal
/// for input in tracker.get_input(&self.input).unwrap().into_iter() {
/// if let Some(s) = tracker.get_output(&input).and_then(|o| o.samples.get(i)) {
/// signal += s;
/// }
/// }
///
/// // add signal to the final output
/// let output = tracker.get_mut_output(&self.output).unwrap();
/// output.samples[i] = signal;
/// }
/// }
///
/// fn get_source_id(&self) -> &usize {
/// &self.id
/// }
/// }
/// ```
/// Tracker trait to keep track of buffers and connections between [`Output`]s and [`Input`]s
///
/// for implementation examples see [`crate::BasicTracker`] or [`crate::DynamicTracker`]
/// Trait to implement conversion from a slice of sized types to a generic