@@ -7,10 +7,26 @@ use std::fmt::{Display, Write};
77use std:: time:: Duration ;
88
99use libc:: c_char;
10+ use rsor:: Slice ;
1011
1112use crate :: transform:: { Quat , Transform , Vec3 } ;
1213use 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 ) ]
1632pub 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]
170181pub 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]
219230pub 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 ( )
0 commit comments