Skip to content

Commit cd5fc8d

Browse files
committed
Use rtrb and rsor
1 parent aba3abb commit cd5fc8d

File tree

6 files changed

+161
-244
lines changed

6 files changed

+161
-244
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ subdirectory = false
1212

1313
[dependencies]
1414
asdfspline = { path = "asdfspline" }
15-
# See https://github.com/crossbeam-rs/crossbeam/pull/338:
16-
crossbeam = { git = "https://github.com/mgeier/crossbeam.git", rev = "b3343023f97848b81fecf6c7fb480cdca7c678d8" }
15+
rtrb = "0.1"
16+
rsor = "0.1"
1717
errno = "*"
1818
libflac-sys = "0.1"
1919
hound = "*"

cbindgen.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,3 @@ include_guard = "ASDF_H"
22
include_version = true
33
language = "C"
44
cpp_compat = true
5-
6-
[export.rename]
7-
"Scene" = "AsdfScene"

src/audiofile/dynamic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub trait AudioFile: AudioFileBasics {
1313
channel_map: &[Option<usize>],
1414
blocksize: u32,
1515
offset: u32,
16-
channels: &mut [Box<[f32]>],
16+
channels: &mut [&mut [f32]],
1717
) -> Result<(), BoxedError>;
1818
}
1919

@@ -28,7 +28,7 @@ where
2828
channel_map: &[Option<usize>],
2929
blocksize: u32,
3030
offset: u32,
31-
channels: &mut [Box<[f32]>],
31+
channels: &mut [&mut [f32]],
3232
) -> Result<(), BoxedError> {
3333
self.fill_channels(channel_map, blocksize, offset, channels)
3434
}

src/capi.rs

Lines changed: 59 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,26 @@ use std::fmt::{Display, Write};
77
use std::time::Duration;
88

99
use libc::c_char;
10+
use rsor::Slice;
1011

1112
use crate::transform::{Quat, Transform, Vec3};
1213
use crate::{Scene, Source};
1314

15+
pub struct AsdfScene {
16+
inner: Scene,
17+
blocksize: u32,
18+
sos: Slice<[f32]>,
19+
}
20+
21+
impl AsdfScene {
22+
pub fn get_source(&self, index: u32) -> AsdfSourceInfo {
23+
AsdfSourceInfo::new(
24+
&self.inner.sources[index as usize],
25+
self.inner.get_source_port(index),
26+
)
27+
}
28+
}
29+
1430
#[repr(C)]
1531
#[derive(Default)]
1632
pub struct AsdfTransform {
@@ -76,12 +92,6 @@ impl Drop for AsdfSourceInfo {
7692
}
7793
}
7894

79-
impl Scene {
80-
pub fn get_source(&self, index: u32) -> AsdfSourceInfo {
81-
AsdfSourceInfo::new(&self.sources[index as usize], self.get_source_port(index))
82-
}
83-
}
84-
8595
/// Load an ASDF scene from a file.
8696
///
8797
/// Before starting playback (i.e. calling asdf_get_audio_data()
@@ -98,53 +108,54 @@ pub unsafe extern "C" fn asdf_scene_new(
98108
blocksize: u32,
99109
buffer_blocks: u32,
100110
usleeptime: u64,
101-
) -> Option<Box<Scene>> {
102-
let filename = match CStr::from_ptr(filename).to_str() {
103-
Ok(s) => s,
104-
Err(e) => {
111+
) -> Option<Box<AsdfScene>> {
112+
let filename = CStr::from_ptr(filename)
113+
.to_str()
114+
.map_err(|e| {
105115
set_error_string(format!("Invalid filename: {}", e));
106-
return None;
107-
}
108-
};
109-
match Scene::new(
116+
})
117+
.ok()?;
118+
let inner = Scene::new(
110119
filename,
111120
samplerate,
112121
blocksize,
113122
buffer_blocks,
114123
Duration::from_micros(usleeptime),
115-
) {
116-
Ok(scene) => Some(Box::new(scene)),
117-
Err(e) => {
118-
set_error(&e);
119-
None
120-
}
121-
}
124+
)
125+
.map_err(|e| set_error(&e))
126+
.ok()?;
127+
let file_sources = inner.file_sources() as usize;
128+
Some(Box::new(AsdfScene {
129+
inner,
130+
blocksize,
131+
sos: Slice::with_capacity(file_sources),
132+
}))
122133
}
123134

124135
/// Discard a scene object created with asdf_scene_new().
125136
///
126137
/// Passing NULL is allowed.
127138
#[no_mangle]
128-
pub extern "C" fn asdf_scene_free(_: Option<Box<Scene>>) {}
139+
pub extern "C" fn asdf_scene_free(_: Option<Box<AsdfScene>>) {}
129140

