Skip to content

Commit 708149a

Browse files
committed
Also added audio out callback, even though the C function does not call it (yet) (see src/audio.c:36)
1 parent bdda0c9 commit 708149a

File tree

1 file changed

+67
-7
lines changed

1 file changed

+67
-7
lines changed

wrappers/python/freenect.pyx

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,12 @@ cdef extern from "numpy/arrayobject.h":
7777

7878
cdef extern from "stdlib.h":
7979
void free(void *ptr)
80+
void *memcpy(void *str1, void *str2, unsigned int n)
81+
void *memset(void *str1, int c, unsigned int n)
8082

8183
cdef extern from "Python.h":
8284
object PyString_FromStringAndSize(char *s, Py_ssize_t len)
85+
char *PyString_AsString(object str)
8386

8487
cdef extern from "libfreenect_sync.h":
8588
int freenect_sync_get_video(void **video, unsigned int *timestamp, int index, int fmt) nogil
@@ -124,8 +127,19 @@ cdef extern from "libfreenect.h":
124127
double freenect_get_tilt_degs(freenect_raw_tilt_state *state)
125128

126129
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+
127138
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+
128141
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)
129143
int freenect_start_audio(void* dev)
130144
int freenect_stop_audio(void* dev)
131145

@@ -242,8 +256,6 @@ cdef init():
242256
return
243257
# We take both the motor and camera devices here, since we provide access
244258
# 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.
247259
freenect_select_subdevices(ctx, DEVICE_MOTOR | DEVICE_CAMERA | DEVICE_AUDIO)
248260
cdef CtxPtr ctx_out
249261
ctx_out = CtxPtr()
@@ -259,7 +271,7 @@ cdef open_device(CtxPtr ctx, int index):
259271
dev_out._ptr = dev
260272
return dev_out
261273

262-
_depth_cb, _video_cb, _audio_cb = None, None, None
274+
_depth_cb, _video_cb, _audio_cb, _audio_out_cb = None, None, None, None
263275

264276
cdef void depth_cb(void *dev, char *data, int timestamp):
265277
nbytes = 614400 # 480 * 640 * 2
@@ -302,11 +314,50 @@ cdef void audio_cb(void *dev, int num_samples, int *mic1, int *mic2, int *mic3,
302314
PyString_FromStringAndSize(mic4_c, nbytes_mic),
303315
PyString_FromStringAndSize(cancelled_c, nbytes_cancelled)))
304316

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+
305356
class Kill(Exception):
306357
"""This kills the runloop, raise from the body only"""
307358

308359

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):
310361
"""Sets up the kinect and maintains a runloop
311362
312363
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):
318369
If None (default), then you won't get a callback for depth.
319370
video: A function that takes (dev, video, timestamp), corresponding to C function.
320371
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)
321378
body: A function that takes (dev, ctx) and is called in the body of process_events
322379
"""
323380
global _depth_cb, _video_cb, _audio_cb
324381
if depth:
325-
_depth_cb = depth
382+
_depth_cb = depth
326383
if video:
327-
_video_cb = video
384+
_video_cb = video
328385
if audio:
329-
_audio_cb = audio
386+
_audio_cb = audio
387+
if audio_out:
388+
_audio_out_cb = audio_out
330389
cdef DevPtr dev
331390
cdef CtxPtr ctx
332391
cdef void* devp
@@ -349,6 +408,7 @@ def runloop(depth=None, video=None, audio=None, body=None):
349408
freenect_set_video_callback(devp, video_cb)
350409
freenect_start_audio(devp)
351410
freenect_set_audio_in_callback(devp, audio_cb)
411+
freenect_set_audio_out_callback(devp, audio_out_cb)
352412
try:
353413
while freenect_process_events(ctxp) >= 0:
354414
if body:

0 commit comments

Comments
 (0)