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