Mercurial > audio-send
comparison org/ear.org @ 21:0ee04505a37f
fixed send.c tangling
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Thu, 03 Nov 2011 15:07:36 -0700 |
parents | e8ae40c9848c |
children | 616215c81d23 |
comparison
equal
deleted
inserted
replaced
20:e8ae40c9848c | 21:0ee04505a37f |
---|---|
148 which are in the master context. | 148 which are in the master context. |
149 - =limitContext()= and =unLimitContext()= make it possible to render | 149 - =limitContext()= and =unLimitContext()= make it possible to render |
150 only one context at a time. | 150 only one context at a time. |
151 | 151 |
152 ** Necessary State | 152 ** Necessary State |
153 #+srcname: send-state | |
153 #+begin_src C | 154 #+begin_src C |
154 //////////////////// State | 155 //////////////////// State |
155 | 156 |
156 typedef struct context_data { | 157 typedef struct context_data { |
157 ALfloat ClickRemoval[MAXCHANNELS]; | 158 ALfloat ClickRemoval[MAXCHANNELS]; |
175 parallel. The solution is to create a copy of this normally global | 176 parallel. The solution is to create a copy of this normally global |
176 device state for each context, and copy it back and forth into and out | 177 device state for each context, and copy it back and forth into and out |
177 of the actual device state whenever a context is rendered. | 178 of the actual device state whenever a context is rendered. |
178 | 179 |
179 ** Synchronization Macros | 180 ** Synchronization Macros |
180 | 181 #+srcname: sync-macros |
181 #+begin_src C | 182 #+begin_src C |
182 //////////////////// Context Creation / Synchronization | 183 //////////////////// Context Creation / Synchronization |
183 | 184 |
184 #define _MAKE_SYNC(NAME, INIT_EXPR, GET_EXPR, SET_EXPR) \ | 185 #define _MAKE_SYNC(NAME, INIT_EXPR, GET_EXPR, SET_EXPR) \ |
185 void NAME (ALuint sourceID1, ALuint sourceID2, \ | 186 void NAME (ALuint sourceID1, ALuint sourceID2, \ |
218 completely synchronize two sources, it is necessary to use all of | 219 completely synchronize two sources, it is necessary to use all of |
219 them. These macros help to condense the otherwise repetitive | 220 them. These macros help to condense the otherwise repetitive |
220 synchronization code involving these similar low-level =OpenAL= functions. | 221 synchronization code involving these similar low-level =OpenAL= functions. |
221 | 222 |
222 ** Source Synchronization | 223 ** Source Synchronization |
224 #+srcname: sync-sources | |
223 #+begin_src C | 225 #+begin_src C |
224 void syncSources(ALsource *masterSource, ALsource *slaveSource, | 226 void syncSources(ALsource *masterSource, ALsource *slaveSource, |
225 ALCcontext *masterCtx, ALCcontext *slaveCtx){ | 227 ALCcontext *masterCtx, ALCcontext *slaveCtx){ |
226 ALuint master = masterSource->source; | 228 ALuint master = masterSource->source; |
227 ALuint slave = slaveSource->source; | 229 ALuint slave = slaveSource->source; |
290 same between the master and slave sources. I'd like to take this | 292 same between the master and slave sources. I'd like to take this |
291 moment to salute the [[http://connect.creativelabs.com/openal/Documentation/Forms/AllItems.aspx][=OpenAL= Reference Manual]], which provides a very | 293 moment to salute the [[http://connect.creativelabs.com/openal/Documentation/Forms/AllItems.aspx][=OpenAL= Reference Manual]], which provides a very |
292 good description of =OpenAL='s internals. | 294 good description of =OpenAL='s internals. |
293 | 295 |
294 ** Context Synchronization | 296 ** Context Synchronization |
297 #+srcname: sync-contexts | |
295 #+begin_src C | 298 #+begin_src C |
296 void syncContexts(ALCcontext *master, ALCcontext *slave){ | 299 void syncContexts(ALCcontext *master, ALCcontext *slave){ |
297 /* If there aren't sufficient sources in slave to mirror | 300 /* If there aren't sufficient sources in slave to mirror |
298 the sources in master, create them. */ | 301 the sources in master, create them. */ |
299 ALCcontext *current = alcGetCurrentContext(); | 302 ALCcontext *current = alcGetCurrentContext(); |
327 =syncSources()=. The only thing that =syncContexts()= has to worry | 330 =syncSources()=. The only thing that =syncContexts()= has to worry |
328 about is automatically creating new sources whenever a slave context | 331 about is automatically creating new sources whenever a slave context |
329 does not have the same number of sources as the master context. | 332 does not have the same number of sources as the master context. |
330 | 333 |
331 ** Context Creation | 334 ** Context Creation |
335 #+srcname: context-creation | |
332 #+begin_src C | 336 #+begin_src C |
333 static void addContext(ALCdevice *Device, ALCcontext *context){ | 337 static void addContext(ALCdevice *Device, ALCcontext *context){ |
334 send_data *data = (send_data*)Device->ExtraData; | 338 send_data *data = (send_data*)Device->ExtraData; |
335 // expand array if necessary | 339 // expand array if necessary |
336 if (data->numContexts >= data->maxContexts){ | 340 if (data->numContexts >= data->maxContexts){ |
355 device-wide =ExtraData= structure. The =renderBuffer= that is created | 359 device-wide =ExtraData= structure. The =renderBuffer= that is created |
356 here is where the rendered sound samples for this slave context will | 360 here is where the rendered sound samples for this slave context will |
357 eventually go. | 361 eventually go. |
358 | 362 |
359 ** Context Switching | 363 ** Context Switching |
364 #+srcname: context-switching | |
360 #+begin_src C | 365 #+begin_src C |
361 //////////////////// Context Switching | 366 //////////////////// Context Switching |
362 | 367 |
363 /* A device brings along with it two pieces of state | 368 /* A device brings along with it two pieces of state |
364 * which have to be swapped in and out with each context. | 369 * which have to be swapped in and out with each context. |
400 the Device's context list to put the desired context-to-be-rendered | 405 the Device's context list to put the desired context-to-be-rendered |
401 into position 0, we can get trick =OpenAL= into rendering each slave | 406 into position 0, we can get trick =OpenAL= into rendering each slave |
402 context separate from all the others. | 407 context separate from all the others. |
403 | 408 |
404 ** Main Device Loop | 409 ** Main Device Loop |
410 #+srcname: main-loop | |
405 #+begin_src C | 411 #+begin_src C |
406 //////////////////// Main Device Loop | 412 //////////////////// Main Device Loop |
407 | 413 |
408 /* Establish the LWJGL context as the master context, which will | 414 /* Establish the LWJGL context as the master context, which will |
409 * be synchronized to all the slave contexts | 415 * be synchronized to all the slave contexts |
456 a way to transport this information to Java, and also a way to drive | 462 a way to transport this information to Java, and also a way to drive |
457 this device from Java. The following JNI interface code is inspired | 463 this device from Java. The following JNI interface code is inspired |
458 by the way LWJGL interfaces with =OpenAL=. | 464 by the way LWJGL interfaces with =OpenAL=. |
459 | 465 |
460 *** step | 466 *** step |
461 | 467 #+srcname: jni-step |
462 #+begin_src C | 468 #+begin_src C |
463 //////////////////// JNI Methods | 469 //////////////////// JNI Methods |
464 | 470 |
465 #include "com_aurellem_send_AudioSend.h" | 471 #include "com_aurellem_send_AudioSend.h" |
466 | 472 |
483 simulate 1 second of AI-time would miss almost all of the sound in | 489 simulate 1 second of AI-time would miss almost all of the sound in |
484 its environment. | 490 its environment. |
485 | 491 |
486 | 492 |
487 *** getSamples | 493 *** getSamples |
494 #+srcname: jni-get-samples | |
488 #+begin_src C | 495 #+begin_src C |
489 /* | 496 /* |
490 * Class: com_aurellem_send_AudioSend | 497 * Class: com_aurellem_send_AudioSend |
491 * Method: ngetSamples | 498 * Method: ngetSamples |
492 * Signature: (JLjava/nio/ByteBuffer;III)V | 499 * Signature: (JLjava/nio/ByteBuffer;III)V |
513 | 520 |
514 =addListener=, =setNthListenerf=, and =setNthListener3f= are | 521 =addListener=, =setNthListenerf=, and =setNthListener3f= are |
515 necessary to change the properties of any listener other than the | 522 necessary to change the properties of any listener other than the |
516 master one, since only the listener of the current active context is | 523 master one, since only the listener of the current active context is |
517 affected by the normal =OpenAL= listener calls. | 524 affected by the normal =OpenAL= listener calls. |
518 | 525 #+srcname: listener-manage |
519 #+begin_src C | 526 #+begin_src C |
520 /* | 527 /* |
521 * Class: com_aurellem_send_AudioSend | 528 * Class: com_aurellem_send_AudioSend |
522 * Method: naddListener | 529 * Method: naddListener |
523 * Signature: (J)V | 530 * Signature: (J)V |
580 | 587 |
581 =getAudioFormat= is a convenience function that uses JNI to build up a | 588 =getAudioFormat= is a convenience function that uses JNI to build up a |
582 =javax.sound.sampled.AudioFormat= object from data in the Device. This | 589 =javax.sound.sampled.AudioFormat= object from data in the Device. This |
583 way, there is no ambiguity about what the bits created by =step= and | 590 way, there is no ambiguity about what the bits created by =step= and |
584 returned by =getSamples= mean. | 591 returned by =getSamples= mean. |
585 | 592 #+srcname: jni-init |
586 #+begin_src C | 593 #+begin_src C |
587 /* | 594 /* |
588 * Class: com_aurellem_send_AudioSend | 595 * Class: com_aurellem_send_AudioSend |
589 * Method: ninitDevice | 596 * Method: ninitDevice |
590 * Signature: (J)V | 597 * Signature: (J)V |
633 #+end_src | 640 #+end_src |
634 | 641 |
635 *** Boring Device management stuff | 642 *** Boring Device management stuff |
636 This code is more-or-less copied verbatim from the other =OpenAL= | 643 This code is more-or-less copied verbatim from the other =OpenAL= |
637 backends. It's the basis for =OpenAL='s primitive object system. | 644 backends. It's the basis for =OpenAL='s primitive object system. |
638 | 645 #+srcname: device-init |
639 #+begin_src C | 646 #+begin_src C |
640 //////////////////// Device Initialization / Management | 647 //////////////////// Device Initialization / Management |
641 | 648 |
642 static const ALCchar sendDevice[] = "Multiple Audio Send"; | 649 static const ALCchar sendDevice[] = "Multiple Audio Send"; |
643 | 650 |
828 <<test-hearing>> | 835 <<test-hearing>> |
829 #+end_src | 836 #+end_src |
830 | 837 |
831 | 838 |
832 #+begin_src C :tangle ../Alc/backends/send.c | 839 #+begin_src C :tangle ../Alc/backends/send.c |
833 <<send>> | 840 <<send-header>> |
834 #+end_src | 841 <<send-state>> |
835 | 842 <<sync-macros>> |
836 | 843 <<sync-sources>> |
844 <<sync-contexts>> | |
845 <<context-creation>> | |
846 <<context-switching>> | |
847 <<main-loop>> | |
848 <<jni-step>> | |
849 <<jni-get-samples>> | |
850 <<listener-manage>> | |
851 <<jni-init>> | |
852 <<device-init>> | |
853 #+end_src | |
854 | |
855 |