-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontext.rs
More file actions
143 lines (118 loc) · 3.84 KB
/
Copy pathcontext.rs
File metadata and controls
143 lines (118 loc) · 3.84 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
use std::time::Instant;
use slotmap::new_key_type;
use crate::{
config::Config,
midi::{MidiError, MidiMessage, MidiRuntimeFrontend, MidiStore},
resources::{
Resources,
params::{ParamError, ParamKey},
},
};
new_key_type! { struct ExternalAudioKey; }
/// The AudioContext struct contains information about the current audio graph, as well as
/// some resources that are hosted up for nodes to access within a specific runtime.
///
/// This prevents complex state sharing or unsafe ptr logic when using things like shared buffers
/// for delay lines or samples.
pub struct AudioContext {
config: Config,
midi_store: Option<MidiStore>,
midi_runtime_frontend: Option<MidiRuntimeFrontend>,
resources: Resources,
block_start: Instant,
}
impl AudioContext {
pub fn new(config: Config, resources: Resources) -> Self {
Self {
config,
midi_store: None,
resources,
midi_runtime_frontend: None,
block_start: Instant::now(),
}
}
/// For a time being, this is a quick hack inside oversampling. I would recommend not using, as it does not reflex internal state!!!
pub fn set_sample_rate(&mut self, sr: usize) {
self.config.sample_rate = sr;
}
pub(crate) fn update_midi(&mut self) {
self.clear_midi();
let Some(runtime) = self.midi_runtime_frontend.take() else {
return;
};
while let Some(msg) = runtime.recv() {
if let Err(e) = self.insert_midi_msg(msg) {
eprintln!("{:?}", e);
}
}
self.midi_runtime_frontend = Some(runtime);
}
/// For a time being, this is a quick hack inside oversampling. I would recommend not using, as it does not reflex internal state!!!
pub fn set_block_size(&mut self, block_size: usize) {
self.config.block_size = block_size;
}
pub fn get_config(&self) -> Config {
self.config
}
pub fn get_resources(&self) -> &Resources {
&self.resources
}
pub fn set_resources(&mut self, resources: Resources) {
self.resources = resources;
}
pub fn get_resources_mut(&mut self) -> &mut Resources {
&mut self.resources
}
pub fn get_param(&self, key: &ParamKey) -> Result<f32, ParamError> {
self.resources.get_param(key)
}
pub fn sample_rate_f32(&self) -> f32 {
self.config.sample_rate as f32
}
#[inline(always)]
pub fn sample_rate(&self) -> usize {
self.config.sample_rate
}
// Add a midi store to the runtime.
pub fn set_midi_store(&mut self, store: MidiStore) {
self.midi_store = Some(store);
}
pub fn set_midi_runtime_frontend(&mut self, frontend: MidiRuntimeFrontend) {
self.midi_runtime_frontend = Some(frontend)
}
pub fn send_to_system_midi(
&mut self,
msg: MidiMessage,
instant: Instant,
) -> Result<(), MidiError> {
if let Some(inner) = &mut self.midi_runtime_frontend {
inner.writer_frontend.send_to_system_midi(msg, instant)
} else {
Err(MidiError::MissingRuntime)
}
}
#[inline(always)]
pub fn get_midi_store(&self) -> Option<&MidiStore> {
self.midi_store.as_ref()
}
#[inline(always)]
pub fn set_instant(&mut self) {
self.block_start = Instant::now()
}
#[inline(always)]
pub fn get_instant(&self) -> Instant {
self.block_start
}
/// Insert a midi message into the store.
#[inline(always)]
pub fn insert_midi_msg(&mut self, msg: MidiMessage) -> Result<(), MidiError> {
let store = self.midi_store.as_mut().unwrap();
store.insert(msg)
}
#[inline(always)]
pub fn clear_midi(&mut self) {
if let Some(store) = &mut self.midi_store {
store.clear();
}
}
}