130141
/// Get number of file sources.
131142
#[no_mangle]
132-
pub extern "C" fn asdf_file_sources(scene: &Scene) -> u32 {
133-
scene.file_sources()
143+
pub extern "C" fn asdf_file_sources(scene: &AsdfScene) -> u32 {
144+
scene.inner.file_sources()
134145
}
135146

136147
/// Get number of live sources.
137148
#[no_mangle]
138-
pub extern "C" fn asdf_live_sources(scene: &Scene) -> u32 {
139-
scene.live_sources()
149+
pub extern "C" fn asdf_live_sources(scene: &AsdfScene) -> u32 {
150+
scene.inner.live_sources()
140151
}
141152

142153
/// Get scene duration in frames.
143154
///
144155
/// Returns `0` if the duration is undefined.
145156
#[no_mangle]
146-
pub extern "C" fn asdf_frames(scene: &Scene) -> u64 {
147-
scene.frames().unwrap_or(0)
157+
pub extern "C" fn asdf_frames(scene: &AsdfScene) -> u64 {
158+
scene.inner.frames().unwrap_or(0)
148159
}
149160

150161
/// Get an AsdfSourceInfo object for a given (0-based) source index.
@@ -153,7 +164,7 @@ pub extern "C" fn asdf_frames(scene: &Scene) -> u64 {
153164
///
154165
/// The returned object must be discarded with asdf_sourceinfo_free().
155166
#[no_mangle]
156-
pub extern "C" fn asdf_get_sourceinfo(scene: &Scene, source_index: u32) -> Box<AsdfSourceInfo> {
167+
pub extern "C" fn asdf_get_sourceinfo(scene: &AsdfScene, source_index: u32) -> Box<AsdfSourceInfo> {
157168
Box::new(scene.get_source(source_index))
158169
}
159170

@@ -168,11 +179,11 @@ pub extern "C" fn asdf_sourceinfo_free(_: Option<Box<AsdfSourceInfo>>) {}
168179
/// This function is realtime-safe.
169180
#[no_mangle]
170181
pub extern "C" fn asdf_get_source_transform(
171-
scene: &Scene,
182+
scene: &AsdfScene,
172183
source_index: u32,
173184
frame: u64,
174185
) -> AsdfTransform {
175-
scene.get_source_transform(source_index, frame).into()
186+
scene.inner.get_source_transform(source_index, frame).into()
176187
}
177188

178189
/// Get AsdfTransform for the reference at a given frame.
@@ -181,8 +192,8 @@ pub extern "C" fn asdf_get_source_transform(
181192
///
182193
/// This function is realtime-safe.
183194
#[no_mangle]
184-
pub extern "C" fn asdf_get_reference_transform(scene: &Scene, frame: u64) -> AsdfTransform {
185-
scene.get_reference_transform(frame).into()
195+
pub extern "C" fn asdf_get_reference_transform(scene: &AsdfScene, frame: u64) -> AsdfTransform {
196+
scene.inner.get_reference_transform(frame).into()
186197
}
187198

188199
/// Seek to the given frame.
@@ -199,8 +210,8 @@ pub extern "C" fn asdf_get_reference_transform(scene: &Scene, frame: u64) -> Asd
199210
///
200211
/// This function is realtime-safe.
201212
#[no_mangle]
202-
pub extern "C" fn asdf_seek(scene: &mut Scene, frame: u64) -> bool {
203-
scene.seek(frame)
213+
pub extern "C" fn asdf_seek(scene: &mut AsdfScene, frame: u64) -> bool {
214+
scene.inner.seek(frame)
204215
}
205216

206217
/// Get a block of audio data.
@@ -214,16 +225,25 @@ pub extern "C" fn asdf_seek(scene: &mut Scene, frame: u64) -> bool {
214225
/// In case of an error, `data` will be filled with zeros
215226
/// and asdf_last_error() will contain an error description.
216227
///
217-
/// This function is realtime-safe.
228+
/// This function is realtime-safe but not re-entrant.
218229
#[no_mangle]
219230
pub unsafe extern "C" fn asdf_get_audio_data(
220-
scene: &mut Scene,
231+
scene: &mut AsdfScene,
221232
data: *const *mut f32,
222233
rolling: bool,
223234
) -> bool {
224-
assert!(!data.is_null());
225-
let data = std::slice::from_raw_parts(data, scene.file_sources() as usize);
235+
let pointers = std::slice::from_raw_parts(data, scene.inner.file_sources() as usize);
236+
let blocksize = scene.blocksize as usize;
237+
238+
// This mutably borrows `scene.sos` and is therefore not re-entrant.
239+
let data = scene.sos.from_iter_mut(
240+
pointers
241+
.iter()
242+
.map(|&ptr| std::slice::from_raw_parts_mut(ptr, blocksize)),
243+
);
244+
// This mutably borrows `scene.inner` and is therefore not re-entrant.
226245
scene
246+
.inner
227247
.get_audio_data(data, rolling)
228248
.map_err(|e| set_error(&e))
229249
.is_ok()

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,9 @@ impl Scene {
136136
/// # Safety
137137
///
138138
/// `target` must be pointing to a writable memory area of sufficient size.
139-
pub unsafe fn get_audio_data(
139+
pub fn get_audio_data(
140140
&mut self,
141-
target: &[*mut f32],
141+
target: &mut [&mut [f32]],
142142
rolling: bool,
143143
) -> Result<(), StreamingError> {
144144
self.streamer.get_data(target, rolling)

0 commit comments

Comments
 (0)