@@ -7,10 +7,26 @@ use std::fmt::{Display, Write};
7
7
use std:: time:: Duration ;
8
8
9
9
use libc:: c_char;
10
+ use rsor:: Slice ;
10
11
11
12
use crate :: transform:: { Quat , Transform , Vec3 } ;
12
13
use crate :: { Scene , Source } ;
13
14
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
+
14
30
#[ repr( C ) ]
15
31
#[ derive( Default ) ]
16
32
pub struct AsdfTransform {
@@ -76,12 +92,6 @@ impl Drop for AsdfSourceInfo {
76
92
}
77
93
}
78
94
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
-
85
95
/// Load an ASDF scene from a file.
86
96
///
87
97
/// Before starting playback (i.e. calling asdf_get_audio_data()
@@ -98,53 +108,54 @@ pub unsafe extern "C" fn asdf_scene_new(
98
108
blocksize : u32 ,
99
109
buffer_blocks : u32 ,
100
110
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| {
105
115
set_error_string ( format ! ( "Invalid filename: {}" , e) ) ;
106
- return None ;
107
- }
108
- } ;
109
- match Scene :: new (
116
+ } )
117
+ . ok ( ) ?;
118
+ let inner = Scene :: new (
110
119
filename,
111
120
samplerate,
112
121
blocksize,
113
122
buffer_blocks,
114
123
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
+ } ) )
122
133
}
123
134
124
135
/// Discard a scene object created with asdf_scene_new().
125
136
///
126
137
/// Passing NULL is allowed.
127
138
#[ no_mangle]
128
- pub extern "C" fn asdf_scene_free ( _: Option < Box < Scene > > ) { }
139
+ pub extern "C" fn asdf_scene_free ( _: Option < Box < AsdfScene > > ) { }
129
140
130
141
/// Get number of file sources.
131
142
#[ 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 ( )
134
145
}
135
146
136
147
/// Get number of live sources.
137
148
#[ 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 ( )
140
151
}
141
152
142
153
/// Get scene duration in frames.
143
154
///
144
155
/// Returns `0` if the duration is undefined.
145
156
#[ 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 )
148
159
}
149
160
150
161
/// Get an AsdfSourceInfo object for a given (0-based) source index.
@@ -153,7 +164,7 @@ pub extern "C" fn asdf_frames(scene: &Scene) -> u64 {
153
164
///
154
165
/// The returned object must be discarded with asdf_sourceinfo_free().
155
166
#[ 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 > {
157
168
Box :: new ( scene. get_source ( source_index) )
158
169
}
159
170
@@ -168,11 +179,11 @@ pub extern "C" fn asdf_sourceinfo_free(_: Option<Box<AsdfSourceInfo>>) {}
168
179
/// This function is realtime-safe.
169
180
#[ no_mangle]
170
181
pub extern "C" fn asdf_get_source_transform (
171
- scene : & Scene ,
182
+ scene : & AsdfScene ,
172
183
source_index : u32 ,
173
184
frame : u64 ,
174
185
) -> AsdfTransform {
175
- scene. get_source_transform ( source_index, frame) . into ( )
186
+ scene. inner . get_source_transform ( source_index, frame) . into ( )
176
187
}
177
188
178
189
/// Get AsdfTransform for the reference at a given frame.
@@ -181,8 +192,8 @@ pub extern "C" fn asdf_get_source_transform(
181
192
///
182
193
/// This function is realtime-safe.
183
194
#[ 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 ( )
186
197
}
187
198
188
199
/// Seek to the given frame.
@@ -199,8 +210,8 @@ pub extern "C" fn asdf_get_reference_transform(scene: &Scene, frame: u64) -> Asd
199
210
///
200
211
/// This function is realtime-safe.
201
212
#[ 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)
204
215
}
205
216
206
217
/// Get a block of audio data.
@@ -214,16 +225,25 @@ pub extern "C" fn asdf_seek(scene: &mut Scene, frame: u64) -> bool {
214
225
/// In case of an error, `data` will be filled with zeros
215
226
/// and asdf_last_error() will contain an error description.
216
227
///
217
- /// This function is realtime-safe.
228
+ /// This function is realtime-safe but not re-entrant .
218
229
#[ no_mangle]
219
230
pub unsafe extern "C" fn asdf_get_audio_data (
220
- scene : & mut Scene ,
231
+ scene : & mut AsdfScene ,
221
232
data : * const * mut f32 ,
222
233
rolling : bool ,
223
234
) -> 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.
226
245
scene
246
+ . inner
227
247
. get_audio_data ( data, rolling)
228
248
. map_err ( |e| set_error ( & e) )
229
249
. is_ok ( )
0 commit comments