Skip to content

Commit b77b259

Browse files
committed
AudioScheduledSourceNode: check start/stop consistency
- panic when stop before start - panic when start twice - panic when stop twice
1 parent 48caf24 commit b77b259

File tree

3 files changed

+118
-8
lines changed

3 files changed

+118
-8
lines changed

src/node/audio_buffer_source.rs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub struct AudioBufferSourceNode {
111111
buffer_time: Arc<AtomicF64>,
112112
buffer: Option<AudioBuffer>,
113113
loop_state: LoopState,
114-
source_started: bool,
114+
start_stop_count: u8,
115115
}
116116

117117
impl AudioNode for AudioBufferSourceNode {
@@ -149,11 +149,12 @@ impl AudioScheduledSourceNode for AudioBufferSourceNode {
149149

150150
fn stop_at(&mut self, when: f64) {
151151
assert_valid_time_value(when);
152-
assert!(
153-
self.source_started,
152+
assert_eq!(
153+
self.start_stop_count, 1,
154154
"InvalidStateError cannot stop before start"
155155
);
156156

157+
self.start_stop_count += 1;
157158
self.registration.post_message(ControlMessage::Stop(when));
158159
}
159160
}
@@ -224,7 +225,7 @@ impl AudioBufferSourceNode {
224225
buffer_time: Arc::clone(&renderer.render_state.buffer_time),
225226
buffer: None,
226227
loop_state,
227-
source_started: false,
228+
start_stop_count: 0,
228229
};
229230

230231
(node, Box::new(renderer))
@@ -256,13 +257,12 @@ impl AudioBufferSourceNode {
256257
assert_valid_time_value(start);
257258
assert_valid_time_value(offset);
258259
assert_valid_time_value(duration);
259-
assert!(
260-
!self.source_started,
260+
assert_eq!(
261+
self.start_stop_count, 0,
261262
"InvalidStateError - Cannot call `start` twice"
262263
);
263264

264-
self.source_started = true;
265-
265+
self.start_stop_count += 1;
266266
let control = ControlMessage::StartWithOffsetAndDuration(start, offset, duration);
267267
self.registration.post_message(control);
268268
}
@@ -1445,4 +1445,31 @@ mod tests {
14451445

14461446
assert_float_eq!(channel[..], expected[..], abs_all <= 0.);
14471447
}
1448+
1449+
#[test]
1450+
#[should_panic]
1451+
fn test_start_twice() {
1452+
let context = OfflineAudioContext::new(2, 1, 44_100.);
1453+
let mut src = context.create_buffer_source();
1454+
src.start();
1455+
src.start();
1456+
}
1457+
1458+
#[test]
1459+
#[should_panic]
1460+
fn test_stop_before_start() {
1461+
let context = OfflineAudioContext::new(2, 1, 44_100.);
1462+
let mut src = context.create_buffer_source();
1463+
src.stop();
1464+
}
1465+
1466+
#[test]
1467+
#[should_panic]
1468+
fn test_stop_twice() {
1469+
let context = OfflineAudioContext::new(2, 1, 44_100.);
1470+
let mut src = context.create_buffer_source();
1471+
src.start();
1472+
src.stop();
1473+
src.stop();
1474+
}
14481475
}

src/node/constant_source.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ pub struct ConstantSourceNode {
7474
registration: AudioContextRegistration,
7575
channel_config: ChannelConfig,
7676
offset: AudioParam,
77+
start_stop_count: u8,
7778
}
7879

7980
impl AudioNode for ConstantSourceNode {
@@ -102,6 +103,12 @@ impl AudioScheduledSourceNode for ConstantSourceNode {
102103

103104
fn start_at(&mut self, when: f64) {
104105
assert_valid_time_value(when);
106+
assert_eq!(
107+
self.start_stop_count, 0,
108+
"InvalidStateError - Cannot call `start` twice"
109+
);
110+
111+
self.start_stop_count += 1;
105112
self.registration.post_message(Schedule::Start(when));
106113
}
107114

@@ -112,6 +119,12 @@ impl AudioScheduledSourceNode for ConstantSourceNode {
112119

113120
fn stop_at(&mut self, when: f64) {
114121
assert_valid_time_value(when);
122+
assert_eq!(
123+
self.start_stop_count, 1,
124+
"InvalidStateError cannot stop before start"
125+
);
126+
127+
self.start_stop_count += 1;
115128
self.registration.post_message(Schedule::Stop(when));
116129
}
117130
}
@@ -142,6 +155,7 @@ impl ConstantSourceNode {
142155
registration,
143156
channel_config: ChannelConfig::default(),
144157
offset: param,
158+
start_stop_count: 0,
145159
};
146160

147161
(node, Box::new(render))
@@ -297,4 +311,31 @@ mod tests {
297311
assert_float_eq!(channel[0..128], vec![0.; 128][..], abs_all <= 0.);
298312
assert_float_eq!(channel[128..], vec![1.; 128][..], abs_all <= 0.);
299313
}
314+
315+
#[test]
316+
#[should_panic]
317+
fn test_start_twice() {
318+
let context = OfflineAudioContext::new(2, 1, 44_100.);
319+
let mut src = context.create_constant_source();
320+
src.start();
321+
src.start();
322+
}
323+
324+
#[test]
325+
#[should_panic]
326+
fn test_stop_before_start() {
327+
let context = OfflineAudioContext::new(2, 1, 44_100.);
328+
let mut src = context.create_constant_source();
329+
src.stop();
330+
}
331+
332+
#[test]
333+
#[should_panic]
334+
fn test_stop_twice() {
335+
let context = OfflineAudioContext::new(2, 1, 44_100.);
336+
let mut src = context.create_constant_source();
337+
src.start();
338+
src.stop();
339+
src.stop();
340+
}
300341
}

src/node/oscillator.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ pub struct OscillatorNode {
132132
detune: AudioParam,
133133
/// Waveform of an oscillator
134134
type_: OscillatorType,
135+
/// Number of start/stop actions, node can only be started and stopped once
136+
start_stop_count: u8,
135137
}
136138

137139
impl AudioNode for OscillatorNode {
@@ -162,6 +164,12 @@ impl AudioScheduledSourceNode for OscillatorNode {
162164

163165
fn start_at(&mut self, when: f64) {
164166
assert_valid_time_value(when);
167+
assert_eq!(
168+
self.start_stop_count, 0,
169+
"InvalidStateError - Cannot call `start` twice"
170+
);
171+
172+
self.start_stop_count += 1;
165173
self.registration.post_message(Schedule::Start(when));
166174
}
167175

@@ -172,6 +180,12 @@ impl AudioScheduledSourceNode for OscillatorNode {
172180

173181
fn stop_at(&mut self, when: f64) {
174182
assert_valid_time_value(when);
183+
assert_eq!(
184+
self.start_stop_count, 1,
185+
"InvalidStateError cannot stop before start"
186+
);
187+
188+
self.start_stop_count += 1;
175189
self.registration.post_message(Schedule::Stop(when));
176190
}
177191
}
@@ -238,6 +252,7 @@ impl OscillatorNode {
238252
frequency: f_param,
239253
detune: det_param,
240254
type_,
255+
start_stop_count: 0,
241256
};
242257

243258
(node, Box::new(renderer))
@@ -1182,4 +1197,31 @@ mod tests {
11821197

11831198
assert_float_eq!(result[..], expected[..], abs_all <= 1e-5);
11841199
}
1200+
1201+
#[test]
1202+
#[should_panic]
1203+
fn test_start_twice() {
1204+
let context = OfflineAudioContext::new(2, 1, 44_100.);
1205+
let mut osc = context.create_oscillator();
1206+
osc.start();
1207+
osc.start();
1208+
}
1209+
1210+
#[test]
1211+
#[should_panic]
1212+
fn test_stop_before_start() {
1213+
let context = OfflineAudioContext::new(2, 1, 44_100.);
1214+
let mut osc = context.create_oscillator();
1215+
osc.stop();
1216+
}
1217+
1218+
#[test]
1219+
#[should_panic]
1220+
fn test_stop_twice() {
1221+
let context = OfflineAudioContext::new(2, 1, 44_100.);
1222+
let mut osc = context.create_oscillator();
1223+
osc.start();
1224+
osc.stop();
1225+
osc.stop();
1226+
}
11851227
}

0 commit comments

Comments
 (0)