@@ -77,9 +77,12 @@ cdef extern from "numpy/arrayobject.h":
77
77
78
78
cdef extern from "stdlib.h" :
79
79
void free (void * ptr )
80
+ void * memcpy (void * str1 , void * str2 , unsigned int n )
81
+ void * memset (void * str1 , int c , unsigned int n )
80
82
81
83
cdef extern from "Python.h" :
82
84
object PyString_FromStringAndSize (char * s , Py_ssize_t len )
85
+ char * PyString_AsString (object str )
83
86
84
87
cdef extern from "libfreenect_sync.h" :
85
88
int freenect_sync_get_video (void ** video , unsigned int * timestamp , int index , int fmt ) nogil
@@ -124,8 +127,19 @@ cdef extern from "libfreenect.h":
124
127
double freenect_get_tilt_degs (freenect_raw_tilt_state * state )
125
128
126
129
cdef extern from "libfreenect-audio.h" :
130
+ ctypedef struct freenect_sample_51 :
131
+ short left
132
+ short right
133
+ short center
134
+ short lfe
135
+ short surround_left
136
+ short surround_right
137
+
127
138
ctypedef void (* freenect_audio_in_cb )(void * dev , int num_samples , int * mic1 , int * mic2 , int * mic3 , int * mic4 , short * cancelled , void * unknown )
139
+ ctypedef void (* freenect_audio_out_cb )(void * dev , freenect_sample_51 * samples , int * sample_count )
140
+
128
141
void freenect_set_audio_in_callback (void * dev , freenect_audio_in_cb callback )
142
+ void freenect_set_audio_out_callback (void * dev , freenect_audio_out_cb callback )
129
143
int freenect_start_audio (void * dev )
130
144
int freenect_stop_audio (void * dev )
131
145
@@ -242,8 +256,6 @@ cdef init():
242
256
return
243
257
# We take both the motor and camera devices here, since we provide access
244
258
# to both but haven't wrapped the python API for selecting subdevices yet.
245
- # Also, we don't support audio in the python wrapper yet, so no sense claiming
246
- # the device.
247
259
freenect_select_subdevices (ctx , DEVICE_MOTOR | DEVICE_CAMERA | DEVICE_AUDIO )
248
260
cdef CtxPtr ctx_out
249
261
ctx_out = CtxPtr ()
@@ -259,7 +271,7 @@ cdef open_device(CtxPtr ctx, int index):
259
271
dev_out ._ptr = dev
260
272
return dev_out
261
273
262
- _depth_cb , _video_cb , _audio_cb = None , None , None
274
+ _depth_cb , _video_cb , _audio_cb , _audio_out_cb = None , None , None , None
263
275
264
276
cdef void depth_cb (void * dev , char * data , int timestamp ):
265
277
nbytes = 614400 # 480 * 640 * 2
@@ -302,11 +314,50 @@ cdef void audio_cb(void *dev, int num_samples, int *mic1, int *mic2, int *mic3,
302
314
PyString_FromStringAndSize (mic4_c , nbytes_mic ),
303
315
PyString_FromStringAndSize (cancelled_c , nbytes_cancelled )))
304
316
317
+ cdef void audio_out_cb (void * dev , freenect_sample_51 * samples , int * sample_count ):
318
+ cdef num_samples = sample_count [0 ]
319
+ cdef char * c_data
320
+ cdef int numbytes = 6 * 2 * num_samples # channels * sample_size * num_samples
321
+ cdef int diff
322
+ if _audio_out_cb :
323
+ dev_out = DevPtr ()
324
+ dev_out ._ptr = dev
325
+
326
+ left , right , center , lfe , sur_l , sur_r = _audio_out_cb (dev_out , num_samples )
327
+
328
+ # Make sure not too many samples are supplied and that
329
+ # an equal number of samples is supplied for each channel
330
+ assert (len (left ) <= num_samples )
331
+ assert (len (left ) == len (right ))
332
+ assert (len (left ) == len (center ))
333
+ assert (len (left ) == len (lfe ))
334
+ assert (len (left ) == len (sur_l ))
335
+ assert (len (left ) == len (sur_r ))
336
+ # Make sure the total number of samples is supplied, if not,
337
+ # extend with zeros
338
+ if (len (left ) < num_samples ):
339
+ diff = num_samples - len (left )
340
+ zeros = np .zeros (diff )
341
+ left = np .append (left , zeros )
342
+ right = np .append (left , zeros )
343
+ center = np .append (left , zeros )
344
+ lfe = np .append (left , zeros )
345
+ sur_l = np .append (left , zeros )
346
+ sur_r = np .append (left , zeros )
347
+ # Format data and copy to the right location
348
+ data = np .column_stack ((left , right , center , lfe , sur_l , sur_r )).astype ('int16' ).tostring ()
349
+ assert (len (data ) == numbytes )
350
+ c_data = PyString_AsString (data )
351
+ memcpy (samples , c_data , numbytes )
352
+ else :
353
+ # Send silence
354
+ memset (samples , 0 , numbytes )
355
+
305
356
class Kill (Exception ):
306
357
"""This kills the runloop, raise from the body only"""
307
358
308
359
309
- def runloop (depth = None , video = None , audio = None , body = None ):
360
+ def runloop (depth = None , video = None , audio = None , audio_out = None , body = None ):
310
361
"""Sets up the kinect and maintains a runloop
311
362
312
363
This is where most of the action happens. You can get the dev pointer from the callback
@@ -318,15 +369,23 @@ def runloop(depth=None, video=None, audio=None, body=None):
318
369
If None (default), then you won't get a callback for depth.
319
370
video: A function that takes (dev, video, timestamp), corresponding to C function.
320
371
If None (default), then you won't get a callback for video.
372
+ audio: A function that takes (dev, mic1, mic2, mic3, mic4, cancelled), corresponding to C function.
373
+ If None (default), then you won't get a callback for incoming audio.
374
+ audio_out: A function that takes (dev, num_samples), corresponding to C function.
375
+ If None (default), then you won't get a callback for outgoing audio.
376
+ If not None, you still will not get a callback because the C code
377
+ does not actually call the callback function yet. (see src/audio.c:36)
321
378
body: A function that takes (dev, ctx) and is called in the body of process_events
322
379
"""
323
380
global _depth_cb , _video_cb , _audio_cb
324
381
if depth :
325
- _depth_cb = depth
382
+ _depth_cb = depth
326
383
if video :
327
- _video_cb = video
384
+ _video_cb = video
328
385
if audio :
329
- _audio_cb = audio
386
+ _audio_cb = audio
387
+ if audio_out :
388
+ _audio_out_cb = audio_out
330
389
cdef DevPtr dev
331
390
cdef CtxPtr ctx
332
391
cdef void * devp
@@ -349,6 +408,7 @@ def runloop(depth=None, video=None, audio=None, body=None):
349
408
freenect_set_video_callback (devp , video_cb )
350
409
freenect_start_audio (devp )
351
410
freenect_set_audio_in_callback (devp , audio_cb )
411
+ freenect_set_audio_out_callback (devp , audio_out_cb )
352
412
try :
353
413
while freenect_process_events (ctxp ) >= 0 :
354
414
if body :
0 commit comments