Repository navigation
Expand file tree
/
Copy pathprocess.rs
More file actions
100 lines (86 loc) · 3.58 KB
/
Copy pathprocess.rs
File metadata and controls
100 lines (86 loc) · 3.58 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
use std::mem::replace;
use rtrb::{Producer, Consumer};
use super::{AppToPlayerMessage, PlayerToAppMessage};
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum PlaybackState {
Paused,
Playing,
}
pub struct Process {
current_buffer: Option<Vec<f32>>,
current_buffer_idx: usize,
playback_state: PlaybackState,
app_to_player_recv: Consumer<AppToPlayerMessage>,
player_to_app_send: Producer<PlayerToAppMessage>,
}
impl Process {
pub fn new( app_to_player_recv: Consumer<AppToPlayerMessage>, player_to_app_send: Producer<PlayerToAppMessage>) -> Self {
Self {
current_buffer: None,
current_buffer_idx: 0,
playback_state: PlaybackState::Paused,
app_to_player_recv,
player_to_app_send,
}
}
// NOTE: as of right now we never have errors, but in the future, if we do,
// go back to a try_process (which returns void) calls a process (which returns result).
// I like that pattern
pub fn process(
&mut self,
data: &mut [f32],
) {
while let Ok(msg) = self.app_to_player_recv.pop() {
match msg {
AppToPlayerMessage::Play => {
self.playback_state = PlaybackState::Playing;
},
AppToPlayerMessage::Pause => {
self.playback_state = PlaybackState::Paused;
},
AppToPlayerMessage::SeekTo(_) => {
todo!()
},
AppToPlayerMessage::UseBuffer(new_buffer) => {
if let Some(current_buffer) = &mut self.current_buffer {
let _ = self.player_to_app_send.push(PlayerToAppMessage::DropBuffer(replace(current_buffer, Vec::new())));
}
self.playback_state = PlaybackState::Paused;
self.current_buffer = Some(new_buffer);
self.current_buffer_idx = 0;
},
}
}
if self.playback_state == PlaybackState::Paused {
silence(data);
return;
}
// assmue data is 2 channels and at correct sample rate.
if let Some(current_buffer) = &self.current_buffer {
if self.current_buffer_idx + data.len() >= current_buffer.len() {
// TODO: PLEASE VET THIS (will be easy to do with synthetic waveform nodes we start making where we can make them be 1 sec)
let count_at_end = current_buffer.len() - self.current_buffer_idx;
let count_at_start = data.len() - count_at_end;
unsafe {
std::ptr::copy(current_buffer.as_ptr().add(self.current_buffer_idx), data.as_mut_ptr(), count_at_end);
std::ptr::copy(current_buffer.as_ptr(), data.as_mut_ptr().add(count_at_end), count_at_start);
}
self.current_buffer_idx = count_at_start;
} else {
unsafe {
std::ptr::copy(current_buffer.as_ptr().add(self.current_buffer_idx), data.as_mut_ptr(), data.len());
}
self.current_buffer_idx += data.len();
}
let _ = self.player_to_app_send.push(PlayerToAppMessage::PlaybackPosition(self.current_buffer_idx, current_buffer.len()));
} else {
silence(data);
let _ = self.player_to_app_send.push(PlayerToAppMessage::PlaybackPosition(0, 0));
}
}
}
pub fn silence(data: &mut [f32]) {
for sample in data.iter_mut() {
*sample = 0.0;
}
}