Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added async audio support to Python bindings and added noise cancelli…

…ng channel to micview
  • Loading branch information...
commit bb14846d7f568e1e49a191db591bcfc6659ae8b4 1 parent dbfd4ce
@MadEgg authored
View
17 examples/micview.c
@@ -40,6 +40,7 @@ static freenect_device* f_dev;
typedef struct {
int32_t* buffers[4];
+ int16_t* canc_buffers;
int max_samples;
int current_idx; // index to the oldest data in the buffer (equivalently, where the next new data will be placed)
int new_data;
@@ -65,6 +66,7 @@ void in_callback(freenect_device* dev, int num_samples,
memcpy(&(c->buffers[1][c->current_idx]), mic2, num_samples*sizeof(int32_t));
memcpy(&(c->buffers[2][c->current_idx]), mic3, num_samples*sizeof(int32_t));
memcpy(&(c->buffers[3][c->current_idx]), mic4, num_samples*sizeof(int32_t));
+ memcpy(&(c->canc_buffers[c->current_idx]), cancelled, num_samples*sizeof(int16_t));
} else {
int first = c->max_samples - c->current_idx;
int left = num_samples - first;
@@ -72,10 +74,12 @@ void in_callback(freenect_device* dev, int num_samples,
memcpy(&(c->buffers[1][c->current_idx]), mic2, first*sizeof(int32_t));
memcpy(&(c->buffers[2][c->current_idx]), mic3, first*sizeof(int32_t));
memcpy(&(c->buffers[3][c->current_idx]), mic4, first*sizeof(int32_t));
+ memcpy(&(c->canc_buffers[c->current_idx]), cancelled, first*sizeof(int16_t));
memcpy(c->buffers[0], &mic1[first], left*sizeof(int32_t));
memcpy(c->buffers[1], &mic2[first], left*sizeof(int32_t));
memcpy(c->buffers[2], &mic3[first], left*sizeof(int32_t));
memcpy(c->buffers[3], &mic4[first], left*sizeof(int32_t));
+ memcpy(c->canc_buffers, &cancelled[first], left*sizeof(int16_t));
}
c->current_idx = (c->current_idx + num_samples) % c->max_samples;
c->new_data = 1;
@@ -118,11 +122,18 @@ void DrawMicData() {
// This is kinda slow. It should be possible to compile each sample
// window into a glCallList, but that's overly complex.
int mic;
- for(mic = 0; mic < 4; mic++) {
+ for(mic = 0; mic < 5; mic++) {
glBegin(GL_LINE_STRIP);
glColor4f(1.0f, 1.0f, 1.0f, 0.7f);
for(x = 0, i = 0; i < state.max_samples; i++) {
- glVertex3f(x, ((float)win_h * (float)(2*mic + 1) / 8. ) + (float)(state.buffers[mic][(base_idx + i) % state.max_samples]) * ((float)win_h/4) /2147483647. , 0);
+ if (mic == 4)
+ {
+ glVertex3f(x, ((float)win_h * (float)(2*mic + 1) / 10. ) + (float)(state.canc_buffers[(base_idx + i) % state.max_samples]) * ((float)win_h/5) /32767. , 0);
+ }
+ else
+ {
+ glVertex3f(x, ((float)win_h * (float)(2*mic + 1) / 10. ) + (float)(state.buffers[mic][(base_idx + i) % state.max_samples]) * ((float)win_h/5) /2147483647. , 0);
+ }
x += xIncr;
}
glEnd();
@@ -176,10 +187,12 @@ int main(int argc, char** argv) {
state.buffers[1] = malloc(state.max_samples * sizeof(int32_t));
state.buffers[2] = malloc(state.max_samples * sizeof(int32_t));
state.buffers[3] = malloc(state.max_samples * sizeof(int32_t));
+ state.canc_buffers = malloc(state.max_samples * sizeof(int16_t));
memset(state.buffers[0], 0, state.max_samples * sizeof(int32_t));
memset(state.buffers[1], 0, state.max_samples * sizeof(int32_t));
memset(state.buffers[2], 0, state.max_samples * sizeof(int32_t));
memset(state.buffers[3], 0, state.max_samples * sizeof(int32_t));
+ memset(state.canc_buffers, 0, state.max_samples * sizeof(int16_t));
freenect_set_user(f_dev, &state);
freenect_set_audio_in_callback(f_dev, in_callback);
View
4,164 wrappers/python/freenect.c
2,668 additions, 1,496 deletions not shown
View
65 wrappers/python/freenect.pyx
@@ -123,6 +123,16 @@ cdef extern from "libfreenect.h":
void freenect_get_mks_accel(freenect_raw_tilt_state *state, double* x, double* y, double* z)
double freenect_get_tilt_degs(freenect_raw_tilt_state *state)
+cdef extern from "libfreenect-audio.h":
+ ctypedef void (*freenect_audio_in_cb)(void *dev, int num_samples, int *mic1, int *mic2, int *mic3, int *mic4, short *cancelled, void *unknown)
+ void freenect_set_audio_in_callback(void *dev, freenect_audio_in_cb callback)
+ int freenect_start_audio(void* dev)
+ int freenect_stop_audio(void* dev)
+
+cdef extern from "tools.h":
+ char *convertShortToChar(short *)
+ char *convertIntToChar(int *)
+
cdef class DevPtr:
cdef void* _ptr
def __repr__(self):
@@ -238,7 +248,7 @@ cdef init():
# to both but haven't wrapped the python API for selecting subdevices yet.
# Also, we don't support audio in the python wrapper yet, so no sense claiming
# the device.
- freenect_select_subdevices(ctx, DEVICE_MOTOR | DEVICE_CAMERA)
+ freenect_select_subdevices(ctx, DEVICE_MOTOR | DEVICE_CAMERA | DEVICE_AUDIO)
cdef CtxPtr ctx_out
ctx_out = CtxPtr()
ctx_out._ptr = ctx
@@ -253,7 +263,7 @@ cdef open_device(CtxPtr ctx, int index):
dev_out._ptr = dev
return dev_out
-_depth_cb, _video_cb = None, None
+_depth_cb, _video_cb, _audio_cb = None, None, None
cdef void depth_cb(void *dev, char *data, int timestamp):
nbytes = 614400 # 480 * 640 * 2
@@ -271,12 +281,36 @@ cdef void video_cb(void *dev, char *data, int timestamp):
if _video_cb:
_video_cb(*_video_cb_np(dev_out, PyString_FromStringAndSize(data, nbytes), timestamp))
+cdef void audio_cb(void *dev, int num_samples, int *mic1, int *mic2, int *mic3, int *mic4, short *cancelled, void *unknown):
+ cdef DevPtr dev_out
+ cdef char *mic1_c
+ cdef char *mic2_c
+ cdef char *mic3_c
+ cdef char *mic4_c
+ cdef char *cancelled_c
+ cdef int i
+ nbytes_mic = num_samples * 4
+ nbytes_cancelled = num_samples * 2
+ dev_out = DevPtr()
+ dev_out._ptr = dev
+ if _audio_cb:
+ mic1_c = convertIntToChar(mic1)
+ mic2_c = convertIntToChar(mic2)
+ mic3_c = convertIntToChar(mic3)
+ mic4_c = convertIntToChar(mic4)
+ cancelled_c = convertShortToChar(cancelled)
+ _audio_cb(*_audio_cb_np(dev_out,
+ PyString_FromStringAndSize(mic1_c, nbytes_mic),
+ PyString_FromStringAndSize(mic2_c, nbytes_mic),
+ PyString_FromStringAndSize(mic3_c, nbytes_mic),
+ PyString_FromStringAndSize(mic4_c, nbytes_mic),
+ PyString_FromStringAndSize(cancelled_c, nbytes_cancelled)))
class Kill(Exception):
"""This kills the runloop, raise from the body only"""
-def runloop(depth=None, video=None, body=None):
+def runloop(depth=None, video=None, audio=None, body=None):
"""Sets up the kinect and maintains a runloop
This is where most of the action happens. You can get the dev pointer from the callback
@@ -290,11 +324,13 @@ def runloop(depth=None, video=None, body=None):
If None (default), then you won't get a callback for video.
body: A function that takes (dev, ctx) and is called in the body of process_events
"""
- global _depth_cb, _video_cb
+ global _depth_cb, _video_cb, _audio_cb
if depth:
_depth_cb = depth
if video:
_video_cb = video
+ if audio:
+ _audio_cb = audio
cdef DevPtr dev
cdef CtxPtr ctx
cdef void* devp
@@ -315,6 +351,8 @@ def runloop(depth=None, video=None, body=None):
freenect_start_video(devp)
freenect_set_depth_callback(devp, depth_cb)
freenect_set_video_callback(devp, video_cb)
+ freenect_start_audio(devp)
+ freenect_set_audio_in_callback(devp, audio_cb)
try:
while freenect_process_events(ctxp) >= 0:
if body:
@@ -323,6 +361,7 @@ def runloop(depth=None, video=None, body=None):
pass
freenect_stop_depth(devp)
freenect_stop_video(devp)
+ freenect_stop_audio(devp)
freenect_close_device(devp)
freenect_shutdown(ctxp)
@@ -357,6 +396,24 @@ def _video_cb_np(dev, string, timestamp):
data.resize((480, 640, 3))
return dev, data, timestamp
+def _audio_cb_np(dev, mic1, mic2, mic3, mic4, cancelled):
+ """Converts the raw audio data into a numpy array for your function
+
+ Args:
+ dev: DevPtr object
+ string: A python string with the video data
+ timestamp: An int representing the time
+
+ Returns:
+ (dev, data, timestamp) where data is a 2D numpy array
+ """
+ mic1_np = np.fromstring(mic1, dtype=np.int32)
+ mic2_np = np.fromstring(mic2, dtype=np.int32)
+ mic3_np = np.fromstring(mic3, dtype=np.int32)
+ mic4_np = np.fromstring(mic4, dtype=np.int32)
+ cancelled_np = np.fromstring(cancelled, dtype=np.int16)
+ return dev, mic1_np, mic2_np, mic3_np, mic4_np, cancelled_np
+
import_array()
def sync_get_depth(index=0, format=DEPTH_11BIT):
View
12 wrappers/python/tools.h
@@ -0,0 +1,12 @@
+#ifndef __FREENECT_TOOLS_
+#define __FREENECT_TOOLS_
+char *convertShortToChar(short *array)
+{
+ return (char *)(array);
+}
+
+char *convertIntToChar(int *array)
+{
+ return (char *)(array);
+}
+#endif
Please sign in to comment.
Something went wrong with that request. Please try again.