Mercurial > audio-send
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 library3 * Copyright (C) 2010 by Chris Robinson4 * This library is free software; you can redistribute it and/or5 * modify it under the terms of the GNU Library General Public6 * License as published by the Free Software Foundation; either7 * 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 of11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12 * Library General Public License for more details.13 *14 * You should have received a copy of the GNU Library General Public15 * License along with this library; if not, write to the16 * 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.html19 */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 prototypes62 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 //synchronization74 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 auxContexts93 // take the mainContext and for each context, COPY94 // 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 do103 // anything to sources while the audio is being rendered, so make sure104 // to maintain an "isDone" state as well.106 // Special device which allows simulation of multiple listeners107 // hearing the same set of sources. Provides access to the rendered108 // data for each listener. Designed to work with LWJGL.110 // first, the mainContext is the only context that is controlled by111 // 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 on116 // all other contexts except the mainContext (this takes care of117 // sources in the mainContext being shut down.)118 // we will iterate through all119 // the active sources in our mainContext (the one which is controlled120 // through LWJGL), and take their sourceIDs. For each of these IDs121 // and for each other context, we'll check some internal structure to122 // see if we've already created a corresponding source. If that123 // source exits, we will SYNCH it with the source which belongs to the124 // mainContext. If it DOESN'T exist, we will CLONE the source from the125 // main context and establish it in the other context.127 // Each render loop consists of noting all of the active sources in128 // the mainContext and storing their IDs. Then, for each context,129 // the correspondig sources to the active sources in the mainContext130 // will be set to PLAY, and all sources in all other contexts will be131 // set to PAUSE. aluMixData will be called for each context in this132 // way.134 // approved by KittyCat137 // CAN get id appropiate for us in the sorce-repated openal functions138 // by quering *source->source140 // first, do it with only two listeners, two contexts, automatically141 // 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 values206 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 values215 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 sources335 //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 sources400 // 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 sources428 // as ctx1. Now, sync each source from ctx1 to the corresponding429 // 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 state483 // 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 will579 // 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 printing631 #define DEBUG 0633 #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 called800 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 can816 // see the damm printf statements in my terminal immediatley817 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 NULL936 };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.";1006 }1014 char* GetALErrorString(ALenum err)1015 {1016 switch(err)1017 {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.";1043 }1051 #include "com_aurellem_audioPlay_TestCall.h"1053 JNIEXPORT void JNICALL Java_com_aurellem_audioPlay_TestCall_nprintGarbage1054 (JNIEnv *env, jclass clazz){1055 UNUSED(env);UNUSED(clazz);1056 printf("Native! method* zzz\n");1057 return;1058 }1060 #include "com_aurellem_audioPlay_WavCaptureMaybe.h"1062 JNIEXPORT void JNICALL Java_com_aurellem_audioPlay_WavCaptureMaybe_nrecord_1whatever1063 (JNIEnv *env, jclass clazz){1064 UNUSED(env);UNUSED(clazz);1065 printf("record_aurellem_whatever!");1066 }1083 //////////////////////////// Real JNI stuff ////////////////////////////////1084 void getMainSamples(ALCvoid *buffer){1085 UNUSED(buffer);1086 // memcpy(mainBuffer, (ALubyte*) buffer, samples);1087 }1089 void getAuxSamples(ALCvoid *buffer){1090 UNUSED(buffer);1091 // memcpy(auxBuffer, (ALubyte*) buffer, samples);1092 }1094 #include "com_jme3_capture_RecordAudioRenderer.h"1096 /*1097 * Class: com_jme3_capture_RecordAudioRenderer1098 * Method: helloEveryone1099 * Signature: ()V1100 */1101 JNIEXPORT void JNICALL Java_com_jme3_capture_RecordAudioRenderer_helloEveryone1102 (JNIEnv *env, jclass clazz){1103 UNUSED(env);UNUSED(clazz);1104 printf("\n**************\nC from Java: I'm audioRecorder :)\n***********\n");1105 }1108 /*1109 * Class: com_jme3_capture_RecordAudioRenderer1110 * Method: nstep1111 * Signature: ()V1112 */1113 JNIEXPORT void JNICALL Java_com_jme3_capture_RecordAudioRenderer_nstep1114 (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));1118 }1120 /*1121 * Class: com_jme3_capture_RecordAudioRenderer1122 * Method: ngetMainSamples1123 * Signature: (JLjava/nio/ByteBuffer;I)V1124 */1125 JNIEXPORT void JNICALL Java_com_jme3_capture_RecordAudioRenderer_ngetMainSamples1126 (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;1137 }1138 memcpy(buffer_address, data->mainBuffer, data->size);1139 data->mainFull = AL_FALSE;1140 }1142 /*1143 * Class: com_jme3_capture_RecordAudioRenderer1144 * Method: ngetAuxSamples1145 * Signature: (JLjava/nio/ByteBuffer;I)V1146 */1147 JNIEXPORT void JNICALL Java_com_jme3_capture_RecordAudioRenderer_ngetAuxSamples1148 (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);1159 }1162 /*1163 * Class: com_jme3_capture_RecordAudioRenderer1164 * Method: nsetAuxListener3f1165 * Signature: (IFFF)V1166 */1167 JNIEXPORT void JNICALL Java_com_jme3_capture_RecordAudioRenderer_nsetAuxListener3f1168 (JNIEnv *env, jclass clazz, jint pname, jfloat v1, jfloat v2, jfloat v3){1169 UNUSED(env);UNUSED(clazz);1170 aux_alListener3f(pname, v1, v2, v3);1171 }1173 /*1174 * Class: com_jme3_capture_RecordAudioRenderer1175 * Method: nsetAuxListenerf1176 * Signature: (IF)V1177 */1178 JNIEXPORT void JNICALL Java_com_jme3_capture_RecordAudioRenderer_nsetAuxListenerf1179 (JNIEnv *env, jclass clazz, jint pname, jfloat v1){1180 UNUSED(env);UNUSED(clazz);1181 aux_alListenerf(pname, v1);1182 }1186 /*1187 static void JNICALL Java_org_lwjgl_openal_ALC11_nalcCaptureSamples1188 (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);1192 }1193 */