view record.c @ 28:1fc162d84343

updated README
author Robert McIntyre <rlm@mit.edu>
date Sat, 19 Nov 2011 20:09:50 -0700
parents f9476ff7637e
children
line wrap: on
line source
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 2010 by Chris Robinson
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
19 */
21 #include "config.h"
22 #include <stdlib.h>
23 #include "alMain.h"
24 #include "AL/al.h"
25 #include "AL/alc.h"
26 #include "alSource.h"
27 #include <jni.h>
30 typedef struct record_data {
31 volatile int killNow;
32 ALvoid *thread;
33 ALuint robert;
35 ALvoid *mainBuffer;
36 ALvoid *auxBuffer;
37 ALuint size;
39 ALuint *unPauseIDs;
40 int unPauseCount;
41 ALboolean mainFull;
42 ALboolean auxFull;
43 ALboolean auxReady;
44 ALboolean mainReady;
46 } record_data;
51 #define UNUSED(x) (void)(x)
52 #define RUNONLY(n) \
53 {static int __runonce = n; \
54 if (__runonce-- <= 0){return;}}
56 #define RUNAT(n) \
57 {static int __runat = n; \
58 if (0 != __runat--){return;}}
60 /// al error handling code prototypes
62 char* GetALErrorString(ALenum err);
63 char* GetALCErrorString(ALenum err);
64 void printError(void);
65 void init(ALCdevice *);
66 void init2(ALCdevice *);
67 void later(ALCdevice *);
68 void every(ALCdevice *);
69 void every2(ALCdevice *);
70 void step(ALCdevice *);
73 //synchronization
74 struct record_data;
75 void syncContexts(ALCcontext *, ALCcontext *);
76 void syncSources(ALsource *, ALsource *, ALCcontext *, ALCcontext *);
77 void pauseMainContext(struct record_data *);
78 void unPauseMainContext(struct record_data *);
79 void pauseAllSources(ALCcontext *);
80 static void saveAux(ALCdevice *);
81 static void swapInAux(ALCdevice *);
82 static void saveMain(ALCdevice *);
83 static void swapInMain(ALCdevice *);
84 void aux_alListenerf(ALenum param, ALfloat value);
85 void aux_alListener3f(ALenum param, ALfloat v1, ALfloat v2, ALfloat v3);
88 //////////////
92 // remove all the sources from all the auxContexts
93 // take the mainContext and for each context, COPY
94 // the sources from the main context.
96 // render each context and make their data available.
98 // =alGenSources= (and =alGetError=)
99 // attach each source to the shared buffer using =alSourcei=
102 // need to make sure in the AudioRender class that we don't do
103 // anything to sources while the audio is being rendered, so make sure
104 // to maintain an "isDone" state as well.
106 // Special device which allows simulation of multiple listeners
107 // hearing the same set of sources. Provides access to the rendered
108 // data for each listener. Designed to work with LWJGL.
110 // first, the mainContext is the only context that is controlled by
111 // LWJGL.
113 // One context will be created for each listener that we want.
115 // Then, at the start of each render loop, first PAUSE the sources on
116 // all other contexts except the mainContext (this takes care of
117 // sources in the mainContext being shut down.)
118 // we will iterate through all
119 // the active sources in our mainContext (the one which is controlled
120 // through LWJGL), and take their sourceIDs. For each of these IDs
121 // and for each other context, we'll check some internal structure to
122 // see if we've already created a corresponding source. If that
123 // source exits, we will SYNCH it with the source which belongs to the
124 // mainContext. If it DOESN'T exist, we will CLONE the source from the
125 // main context and establish it in the other context.
127 // Each render loop consists of noting all of the active sources in
128 // the mainContext and storing their IDs. Then, for each context,
129 // the correspondig sources to the active sources in the mainContext
130 // will be set to PLAY, and all sources in all other contexts will be
131 // set to PAUSE. aluMixData will be called for each context in this
132 // way.
134 // approved by KittyCat
137 // CAN get id appropiate for us in the sorce-repated openal functions
138 // by quering *source->source
140 // first, do it with only two listeners, two contexts, automatically
141 // created.
143 static ALCcontext* mainContext = NULL;
144 static ALCcontext* auxContext = NULL;
147 void aux_alListenerf(ALenum param, ALfloat value){
148 ALCcontext *current = alcGetCurrentContext();
149 alcMakeContextCurrent(auxContext);
150 alListenerf(param, value);
151 alcMakeContextCurrent(current);
152 }
154 void aux_alListener3f(ALenum param, ALfloat v1, ALfloat v2, ALfloat v3){
155 ALCcontext *current = alcGetCurrentContext();
156 alcMakeContextCurrent(auxContext);
157 alListener3f(param, v1, v2, v3);
158 alcMakeContextCurrent(current);
159 }
163 void pauseAllSources(ALCcontext *ctx){
164 ALCcontext *current = alcGetCurrentContext();
165 alcMakeContextCurrent(ctx);
166 ALsource **src, **src_end;
167 src = ctx->ActiveSources;
168 src_end = src + ctx->ActiveSourceCount;
169 while(src != src_end){
170 if (AL_PLAYING == (*src)->state){
171 //if (AL_TRUE){
172 ALuint source_id = (*src)->source;
173 //printf("pausing ONE source\n");
174 alSourcePause(source_id);
175 }
176 src++;
177 }
178 alcMakeContextCurrent(current);
179 }
182 void init2(ALCdevice *Device){
183 UNUSED(Device);
184 RUNONLY(1)
185 // the mainContext only ever has a FIXED number of sources!
186 // duplicate them ALL into auxContext!
187 alcMakeContextCurrent(auxContext);{
188 UIntMap source_map= mainContext->SourceMap;
189 ALuint num_sources = source_map.size;
190 ALuint newSources[num_sources];
191 alGenSources(num_sources, newSources);}
192 alcMakeContextCurrent(mainContext);
195 }
199 /*
200 void syncSourcei(ALuint sourceID1, ALuint sourceID2,
201 ALCcontext *ctx1, ALCcontext *ctx2,
202 int numParams, ALenum *params){
203 ALint values[numParams];
204 ALCcontext current = alcGetCurrentContext();
205 // get values
206 printf("getting values from source1\n");
207 alcMakeContextCurrent(ctx1);
208 int i;
209 for(i=0; i<numParams; i++){
210 alGetSourcei(sourceID1, params[i], values+i);
211 printf("value is %d\n", values[i]);
212 printError();
213 }
214 // set values
215 printf("setting values of source2\n");
216 alcMakeContextCurrent(ctx2);
217 for (i=0; i<numParams; i++){
218 alSourcei(sourceID2, params[i], values[i]);
219 printError();
220 }
221 alcMakeContextCurrent(current);
222 printError();
223 }
224 */
227 #define _MAKE_SYNC(NAME, INIT_EXPR, GET_EXPR, SET_EXPR) \
228 void NAME (ALuint sourceID1, ALuint sourceID2, \
229 ALCcontext *ctx1, ALCcontext *ctx2, \
230 ALenum param){ \
231 INIT_EXPR; \
232 ALCcontext *current = alcGetCurrentContext(); \
233 alcMakeContextCurrent(ctx1); \
234 GET_EXPR; \
235 /*printError();*/ \
236 alcMakeContextCurrent(ctx2); \
237 SET_EXPR; \
238 /*printError();*/ \
239 alcMakeContextCurrent(current); \
240 }
242 #define MAKE_SYNC(NAME, TYPE, GET, SET) \
243 _MAKE_SYNC(NAME, \
244 TYPE value, \
245 GET(sourceID1, param, &value), \
246 SET(sourceID2, param, value))
248 #define MAKE_SYNC3(NAME, TYPE, GET, SET) \
249 _MAKE_SYNC(NAME, \
250 TYPE value1; TYPE value2; TYPE value3;, \
251 GET(sourceID1, param, &value1, &value2, &value3), \
252 SET(sourceID2, param, value1, value2, value3))
254 MAKE_SYNC( syncSourcei, ALint, alGetSourcei, alSourcei);
255 MAKE_SYNC( syncSourcef, ALfloat, alGetSourcef, alSourcef);
256 MAKE_SYNC3(syncSource3i, ALint, alGetSource3i, alSource3i);
257 MAKE_SYNC3(syncSource3f, ALfloat, alGetSource3f, alSource3f);
264 #define DsyncSourcei(sourceID1, sourceID2, ctx1, ctx2, param) \
265 {/*printf("synci : " #param "\n");*/ \
266 syncSourcei(sourceID1, sourceID2, ctx1, ctx2, param);}
268 #define DsyncSourcef(sourceID1, sourceID2, ctx1, ctx2, param) \
269 {/*printf("syncf : " #param "\n");*/ \
270 syncSourcef(sourceID1, sourceID2, ctx1, ctx2, param);}
272 #define DsyncSource3i(sourceID1, sourceID2, ctx1, ctx2, param) \
273 {/*printf("sync3i : " #param "\n");*/ \
274 syncSource3i(sourceID1, sourceID2, ctx1, ctx2, param);}
276 #define DsyncSource3f(sourceID1, sourceID2, ctx1, ctx2, param) \
277 {/*printf("sync3f : " #param "\n");*/ \
278 syncSource3f(sourceID1, sourceID2, ctx1, ctx2, param);}
280 void printValid(ALuint sourceID){
281 alcMakeContextCurrent(auxContext);
282 printf("source%d : %s\n", sourceID, alIsSource(sourceID) ? "VALID" : "INVALID");
283 alcMakeContextCurrent(mainContext);
284 }
288 void syncSources(ALsource *source1, ALsource *source2,
289 ALCcontext *ctx1, ALCcontext *ctx2){
291 ALuint ID1 = source1->source;
292 ALuint ID2 = source2->source;
293 ALCcontext *current = alcGetCurrentContext();
294 //printf("***************\n");
295 //printf("SYNCHING source %d with source %d\n", ID1, ID2);
297 DsyncSourcef(ID1,ID2,ctx1,ctx2,AL_PITCH);
298 DsyncSourcef(ID1,ID2,ctx1,ctx2,AL_GAIN);
299 DsyncSourcef(ID1,ID2,ctx1,ctx2,AL_MAX_DISTANCE);
300 DsyncSourcef(ID1,ID2,ctx1,ctx2,AL_ROLLOFF_FACTOR);
301 DsyncSourcef(ID1,ID2,ctx1,ctx2,AL_REFERENCE_DISTANCE);
302 DsyncSourcef(ID1,ID2,ctx1,ctx2,AL_MIN_GAIN);
303 DsyncSourcef(ID1,ID2,ctx1,ctx2,AL_MAX_GAIN);
304 DsyncSourcef(ID1,ID2,ctx1,ctx2,AL_CONE_OUTER_GAIN);
305 DsyncSourcef(ID1,ID2,ctx1,ctx2,AL_CONE_INNER_ANGLE);
306 DsyncSourcef(ID1,ID2,ctx1,ctx2,AL_CONE_OUTER_ANGLE);
307 DsyncSourcef(ID1,ID2,ctx1,ctx2,AL_SEC_OFFSET);
308 DsyncSourcef(ID1,ID2,ctx1,ctx2,AL_SAMPLE_OFFSET);
309 DsyncSourcef(ID1,ID2,ctx1,ctx2,AL_BYTE_OFFSET);
311 DsyncSource3f(ID1,ID2,ctx1,ctx2,AL_POSITION);
312 DsyncSource3f(ID1,ID2,ctx1,ctx2,AL_VELOCITY);
313 DsyncSource3f(ID1,ID2,ctx1,ctx2,AL_DIRECTION);
315 DsyncSourcei(ID1,ID2,ctx1,ctx2,AL_SOURCE_RELATIVE);
316 DsyncSourcei(ID1,ID2,ctx1,ctx2,AL_LOOPING);
322 // first, copy buffer patterns over.
324 //source2->lSourceType = source1->lSourceType;
325 //source2->NumChannels = source1->NumChannels;
326 //source2->SampleSize = source1->SampleSize;
327 //source2->Buffer = source1->Buffer;
328 // source2->queue = source1->queue;
329 // source2->BuffersInQueue = source1-> BuffersInQueue;
330 // source2->BuffersPlayed = source1 -> BuffersPlayed;
332 // then, duplicate the state.
334 // handle static sources
335 //printf("handling Buffers\n");
336 alcMakeContextCurrent(ctx1);
337 ALint source_type;
338 alGetSourcei(ID1, AL_SOURCE_TYPE, &source_type);
339 //printError();
341 if (AL_STATIC == source_type){
342 //printf("setting STATIC source\n");
343 ALint buffer_id1;
344 ALint buffer_id2;
345 alGetSourcei(ID1, AL_BUFFER, &buffer_id1);
346 alcMakeContextCurrent(ctx2);
347 alGetSourcei(ID2, AL_BUFFER, &buffer_id2);
348 if (buffer_id1 != buffer_id2){
349 //printf("setting source2's buffer from %d to %d\n", buffer_id2, buffer_id1);
350 alSourcei(ID2, AL_BUFFER, buffer_id1);
351 //printError();
352 }
353 else {
354 //printf("Buffers are already the same, doing nothing.\n");
355 }
356 }
357 else {
358 // printf("not a static source!\n");
359 }
366 alcMakeContextCurrent(ctx2);
371 //printf("setting STATE\n");
372 alcMakeContextCurrent(ctx1);
373 ALint state1;
374 alGetSourcei(ID1, AL_SOURCE_STATE, &state1);
375 //printError();
377 alcMakeContextCurrent(ctx2);
378 ALint state2;
379 alGetSourcei(ID2, AL_SOURCE_STATE, &state2);
380 //printError();
381 if (state1 != state2){
382 switch (state1){
383 case AL_INITIAL : /*printf("INITIAL\n")*/;alSourceRewind(ID2);break;
384 case AL_PLAYING : /*printf("PLAYING\n")*/;alSourcePlay(ID2);break;
385 case AL_PAUSED : /*printf("PAUSED\n")*/;alSourcePause(ID2);break;
386 case AL_STOPPED : /*printf("STOPPED\n")*/;alSourceStop(ID2);break;
387 }
388 }
389 //printError();
393 alcMakeContextCurrent(current);
395 }
398 void syncContexts(ALCcontext *ctx1, ALCcontext *ctx2){
399 // if there aren't sufficient sources in ctx2 to mirror the sources
400 // in ctx1, create them.
401 ALCcontext *current = alcGetCurrentContext();
403 UIntMap *sourceMap1 = &(ctx1->SourceMap);
404 UIntMap *sourceMap2 = &(ctx2->SourceMap);
407 ALuint sources1 = sourceMap1->size;
408 ALuint sources2 = sourceMap2->size;
410 //printf("ctx1 has %d sources; ctx2 has %d sources\n", sources1, sources2);
412 alcMakeContextCurrent(ctx2);
413 if (sources2 < sources1){
414 ALuint numSources = sources1 - sources2;
415 ALuint newSources[numSources];
416 alGenSources(numSources, newSources);
417 printf("adjusting...\n");
418 printf("now ctx1 has %d sources; ctx2 has %d sources\n",
419 sourceMap1->size, sourceMap2->size);
420 }
421 //printError();
424 alcMakeContextCurrent(current);
427 // after this, ctx2 is gauranteed to have at least as many sources
428 // as ctx1. Now, sync each source from ctx1 to the corresponding
429 // source in ctx2.
431 int i;
435 for(i = 0; i < sourceMap1->size; i++){
436 syncSources((ALsource*)sourceMap1->array[i].value,
437 (ALsource*)sourceMap2->array[i].value,
438 ctx1, ctx2);
439 }
445 }
449 void pauseMainContext(record_data *data){
450 //printf("pausing MainContext\n");
451 data->unPauseCount = 0;
452 data->unPauseIDs =
453 (ALuint*)realloc(data->unPauseIDs,
454 sizeof(ALuint) * mainContext->ActiveSourceCount);
456 ALsource **src, **src_end;
457 src = mainContext->ActiveSources;
458 src_end = src + mainContext->ActiveSourceCount;
460 while(src != src_end){
462 if (AL_PLAYING == (*src)->state){
463 ALuint source_id = (*src)->source;
464 data->unPauseIDs[data->unPauseCount++] = source_id;
465 alSourcePause(source_id);
466 }
467 src++;
468 }
469 }
474 void unPauseMainContext(record_data *data){
475 int i;
476 for(i=0;i<data->unPauseCount;i++){
477 alSourcePlay(data->unPauseIDs[i]);
478 }
479 }
482 // a device brings along with it multiple pieces of state
483 // which have to be swapped in and out with each context.
485 //static ALfloat DryBufferMain[BUFFERSIZE][MAXCHANNELS];
486 //static ALfloat DryBufferAux[BUFFERSIZE][MAXCHANNELS];
487 //static ALfloat PanningLUTMain[LUT_NUM][MAXCHANNELS];
488 //static ALfloat PanningLUTAux[LUT_NUM][MAXCHANNELS];
489 static ALfloat ClickRemovalMain[MAXCHANNELS];
490 static ALfloat ClickRemovalAux[MAXCHANNELS];
491 static ALfloat PendingClicksMain[MAXCHANNELS];
492 static ALfloat PendingClicksAux[MAXCHANNELS];
496 static void saveAux(ALCdevice *Device){
497 //memcpy(DryBufferAux, Device->DryBuffer, sizeof(ALfloat)*BUFFERSIZE*MAXCHANNELS);
498 //memcpy(PanningLUTAux, Device->PanningLUT, sizeof(ALfloat)*LUT_NUM*MAXCHANNELS);
499 memcpy(ClickRemovalAux, Device->ClickRemoval, sizeof(ALfloat)*MAXCHANNELS);
500 memcpy(PendingClicksAux, Device->PendingClicks, sizeof(ALfloat)*MAXCHANNELS);
501 }
502 static void swapInAux(ALCdevice *Device){
503 //memcpy(Device->DryBuffer, DryBufferAux, sizeof(ALfloat)*BUFFERSIZE*MAXCHANNELS);
504 //memcpy(Device->PanningLUT, PanningLUTAux, sizeof(ALfloat)*LUT_NUM*MAXCHANNELS);
505 memcpy(Device->ClickRemoval, ClickRemovalAux, sizeof(ALfloat)*MAXCHANNELS);
506 memcpy(Device->PendingClicks, PendingClicksAux, sizeof(ALfloat)*MAXCHANNELS);
507 }
510 static void saveMain(ALCdevice *Device){
511 //memcpy(DryBufferMain, Device->DryBuffer, sizeof(ALfloat)*BUFFERSIZE*MAXCHANNELS);
512 //memcpy(PanningLUTMain, Device->PanningLUT, sizeof(ALfloat)*LUT_NUM*MAXCHANNELS);
513 memcpy(ClickRemovalMain, Device->ClickRemoval, sizeof(ALfloat)*MAXCHANNELS);
514 memcpy(PendingClicksMain, Device->PendingClicks, sizeof(ALfloat)*MAXCHANNELS);
515 }
516 static void swapInMain(ALCdevice *Device){
517 //memcpy(Device->DryBuffer, DryBufferMain, sizeof(ALfloat)*BUFFERSIZE*MAXCHANNELS);
518 //memcpy(Device->PanningLUT, PanningLUTMain, sizeof(ALfloat)*LUT_NUM*MAXCHANNELS);
519 memcpy(Device->ClickRemoval, ClickRemovalMain, sizeof(ALfloat)*MAXCHANNELS);
520 memcpy(Device->PendingClicks, PendingClicksMain, sizeof(ALfloat)*MAXCHANNELS);
521 }
524 static ALCcontext **currentContext;
525 static ALuint currentNumContext;
526 static void unLimitContext(ALCdevice *Device){
527 Device->Contexts = currentContext;
528 Device->NumContexts = currentNumContext;
529 }
531 static void limitContext(ALCdevice *Device, ALCcontext *ctx){
532 currentContext = Device->Contexts;
533 currentNumContext = Device->NumContexts;
534 Device->Contexts = &ctx;
535 Device->NumContexts = 1;
536 }
539 void every2(ALCdevice *Device){
541 record_data *data = (record_data*)Device->ExtraData;
543 if (data->mainFull){
544 printf("data has not yet been extracted!\n");
545 return;
546 }
549 syncContexts(mainContext , auxContext);
551 alcMakeContextCurrent(auxContext);
552 limitContext(Device, auxContext);
553 swapInAux(Device);
554 aluMixData(Device, data->auxBuffer, Device->UpdateSize);
555 saveAux(Device);
556 unLimitContext(Device);
559 alcMakeContextCurrent(mainContext);
560 limitContext(Device, mainContext);
561 swapInMain(Device);
562 aluMixData(Device, data->mainBuffer, Device->UpdateSize);
563 saveMain(Device);
564 unLimitContext(Device);
566 data->mainFull = AL_TRUE;
567 data->auxFull = AL_TRUE;
569 }
576 void every(ALCdevice *Device){
577 UNUSED(Device);
578 // by the time every() is called, mainContext and auxContext will
579 // have been initiliazed.
580 printf("+++++++\nevery is called\n");
581 // print sourceid for all sources.
582 ALsource **src, **src_end;
583 // LockDevice(Device);
584 // pauseAllSources(auxContext);
585 src = mainContext->ActiveSources;
586 src_end = src + mainContext->ActiveSourceCount;
587 UIntMap source_map ;
588 int i;
590 source_map= mainContext->SourceMap;
591 printf("max sources in the mainContext is %d\n", source_map.maxsize);
592 printf("current sources: %d\n", source_map.size);
594 printf("their ID's are:\n");
595 for(i = 0; i < source_map.size; i++){
596 printf("%d, ",source_map.array[i].key);
597 }
598 printf("\n");
599 source_map= auxContext->SourceMap;
600 printf("max sources in the auxContext is %d\n", source_map.maxsize);
601 printf("current sources: %d\n", source_map.size);
603 printf("their ID's are:\n");
604 for(i = 0; i < source_map.size; i++){
605 printf("%d, ",source_map.array[i].key);
606 }
607 printf("\n");
609 while(src != src_end){
611 if (AL_PLAYING == (*src)->state){
612 ALuint source_id = (*src)->source;
613 printf("source %d is AL_PLAYING\n",source_id);
614 }
615 src++;
617 }
620 // UnlockDevice(Device);
621 }
629 // debug printing
631 #define DEBUG 0
633 #define dprintf(expr) {if (DEBUG) {printf(expr);}}
638 static const ALCchar recordDevice[] = "Aurellem";
645 struct ALsource * cloneSource(struct ALsource *source);
647 //struct ALsource * cloneSource(struct ALsource *source){
648 // ALuint[1] sourceID;
651 //}
653 int lock = 0;
655 /*
656 static ALuint RecordProc()
657 {
658 if (0 == lock){return 0;}
659 ALCdevice *Device = deviceInstance;
660 dprintf("RLM: recordProc is begun!!\n");
661 printError();
662 static int MixCount = 0 ;
663 if (Device->Connected)
664 {
665 // the device does not seem to be "ready" until this point.
666 init(Device);
667 //init2(Device);
668 printf("\nMix Cycle %d\n", MixCount++);
669 every(Device);
670 every2(Device);
671 //aluMixData(Device, NULL, Device->UpdateSize);
672 }
673 lock = 1;
674 return 0;
675 }
676 */
679 /*
680 static ALuint RecordProc(ALvoid *ptr)
681 {
683 printf("RLM: recordProc is begun!!\n");
684 ALCdevice *Device = (ALCdevice*)ptr;
685 //printError();
686 record_data *data = (record_data*)Device->ExtraData;
687 ALuint now, start;
688 ALuint64 avail, done;
689 const ALuint restTime = (ALuint64)Device->UpdateSize * 1000 /
690 Device->Frequency / 2;
692 done = 0;
693 start = timeGetTime();
694 //static int MixCount = 0 ;
697 if(!data->killNow && Device->Connected)
698 {
699 printf("sext level breakfast manuever!\n");
700 now = timeGetTime();
702 avail = (ALuint64)(now-start) * Device->Frequency / 1000;
703 if(avail < done)
704 {
706 avail += (ALuint64)0xFFFFFFFFu*Device->Frequency/1000 - done;
707 done = 0;
708 }
709 if(avail-done < Device->UpdateSize)
710 {
711 //Sleep(restTime);
712 //continue;
713 }
715 while(avail-done >= Device->UpdateSize)
716 {
717 // the device does not seem to be "ready" until this point.
718 init(Device);
719 //init2(Device);
720 //printf("\nMix Cycle %d\n", MixCount++);
721 //every(Device);
722 every2(Device);
723 //later(Device);
724 //printError();
725 //aluMixData(Device, NULL, Device->UpdateSize);
726 //Sleep(3000);
727 done += Device->UpdateSize;
728 }
729 }
730 else {
731 printf("WARNGING\n");
732 }
734 return 0;
735 }
736 */
740 static ALuint RecordProc(ALCdevice *Device)
741 {
743 //printf("RLM: recordProc is begun!!\n");
744 // ALCdevice *Device = (ALCdevice*)ptr;
746 record_data *data = (record_data*)Device->ExtraData;
748 if(!data->killNow && Device->Connected)
749 {
751 if (AL_TRUE)
752 {
753 // the device does not seem to be "ready" until this point.
754 init(Device);
755 //init2(Device);
756 //printf("\nMix Cycle %d\n", MixCount++);
757 //every(Device);
758 every2(Device);
759 //later(Device);
760 //printError();
761 //aluMixData(Device, NULL, Device->UpdateSize);
762 //Sleep(3000);
763 }
764 }
765 else {
766 printf("WARNGING\n");
767 }
769 return 0;
770 }
773 void init(ALCdevice *Device){
774 RUNONLY(1);
775 printf("one time init\n");
776 printError();
777 printf("auxContext : %p\n", auxContext);
778 auxContext = alcCreateContext(Device,NULL);
779 printf("auxContext : %p\n", auxContext);
780 printError();
781 printf("mainContext : %p\n", mainContext);
782 mainContext = alcGetCurrentContext();
783 printf("mainContext : %p\n", mainContext);
784 printError();
785 printf("setting listener properties\n");
786 alcMakeContextCurrent(auxContext);
787 ALfloat val1;
788 ALfloat val2;
789 ALfloat val3;
790 alGetListener3f(AL_POSITION, &val1, &val2, &val3);
791 printf("location is [%f,%f,%f]\n", val1,val2,val3);
792 alGetListener3f(AL_VELOCITY, &val1, &val2, &val3);
793 printf("velocity is [%f,%f,%f]\n", val1,val2,val3);
794 saveAux(Device);
795 saveMain(Device);
796 }
798 void later(ALCdevice *Device){
799 // run only the third time it is called
800 UNUSED(Device);
801 RUNAT(3);
802 printf("Suspending main Context....\n");
803 alcSuspendContext(mainContext);
804 printError();
805 printf("Switching to aux Context...\n");
806 alcMakeContextCurrent(auxContext);
807 printError();
808 }
812 static ALCboolean record_open_playback(ALCdevice *device, const ALCchar *deviceName)
813 {
814 record_data *data;
815 // stop any buffering for stdout, so that I can
816 // see the damm printf statements in my terminal immediatley
817 setbuf(stdout, NULL);
819 dprintf("open_playback is called.\n");
820 if(!deviceName)
821 deviceName = recordDevice;
822 else if(strcmp(deviceName, recordDevice) != 0)
823 return ALC_FALSE;
825 data = (record_data*)calloc(1, sizeof(*data));
827 device->szDeviceName = strdup(deviceName);
828 data->robert = 5;
829 device->ExtraData = data;
831 return ALC_TRUE;
832 }
834 static void record_close_playback(ALCdevice *device)
835 {
836 record_data *data = (record_data*)device->ExtraData;
837 dprintf("RLM: close playback called\n");
838 free(data);
839 device->ExtraData = NULL;
840 }
846 static ALCboolean record_reset_playback(ALCdevice *device)
847 {
848 record_data *data = (record_data*)device->ExtraData;
849 dprintf("RLM: reset playback called\n");
851 ALuint channels=0, bits=0;
855 switch(device->FmtType)
856 {
857 case DevFmtByte:
858 device->FmtType = DevFmtUByte;
859 break;
860 case DevFmtUShort:
861 device->FmtType = DevFmtShort;
862 break;
863 case DevFmtUByte:
864 case DevFmtShort:
865 case DevFmtFloat:
866 break;
867 }
868 bits = BytesFromDevFmt(device->FmtType) * 8;
869 channels = ChannelsFromDevFmt(device->FmtChans);
870 data->size = device->UpdateSize * channels * bits / 8;
871 data->auxBuffer = malloc(data->size);
872 data->mainBuffer = malloc(data->size);
873 data->mainFull = AL_FALSE;
874 data->auxFull = AL_FALSE;
875 data->mainReady = AL_TRUE;
876 data->auxReady = AL_TRUE;
878 if(!data->mainBuffer || !data->auxBuffer)
879 {
880 ERR("Buffer malloc failed\n");
881 return ALC_FALSE;
882 }
884 //data->thread = StartThread(RecordProc, device);
885 //data->thread = StartThread(noop, device);
887 //TODO: shoudl free everything somewhere else!
889 /*
890 if(data->thread == NULL)
891 {
892 free(data->mainBuffer);
893 free(data->auxBuffer);
894 free(data->unPauseIDs);
895 data->auxBuffer = NULL;
896 data->mainBuffer = NULL;
898 return ALC_FALSE;
899 }
900 */
901 return ALC_TRUE;
902 }
906 static void record_stop_playback(ALCdevice *device)
907 {
908 record_data *data = (record_data*)device->ExtraData;
909 dprintf("RLM: stop playback called\n");
910 printf("szName is %s \n", device->szDeviceName);
911 printf("robert is %d \n", data->robert);
914 if(!data->thread)
915 return;
917 data->killNow = 1;
918 StopThread(data->thread);
919 data->thread = NULL;
921 data->killNow = 0;
922 }
925 static const BackendFuncs record_funcs = {
926 record_open_playback,
927 record_close_playback,
928 record_reset_playback,
929 record_stop_playback,
930 NULL,
931 NULL, /* These would be filled with functions to */
932 NULL, /* handle capturing audio if we did that. */
933 NULL,
934 NULL,
935 NULL
936 };
938 ALCboolean alc_record_init(BackendFuncs *func_list)
939 {
940 dprintf("RECORD: I'm InIT111\n");
941 *func_list = record_funcs;
942 return ALC_TRUE;
943 }
945 void alc_record_deinit(void)
946 {
947 }
949 void alc_record_probe(enum DevProbe type)
950 {
951 dprintf("RECORD: I'm being probed! :/\n");
953 switch(type)
954 {
955 case DEVICE_PROBE:
956 AppendDeviceList(recordDevice);
957 break;
958 case ALL_DEVICE_PROBE:
959 AppendAllDeviceList(recordDevice);
960 break;
961 case CAPTURE_DEVICE_PROBE:
962 break;
963 }
964 }
969 void printError(void){
970 ALenum error = alGetError();
971 printf("%s\n", GetALCErrorString(error));
972 printf("%s\n", GetALErrorString(error));
973 }
977 char* GetALCErrorString(ALenum err)
978 {
979 switch(err)
980 {
981 case ALC_NO_ERROR:
982 return "AL_NO_ERROR";
983 break;
985 case ALC_INVALID_DEVICE:
986 return "ALC_INVALID_DEVICE";
987 break;
989 case ALC_INVALID_CONTEXT:
990 return "ALC_INVALID_CONTEXT";
991 break;
993 case ALC_INVALID_ENUM:
994 return "ALC_INVALID_ENUM";
995 break;
997 case ALC_INVALID_VALUE:
998 return "ALC_INVALID_VALUE";
999 break;
1001 case ALC_OUT_OF_MEMORY:
1002 return "ALC_OUT_OF_MEMORY";
1003 break;
1004 };
1005 return "UNknown error.";
1014 char* GetALErrorString(ALenum err)
1016 switch(err)
1018 case AL_NO_ERROR:
1019 return "AL_NO_ERROR";
1020 break;
1022 case AL_INVALID_NAME:
1023 return "AL_INVALID_NAME";
1024 break;
1026 case AL_INVALID_ENUM:
1027 return "AL_INVALID_ENUM";
1028 break;
1030 case AL_INVALID_VALUE:
1031 return "AL_INVALID_VALUE";
1032 break;
1034 case AL_INVALID_OPERATION:
1035 return "AL_INVALID_OPERATION";
1036 break;
1038 case AL_OUT_OF_MEMORY:
1039 return "AL_OUT_OF_MEMORY";
1040 break;
1041 };
1042 return "UNknown error.";
1051 #include "com_aurellem_audioPlay_TestCall.h"
1053 JNIEXPORT void JNICALL Java_com_aurellem_audioPlay_TestCall_nprintGarbage
1054 (JNIEnv *env, jclass clazz){
1055 UNUSED(env);UNUSED(clazz);
1056 printf("Native! method* zzz\n");
1057 return;
1060 #include "com_aurellem_audioPlay_WavCaptureMaybe.h"
1062 JNIEXPORT void JNICALL Java_com_aurellem_audioPlay_WavCaptureMaybe_nrecord_1whatever
1063 (JNIEnv *env, jclass clazz){
1064 UNUSED(env);UNUSED(clazz);
1065 printf("record_aurellem_whatever!");
1083 //////////////////////////// Real JNI stuff ////////////////////////////////
1084 void getMainSamples(ALCvoid *buffer){
1085 UNUSED(buffer);
1086 // memcpy(mainBuffer, (ALubyte*) buffer, samples);
1089 void getAuxSamples(ALCvoid *buffer){
1090 UNUSED(buffer);
1091 // memcpy(auxBuffer, (ALubyte*) buffer, samples);
1094 #include "com_jme3_capture_RecordAudioRenderer.h"
1096 /*
1097 * Class: com_jme3_capture_RecordAudioRenderer
1098 * Method: helloEveryone
1099 * Signature: ()V
1100 */
1101 JNIEXPORT void JNICALL Java_com_jme3_capture_RecordAudioRenderer_helloEveryone
1102 (JNIEnv *env, jclass clazz){
1103 UNUSED(env);UNUSED(clazz);
1104 printf("\n**************\nC from Java: I'm audioRecorder :)\n***********\n");
1108 /*
1109 * Class: com_jme3_capture_RecordAudioRenderer
1110 * Method: nstep
1111 * Signature: ()V
1112 */
1113 JNIEXPORT void JNICALL Java_com_jme3_capture_RecordAudioRenderer_nstep
1114 (JNIEnv *env, jclass clazz, jlong device){
1115 UNUSED(env);UNUSED(clazz);UNUSED(device);
1116 //printf("C from Java: I'm audioRecorder -- nstep :)\n");
1117 RecordProc((ALCdevice*)((intptr_t)device));
1120 /*
1121 * Class: com_jme3_capture_RecordAudioRenderer
1122 * Method: ngetMainSamples
1123 * Signature: (JLjava/nio/ByteBuffer;I)V
1124 */
1125 JNIEXPORT void JNICALL Java_com_jme3_capture_RecordAudioRenderer_ngetMainSamples
1126 (JNIEnv *env, jclass clazz, jlong device, jobject buffer, jint position){
1127 UNUSED(clazz);
1129 ALvoid *buffer_address =
1130 ((ALbyte *)(((char*)(*env)->GetDirectBufferAddress(env, buffer)) + position));
1131 ALCdevice *recorder = (ALCdevice*) ((intptr_t)device);
1132 //printf("getMainSamples: device is %p\n", recorder);
1133 record_data *data = (record_data*)recorder->ExtraData;
1134 if (!data->mainFull){
1135 printf("data is not ready!\n");
1136 return;
1138 memcpy(buffer_address, data->mainBuffer, data->size);
1139 data->mainFull = AL_FALSE;
1142 /*
1143 * Class: com_jme3_capture_RecordAudioRenderer
1144 * Method: ngetAuxSamples
1145 * Signature: (JLjava/nio/ByteBuffer;I)V
1146 */
1147 JNIEXPORT void JNICALL Java_com_jme3_capture_RecordAudioRenderer_ngetAuxSamples
1148 (JNIEnv *env, jclass clazz, jlong device, jobject buffer, jint position){
1149 UNUSED(clazz);
1151 ALvoid *buffer_address =
1152 ((ALbyte *)(((char*)(*env)->GetDirectBufferAddress(env, buffer)) + position));
1153 ALCdevice *recorder = (ALCdevice*) ((intptr_t)device);
1154 //printf("getMainSamples: device is %p\n", recorder);
1155 record_data *data = (record_data*)recorder->ExtraData;
1157 memcpy(buffer_address, data->auxBuffer, data->size);
1162 /*
1163 * Class: com_jme3_capture_RecordAudioRenderer
1164 * Method: nsetAuxListener3f
1165 * Signature: (IFFF)V
1166 */
1167 JNIEXPORT void JNICALL Java_com_jme3_capture_RecordAudioRenderer_nsetAuxListener3f
1168 (JNIEnv *env, jclass clazz, jint pname, jfloat v1, jfloat v2, jfloat v3){
1169 UNUSED(env);UNUSED(clazz);
1170 aux_alListener3f(pname, v1, v2, v3);
1173 /*
1174 * Class: com_jme3_capture_RecordAudioRenderer
1175 * Method: nsetAuxListenerf
1176 * Signature: (IF)V
1177 */
1178 JNIEXPORT void JNICALL Java_com_jme3_capture_RecordAudioRenderer_nsetAuxListenerf
1179 (JNIEnv *env, jclass clazz, jint pname, jfloat v1){
1180 UNUSED(env);UNUSED(clazz);
1181 aux_alListenerf(pname, v1);
1186 /*
1187 static void JNICALL Java_org_lwjgl_openal_ALC11_nalcCaptureSamples
1188 (JNIEnv *env, jclass clazz, jlong device, jobject buffer, jint position, jint samples) {
1189 ALvoid *buffer_address =
1190 ((ALbyte *)(((char*)(*env)->GetDirectBufferAddress(env, buffer)) + position));
1191 alcCaptureSamples((ALCdevice*) ((intptr_t)device), buffer_address, samples);
1193 */