micview.c
Go to the documentation of this file.
1 /*
2  * This file is part of the OpenKinect Project. http://www.openkinect.org
3  *
4  * Copyright (c) 2011 individual OpenKinect contributors. See the CONTRIB file
5  * for details.
6  *
7  * This code is licensed to you under the terms of the Apache License, version
8  * 2.0, or, at your option, the terms of the GNU General Public License,
9  * version 2.0. See the APACHE20 and GPL2 files for the text of the licenses,
10  * or the following URLs:
11  * http://www.apache.org/licenses/LICENSE-2.0
12  * http://www.gnu.org/licenses/gpl-2.0.txt
13  *
14  * If you redistribute this file in source form, modified or unmodified, you
15  * may:
16  * 1) Leave this header intact and distribute it under the same terms,
17  * accompanying it with the APACHE20 and GPL20 files, or
18  * 2) Delete the Apache 2.0 clause and accompany it with the GPL2 file, or
19  * 3) Delete the GPL v2 clause and accompany it with the APACHE20 file
20  * In all cases you must keep the copyright notice intact and include a copy
21  * of the CONTRIB file.
22  *
23  * Binary distributions must follow the binary distribution requirements of
24  * either License.
25  */
26 
27 #include "libfreenect.h"
28 #include "libfreenect_audio.h"
29 #include <stdio.h>
30 #include <string.h>
31 #include <signal.h>
32 #include <pthread.h>
33 
34 #if defined(__APPLE__)
35 #include <GLUT/glut.h>
36 #else
37 #include <GL/glut.h>
38 #endif
39 
40 pthread_t freenect_thread;
41 volatile int die = 0;
42 
45 
46 typedef struct {
47  int32_t* buffers[4];
49  int current_idx; // index to the oldest data in the buffer (equivalently, where the next new data will be placed)
50  int new_data;
51 } capture;
52 
54 
55 int paused = 0;
56 
57 pthread_mutex_t audiobuf_mutex = PTHREAD_MUTEX_INITIALIZER;
58 pthread_cond_t audiobuf_cond = PTHREAD_COND_INITIALIZER;
59 
60 int win_h, win_w;
61 
62 void in_callback(freenect_device* dev, int num_samples,
63  int32_t* mic1, int32_t* mic2,
64  int32_t* mic3, int32_t* mic4,
65  int16_t* cancelled, void *unknown) {
66  pthread_mutex_lock(&audiobuf_mutex);
67  capture* c = (capture*)freenect_get_user(dev);
68  if(num_samples < c->max_samples - c->current_idx) {
69  memcpy(&(c->buffers[0][c->current_idx]), mic1, num_samples*sizeof(int32_t));
70  memcpy(&(c->buffers[1][c->current_idx]), mic2, num_samples*sizeof(int32_t));
71  memcpy(&(c->buffers[2][c->current_idx]), mic3, num_samples*sizeof(int32_t));
72  memcpy(&(c->buffers[3][c->current_idx]), mic4, num_samples*sizeof(int32_t));
73  } else {
74  int first = c->max_samples - c->current_idx;
75  int left = num_samples - first;
76  memcpy(&(c->buffers[0][c->current_idx]), mic1, first*sizeof(int32_t));
77  memcpy(&(c->buffers[1][c->current_idx]), mic2, first*sizeof(int32_t));
78  memcpy(&(c->buffers[2][c->current_idx]), mic3, first*sizeof(int32_t));
79  memcpy(&(c->buffers[3][c->current_idx]), mic4, first*sizeof(int32_t));
80  memcpy(c->buffers[0], &mic1[first], left*sizeof(int32_t));
81  memcpy(c->buffers[1], &mic2[first], left*sizeof(int32_t));
82  memcpy(c->buffers[2], &mic3[first], left*sizeof(int32_t));
83  memcpy(c->buffers[3], &mic4[first], left*sizeof(int32_t));
84  }
85  c->current_idx = (c->current_idx + num_samples) % c->max_samples;
86  c->new_data = 1;
87  pthread_cond_signal(&audiobuf_cond);
88  pthread_mutex_unlock(&audiobuf_mutex);
89 }
90 
91 void* freenect_threadfunc(void* arg) {
92  while(!die && freenect_process_events(f_ctx) >= 0) {
93  // If we did anything else in the freenect thread, it might go here.
94  }
95  freenect_stop_audio(f_dev);
96  freenect_close_device(f_dev);
97  freenect_shutdown(f_ctx);
98  return NULL;
99 }
100 
101 void DrawMicData() {
102  if (paused)
103  return;
104  pthread_mutex_lock(&audiobuf_mutex);
105  while(!state.new_data)
106  pthread_cond_wait(&audiobuf_cond, &audiobuf_mutex);
107  state.new_data = 0;
108  // Draw:
109  glClear(GL_COLOR_BUFFER_BIT);
110  glMatrixMode(GL_MODELVIEW);
111  glLoadIdentity();
112 
113  float xIncr = (float)win_w / state.max_samples;
114  float x = 0.;
115  int i;
116  int base_idx = state.current_idx;
117 
118  // Technically, we should hold the lock until we're done actually drawing
119  // the lines, but this is sufficient to ensure that the drawings align
120  // provided we don't reallocate buffers.
121  pthread_mutex_unlock(&audiobuf_mutex);
122 
123  // This is kinda slow. It should be possible to compile each sample
124  // window into a glCallList, but that's overly complex.
125  int mic;
126  for(mic = 0; mic < 4; mic++) {
127  glBegin(GL_LINE_STRIP);
128  glColor4f(1.0f, 1.0f, 1.0f, 0.7f);
129  for(x = 0, i = 0; i < state.max_samples; i++) {
130  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);
131  x += xIncr;
132  }
133  glEnd();
134  }
135  glutSwapBuffers();
136 }
137 
138 void Reshape(int w, int h) {
139  win_w = w;
140  win_h = h;
141  glViewport(0, 0, w, h);
142  glMatrixMode(GL_PROJECTION);
143  glLoadIdentity();
144  glOrtho(0.0, (float)w, (float)h, 0.0, -1.0, 1.0);
145  glMatrixMode(GL_MODELVIEW);
146  glLoadIdentity();
147 }
148 
149 void Keyboard(unsigned char key, int x, int y) {
150  if(key == 'q') {
151  die = 1;
152  pthread_exit(NULL);
153  }
154  if(key == 32) {
155  paused = !paused;
156  }
157 }
158 
159 int main(int argc, char** argv) {
160  if (freenect_init(&f_ctx, NULL) < 0) {
161  printf("freenect_init() failed\n");
162  return 1;
163  }
166 
167  int nr_devices = freenect_num_devices (f_ctx);
168  printf ("Number of devices found: %d\n", nr_devices);
169  if (nr_devices < 1) {
170  freenect_shutdown(f_ctx);
171  return 1;
172  }
173 
174  int user_device_number = 0;
175  if (freenect_open_device(f_ctx, &f_dev, user_device_number) < 0) {
176  printf("Could not open device\n");
177  freenect_shutdown(f_ctx);
178  return 1;
179  }
180 
181  state.max_samples = 256 * 60;
182  state.current_idx = 0;
183  state.buffers[0] = malloc(state.max_samples * sizeof(int32_t));
184  state.buffers[1] = malloc(state.max_samples * sizeof(int32_t));
185  state.buffers[2] = malloc(state.max_samples * sizeof(int32_t));
186  state.buffers[3] = malloc(state.max_samples * sizeof(int32_t));
187  memset(state.buffers[0], 0, state.max_samples * sizeof(int32_t));
188  memset(state.buffers[1], 0, state.max_samples * sizeof(int32_t));
189  memset(state.buffers[2], 0, state.max_samples * sizeof(int32_t));
190  memset(state.buffers[3], 0, state.max_samples * sizeof(int32_t));
191  freenect_set_user(f_dev, &state);
192 
194  freenect_start_audio(f_dev);
195 
196  int res = pthread_create(&freenect_thread, NULL, freenect_threadfunc, NULL);
197  if (res) {
198  printf("pthread_create failed\n");
199  freenect_shutdown(f_ctx);
200  return 1;
201  }
202  printf("This is the libfreenect microphone waveform viewer. Press 'q' to quit or spacebar to pause/unpause the view.\n");
203 
204  glutInit(&argc, argv);
205  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_ALPHA );
206  glutInitWindowSize(800, 600);
207  glutInitWindowPosition(0, 0);
208  glutCreateWindow("Microphones");
209  glClearColor(0.0, 0.0, 0.0, 0.0);
210  glEnable(GL_BLEND);
211  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
212  Reshape(800, 600);
213  glutReshapeFunc(Reshape);
214  glutDisplayFunc(DrawMicData);
215  glutIdleFunc(DrawMicData);
216  glutKeyboardFunc(Keyboard);
217 
218  glutMainLoop();
219 
220  return 0;
221 }
static freenect_context * f_ctx
Definition: micview.c:43
void freenect_select_subdevices(freenect_context *ctx, freenect_device_flags subdevs)
Definition: fakenect.c:338
pthread_cond_t audiobuf_cond
Definition: micview.c:58
FREENECTAPI int freenect_stop_audio(freenect_device *dev)
Definition: audio.c:198
short int16_t
void Reshape(int w, int h)
Definition: micview.c:138
int freenect_num_devices(freenect_context *ctx)
Definition: fakenect.c:308
int freenect_shutdown(freenect_context *ctx)
Definition: fakenect.c:402
void in_callback(freenect_device *dev, int num_samples, int32_t *mic1, int32_t *mic2, int32_t *mic3, int32_t *mic4, int16_t *cancelled, void *unknown)
Definition: micview.c:62
int win_w
Definition: micview.c:60
void freenect_set_log_level(freenect_context *ctx, freenect_loglevel level)
Definition: fakenect.c:401
int win_h
Definition: micview.c:60
FREENECTAPI void freenect_set_audio_in_callback(freenect_device *dev, freenect_audio_in_cb callback)
Definition: audio.c:142
int new_data
Definition: micview.c:50
void * freenect_get_user(freenect_device *dev)
Definition: fakenect.c:360
int paused
Definition: micview.c:55
int int32_t
static freenect_device * f_dev
Definition: micview.c:44
void * freenect_threadfunc(void *arg)
Definition: micview.c:91
FREENECTAPI int freenect_start_audio(freenect_device *dev)
Definition: audio.c:149
int freenect_close_device(freenect_device *dev)
Definition: fakenect.c:406
pthread_t freenect_thread
Definition: micview.c:40
volatile int die
Definition: micview.c:41
int freenect_open_device(freenect_context *ctx, freenect_device **dev, int index)
Definition: fakenect.c:314
int max_samples
Definition: micview.c:48
int main(int argc, char **argv)
Definition: micview.c:159
void Keyboard(unsigned char key, int x, int y)
Definition: micview.c:149
capture state
Definition: micview.c:53
int32_t * buffers[4]
Definition: micview.c:47
int current_idx
Definition: micview.c:49
pthread_mutex_t audiobuf_mutex
Definition: micview.c:57
int freenect_process_events(freenect_context *ctx)
Definition: fakenect.c:140
void freenect_set_user(freenect_device *dev, void *user)
Definition: fakenect.c:355
void DrawMicData()
Definition: micview.c:101
int freenect_init(freenect_context **ctx, freenect_usb_context *usb_ctx)
Definition: fakenect.c:327


libfreenect
Author(s): Hector Martin, Josh Blake, Kyle Machulis, OpenKinect community
autogenerated on Mon Jun 10 2019 13:46:42