1
2 /*
3 # Sfront, a SAOL to C translator
4 # This file: audiounit audio driver for sfront
5 #
6 # Copyright (c) 1999-2008, Regents of the University of California
7 # All rights reserved.
8 #
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions are
11 # met:
12 #
13 # Redistributions of source code must retain the above copyright
14 # notice, this list of conditions and the following disclaimer.
15 #
16 # Redistributions in binary form must reproduce the above copyright
17 # notice, this list of conditions and the following disclaimer in the
18 # documentation and/or other materials provided with the distribution.
19 #
20 # Neither the name of the University of California, Berkeley nor the
21 # names of its contributors may be used to endorse or promote products
22 # derived from this software without specific prior written permission.
23 #
24 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #
36 # Maintainer: John Lazzaro, lazzaro@cs.berkeley.edu
37 */
38
39
40 /****************************************************************/
41 /****************************************************************/
42 /* Apple AudioUnit audio driver for sfront */
43 /****************************************************************/
44
45 /*~~~~~~~~~~~~~*/
46 /* debug level */
47 /*_____________*/
48
49 /* Level 0: No debugging messages */
50 /* Level 1: Session setup and error messages */
51 /* Level 2: + All MIDI events */
52 /* Level 3: + All Rendering calls */
53
54 #if !defined(ASYS_AUDIOUNIT_DEBUG_LEVEL)
55 #define ASYS_AUDIOUNIT_DEBUG_LEVEL 0
56 #endif
57
58 /*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
59 /* output clipping behavior */
60 /*__________________________*/
61
62 #define ASYS_AUDIOUNIT_OUTPUT_CLIPPING 0
63
64 /*~~~~~~~~~~~~~~~~~~~~~*/
65 /* aucontrol detection */
66 /*_____________________*/
67
68 #if defined(CSYS_CDRIVER_AUCONTROL) || defined(CSYS_CDRIVER_AUCONTROLM)
69 #define ASYS_AUDIOUNIT_HAS_AUCONTROL 1
70 #else
71 #define ASYS_AUDIOUNIT_HAS_AUCONTROL 0
72 #endif
73
74 #if defined(CSYS_CDRIVER_AUCONTROLM)
75 #define ASYS_AUDIOUNIT_MIDISUPPORT 1
76 #else
77 #define ASYS_AUDIOUNIT_MIDISUPPORT 0
78 #endif
79
80 /*~~~~~~~~~~~~~~~~~~~*/
81 /* reentrant defines */
82 /*___________________*/
83
84 #if (ENGINE_STYLE == ENGINE_REENTRANT)
85 #define MY_ENGINE_PTR My->ENGINE_PTR
86 #define MY_ENGINE_PTR_COMMA My->ENGINE_PTR,
87 #define MY_ENGINE_PTR_ASSIGNED_TO My->ENGINE_PTR =
88 #define MY_ENGINE_PTR_DESTROY_SEMICOLON free(MY_ENGINE_PTR);
89 #define MY_ENGINE_PTR_IS_NULL (MY_ENGINE_PTR == NULL)
90 #define MY_ENGINE_PTR_IS_NOT_NULL (MY_ENGINE_PTR != NULL)
91 #define ENGINE_MEMSTATUS_SEMICOLON(x) \
92 asysn_audiounit_memstatus(ENGINE_PTR, ENGINE_SIZE, x);
93 #else
94 #define MY_ENGINE_PTR
95 #define MY_ENGINE_PTR_COMMA
96 #define MY_ENGINE_PTR_ASSIGNED_TO
97 #define MY_ENGINE_PTR_DESTROY_SEMICOLON
98 #define MY_ENGINE_PTR_IS_NULL (0)
99 #define MY_ENGINE_PTR_IS_NOT_NULL (1)
100 #define ENGINE_MEMSTATUS_SEMICOLON(x)
101 #endif
102
103 /*~~~~~~~~~~~~~~~~~*/
104 /* include headers */
105 /*_________________*/
106
107 #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
108 #include <CoreServices/CoreServices.h>
109 #include <AudioUnit/AudioUnit.h>
110 #include <AudioToolbox/AudioUnitUtilities.h>
111 #else
112 #include <ConditionalMacros.h>
113 #include <CoreServices.h>
114 #include <AudioUnit.h>
115 #include <AudioUnitUtilities.h>
116 #endif
117
118 /* 64-bit integer headers */
119
120 #include <stdint.h>
121
122 /* for control driver socket system */
123
124 #include <sys/types.h>
125 #include <sys/socket.h>
126 #include <unistd.h>
127 #include <sys/uio.h>
128 #include <fcntl.h>
129
130 /* include files for memory paging */
131
132 #include <sys/mman.h>
133
134 /* include files for synchronization */
135
136 #include <libkern/OSAtomic.h>
137
138 /*~~~~~~~~~~~~~~~~~~*/
139 /* endian detection */
140 /*__________________*/
141
142 Float32 asysn_audiounit_float32_endian_test = -1;
143
144 #define ASYS_AUDIOUNIT_FLOAT32_BIGENDIAN \
145 ((((char *)(&asysn_audiounit_float32_endian_test))[0]) != 0)
146
147 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
148 /* audiounit defines */
149 /*___________________________*/
150
151 /* after if if-tree runs, only one audio type should be 1 */
152
153 #if (!defined(ASYS_HASINPUT) && defined(ASYS_HASOUTPUT) && defined(ASYS_ACTIVE_O))
154 #define ASYS_AUDIOUNIT_MUSICDEVICE 1
155 #else
156 #define ASYS_AUDIOUNIT_MUSICDEVICE 0
157 #endif
158
159 #if (defined(ASYS_HASINPUT) && defined(ASYS_HASOUTPUT) && defined(ASYS_ACTIVE_IO))
160 #define ASYS_AUDIOUNIT_EFFECT 1
161 #else
162 #define ASYS_AUDIOUNIT_EFFECT 0
163 #endif
164
165
166 /*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
167 /*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
168 /* The Wiretap Macro Calls */
169 /*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
170 /*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
171
172 /********************/
173 /* level one macros */
174 /********************/
175
176 #if (ASYS_AUDIOUNIT_DEBUG_LEVEL >= 1)
177
178 #define ASYS_AUDIOUNIT_WIRETAP(a, b) do {\
179 asysn_audiounit_wiretap(a, b);\
180 } while (0)
181 #define ASYS_AUDIOUNIT_WIRETAP_PUTSTRING(a) do {\
182 asysn_audiounit_wiretap_putstring(a);\
183 } while (0)
184 #define ASYS_AUDIOUNIT_WIRETAP_PRINT_COMPONENT_RESULT(a) do {\
185 asysn_audiounit_wiretap_print_component_result(a);\
186 } while (0)
187
188 #else
189
190 #define ASYS_AUDIOUNIT_WIRETAP(a, b) do { } while (0)
191 #define ASYS_AUDIOUNIT_WIRETAP_PUTSTRING(a) do { } while (0)
192 #define ASYS_AUDIOUNIT_WIRETAP_PRINT_COMPONENT_RESULT(a) do { } while (0)
193
194 #endif
195
196 /********************/
197 /* level two macros */
198 /********************/
199
200 #if (ASYS_AUDIOUNIT_DEBUG_LEVEL >= 2)
201
202 #define ASYS_AUDIOUNIT_WIRETAP_MIDIEVENT(a, b, c, d, e, f) do {\
203 asysn_audiounit_wiretap_midievent(a, b, c, d, e, f);\
204 } while (0)
205 #define ASYS_AUDIOUNIT_WIRETAP_M(a, b) do {\
206 asysn_audiounit_wiretap(a, b);\
207 } while (0)
208 #define ASYS_AUDIOUNIT_WIRETAP_GETPARAMETER(a, b, c, d, e, f) do {\
209 asysn_audiounit_wiretap_getparameter(a, b, c, d, e, f);\
210 } while (0)
211 #define ASYS_AUDIOUNIT_WIRETAP_SETPARAMETER(a, b, c, d, e, f, g) do {\
212 asysn_audiounit_wiretap_setparameter(a, b, c, d, e, f, g);\
213 } while (0)
214 #else
215
216 #define ASYS_AUDIOUNIT_WIRETAP_MIDIEVENT(a, b, c, d, e, f) do { } while (0)
217 #define ASYS_AUDIOUNIT_WIRETAP_M(a, b) do { } while (0)
218 #define ASYS_AUDIOUNIT_WIRETAP_GETPARAMETER(a, b, c, d, e, f) do { } while (0)
219 #define ASYS_AUDIOUNIT_WIRETAP_SETPARAMETER(a, b, c, d, e, f, g) do { } while (0)
220
221 #endif
222
223 /**********************/
224 /* level three macros */
225 /**********************/
226
227 #if (ASYS_AUDIOUNIT_DEBUG_LEVEL >= 3)
228
229 #define ASYS_AUDIOUNIT_WIRETAP_RENDERER(a, b, c, d, e, f) do {\
230 asysn_audiounit_wiretap_renderer(a, b, c, d, e, f);\
231 } while (0)
232 #define ASYS_AUDIOUNIT_WIRETAP_R(a, b) do {\
233 asysn_audiounit_wiretap(a, b);\
234 } while (0)
235
236 #else
237
238 #define ASYS_AUDIOUNIT_WIRETAP_RENDERER(a, b, c, d, e, f) do { } while (0)
239 #define ASYS_AUDIOUNIT_WIRETAP_R(a, b) do { } while (0)
240
241 #endif
242
243
244 /****************************************************************/
245 /* Part One: Sfront asys_ dummy function calls */
246 /****************************************************************/
247
248 #if (defined(ASYS_HASOUTPUT) && !defined(ASYS_HASINPUT))
249
250 /****************************************************************/
251 /* sets up audio output for a given srate/channels */
252 /****************************************************************/
253
asys_osetup(int srate,int ochannels,int osample,char * oname,int toption)254 int asys_osetup(int srate, int ochannels, int osample,
255 char * oname, int toption) { return ASYS_DONE; }
256
257 #endif
258
259 #if (!defined(ASYS_HASOUTPUT) && defined(ASYS_HASINPUT))
260
261 /****************************************************************/
262 /* sets up audio input for a given srate/channels */
263 /****************************************************************/
264
asys_isetup(int srate,int ichannels,int isample,char * iname,int toption)265 int asys_isetup(int srate, int ichannels, int isample,
266 char * iname, int toption) { return ASYS_DONE; }
267
268 #endif
269
270 #if (defined(ASYS_HASOUTPUT) && defined(ASYS_HASINPUT))
271
272 /****************************************************************/
273 /* sets up audio input and output for a given srate/channels */
274 /****************************************************************/
275
asys_iosetup(int srate,int ichannels,int ochannels,int isample,int osample,char * iname,char * oname,int toption)276 int asys_iosetup(int srate, int ichannels, int ochannels,
277 int isample, int osample, char * iname,
278 char * oname, int toption) { return ASYS_DONE; }
279 #endif
280
281 #if (defined(ASYS_HASOUTPUT)&&(!defined(ASYS_HASINPUT)))
282
283 /****************************************************************/
284 /* shuts down audio output */
285 /****************************************************************/
286
asys_oshutdown(void)287 void asys_oshutdown(void) { }
288
289 #endif
290
291 #if (!defined(ASYS_HASOUTPUT)&&(defined(ASYS_HASINPUT)))
292
293 /****************************************************************/
294 /* shuts down audio input device */
295 /****************************************************************/
296
asys_ishutdown(void)297 void asys_ishutdown(void) { }
298
299 #endif
300
301 #if (defined(ASYS_HASOUTPUT)&&(defined(ASYS_HASINPUT)))
302
303 /****************************************************************/
304 /* shuts down audio input and output device */
305 /****************************************************************/
306
asys_ioshutdown(void)307 void asys_ioshutdown(void) { }
308
309 #endif
310
311 /****************************************************************/
312 /* syntactically necessary, but will never be called */
313 /****************************************************************/
314
asys_main(void)315 void asys_main(void) { }
316
317 /*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
318 /* ksync function suite */
319 /*-------------------------*/
320
321 #if defined(ASYS_KSYNC)
322
323 /***********************************************************/
324 /* initializes k-rate boundaries sync */
325 /***********************************************************/
326
ksyncinit()327 void ksyncinit() { }
328
329 /***********************************************************/
330 /* synchronizes on k-rate boundaries */
331 /***********************************************************/
332
ksync()333 float ksync() { return 0.0F; } /* encodes "uses no CPU" */
334
335 #endif /* ASYS_KSYNC */
336
337
338 /*************************************************************/
339 /* Start of Part Two: The AudioUnit Component */
340 /*************************************************************/
341
342 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
343 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
344 /* AudioUnit Property Constants */
345 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
346 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
347
348 #define ASYS_AUDIOUNIT_NULL 0
349 #define ASYS_AUDIOUNIT_MONO 1
350 #define ASYS_AUDIOUNIT_STEREO 2
351
352 #define ASYS_AUDIOUNIT_OUTPUT_MAXCHANNELS ASYS_AUDIOUNIT_STEREO
353
354 #if defined(ASYS_HASINPUT)
355 #define ASYS_AUDIOUNIT_INPUT_MAXCHANNELS ASYS_AUDIOUNIT_STEREO
356 #define ASYS_AUDIOUNIT_SUPPORTED_FORMATS 4
357 #else
358 #define ASYS_AUDIOUNIT_INPUT_MAXCHANNELS 0
359 #define ASYS_AUDIOUNIT_SUPPORTED_FORMATS 2
360 #endif
361
362 /* static input and output channels, from SAOL program */
363
364 #define ASYS_AUDIOUNIT_OUTPUT_CHANNELS (ENDBUS_output_bus - BUS_output_bus)
365
366 #if defined(ASYS_HASINPUT)
367 #define ASYS_AUDIOUNIT_INPUT_CHANNELS (ENDBUS_input_bus - BUS_input_bus)
368 #else
369 #define ASYS_AUDIOUNIT_INPUT_CHANNELS 0
370 #endif
371
372 /* element limits */
373
374 #if (ASYS_AUDIOUNIT_EFFECT)
375
376 #define ASYS_AUDIOUNIT_ELEMENT_INPUTPREF 1 /* our default */
377 #define ASYS_AUDIOUNIT_ELEMENT_INPUTMAX 8 /* maximum we accept */
378
379 #define ASYS_AUDIOUNIT_ELEMENT_OUTPUTPREF 1 /* our default */
380 #define ASYS_AUDIOUNIT_ELEMENT_OUTPUTMAX 1 /* maximum we accept */
381
382 #define ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE 8 /* for I-bound data structures */
383
384 #else
385
386 #define ASYS_AUDIOUNIT_ELEMENT_INPUTPREF 0 /* our default */
387 #define ASYS_AUDIOUNIT_ELEMENT_INPUTMAX 0 /* maximum we accept */
388
389 #define ASYS_AUDIOUNIT_ELEMENT_OUTPUTPREF 1 /* our default */
390 #define ASYS_AUDIOUNIT_ELEMENT_OUTPUTMAX 1 /* maximum we accept */
391
392 #define ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE 1 /* for I-bound data structures */
393
394 #endif
395
396 /* maximum number of frames per slice */
397
398 #define ASYS_AUDIOUNIT_FRAMES_PER_SLICE 4096
399
400 /* in-place processing not supported */
401
402 #define ASYS_AUDIOUNIT_INPLACE_PROCESSING 0
403
404 /* number of instruments -- only used by MusicDevice */
405
406 #define ASYS_AUDIOUNIT_INSTRUMENT_COUNT 1
407
408 /* constants for property listeners */
409
410 #define ASYS_AUDIOUNIT_PROPLISTEN_PARAMETERINFO 0
411 #define ASYS_AUDIOUNIT_PROPLISTEN_PARAMETERLIST 1
412 #define ASYS_AUDIOUNIT_PROPLISTEN_CPULOAD 2
413 #define ASYS_AUDIOUNIT_PROPLISTEN_LATENCY 3
414 #define ASYS_AUDIOUNIT_PROPLISTEN_TAILTIME 4
415 #define ASYS_AUDIOUNIT_PROPLISTEN_FACTORYPRESETS 5
416 #define ASYS_AUDIOUNIT_PROPLISTEN_RENDERQUALITY 6
417 #define ASYS_AUDIOUNIT_PROPLISTEN_CURRENTPRESET 7
418 #define ASYS_AUDIOUNIT_PROPLISTEN_PRESENTPRESET 8
419 #define ASYS_AUDIOUNIT_PROPLISTEN_STREAMFROMDISK 9
420 #define ASYS_AUDIOUNIT_PROPLISTEN_MAXIMUMFRAMESPERSLICE 10
421 #define ASYS_AUDIOUNIT_PROPLISTEN_ARRAYSIZE 11 /* ++ for each property added */
422
423 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
424 /* reset/paging behaviors */
425 /*___________________________*/
426
427 /* active reset does Uninitialize/Initialize for ResetSelect */
428
429 #define ASYS_AUDIOUNIT_PASSIVE_RESET 0
430 #define ASYS_AUDIOUNIT_ACTIVE_RESET 1
431 #define ASYS_AUDIOUNIT_RESET_TYPE ASYS_AUDIOUNIT_PASSIVE_RESET
432
433 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
434 /* istate-machine constants */
435 /*___________________________*/
436
437 #define ASYS_AUDIOUNIT_ISTATE_ABSENT 0
438 #define ASYS_AUDIOUNIT_ISTATE_INSTANCE 1
439 #define ASYS_AUDIOUNIT_ISTATE_INSTANCE_PASSING 2
440 #define ASYS_AUDIOUNIT_ISTATE_FLUX 3
441 #define ASYS_AUDIOUNIT_ISTATE_FLUX_PASSING 4
442 #define ASYS_AUDIOUNIT_ISTATE_ENGINE 5
443 #define ASYS_AUDIOUNIT_ISTATE_ENGINE_PASSING 6
444 #define ASYS_AUDIOUNIT_ISTATE_ENGINE_RENDER 7
445
446 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
447 /* istate-machine return values */
448 /*_______________________________*/
449
450 #define ASYS_AUDIOUNIT_IRESPONSE_COMPLETE 0
451 #define ASYS_AUDIOUNIT_IRESPONSE_INITIALIZE 1
452 #define ASYS_AUDIOUNIT_IRESPONSE_UNINITIALIZE 2
453 #define ASYS_AUDIOUNIT_IRESPONSE_CLOSE 3
454 #define ASYS_AUDIOUNIT_IRESPONSE_RENDER 4
455 #define ASYS_AUDIOUNIT_IRESPONSE_WIRE 5
456 #define ASYS_AUDIOUNIT_IRESPONSE_REINITIALIZE 6
457 #define ASYS_AUDIOUNIT_IRESPONSE_REUNINITIALIZE 7
458 #define ASYS_AUDIOUNIT_IRESPONSE_UNINITIALIZE_AND_CLOSE 8
459 #define ASYS_AUDIOUNIT_IRESPONSE_MY_IS_NULL 9
460 #define ASYS_AUDIOUNIT_IRESPONSE_ERROR 10
461
462 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
463 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
464 /* Control Driver Constants */
465 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
466 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
467
468 /* retry limit for socket writing */
469
470 #define ASYS_AUDIOUNIT_RETRY_MAX 256
471
472 /* bitfield constants for MIDIevent flags variable */
473
474 #define ASYS_AUDIOUNIT_MIDIFLAGS_WAITING 0x01u /* queuing flag bit */
475
476 /* bitfield constants for SASLevent flags variable */
477
478 #define ASYS_AUDIOUNIT_SASLFLAGS_WAITING 0x01u /* queuing flag bit */
479
480 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
481 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
482 /* SAOL Parameter Constants */
483 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
484 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
485
486 #define ASYS_AUDIOUNIT_PARAMETER_DEFAULT_UNIT kAudioUnitParameterUnit_Generic
487 #define ASYS_AUDIOUNIT_PARAMETER_DEFAULT_MINIMUM 0.0F
488 #define ASYS_AUDIOUNIT_PARAMETER_DEFAULT_MAXIMUM 1.0F
489 #define ASYS_AUDIOUNIT_PARAMETER_DEFAULT_DEFAULT 0.5F
490
491 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
492 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
493 /* TypeDefs */
494 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
495 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
496
497 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
498 /* typedef for a MIDI event */
499 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
500
501 typedef struct asysn_audiounit_MIDIevent {
502 unsigned char cmd;
503 unsigned char d0;
504 unsigned char d1;
505 unsigned char flags;
506 int kcycleidx;
507 } asysn_audiounit_MIDIevent;
508
509 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
510 /* typedef for a SASL event */
511 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
512
513 typedef struct asysn_audiounit_SASLevent {
514 int index;
515 Float32 value;
516 unsigned char flags;
517 int kcycleidx;
518 } asysn_audiounit_SASLevent;
519
520 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
521 /* typedef for SAOL parameter */
522 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
523
524 typedef struct asysn_audiounit_saolparam {
525 Float32 value;
526 int index;
527 int use;
528 } asysn_audiounit_saolparam;
529
530 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
531 /* typedef for a listener proc */
532 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
533
534 typedef struct asysn_audiounit_proplisten {
535 AudioUnitPropertyListenerProc lproc;
536 void * lrefcon;
537 struct asysn_audiounit_proplisten * next;
538 } asysn_audiounit_proplisten;
539
540 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
541 /* typedef for a render notify proc */
542 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
543
544 typedef struct asysn_audiounit_rendernotify {
545 AURenderCallback nproc;
546 void * nrefcon;
547 struct asysn_audiounit_rendernotify * next;
548 } asysn_audiounit_rendernotify;
549
550 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
551 /* typedef for instance state */
552 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
553
554 typedef struct asysn_audiounit_InstanceState {
555
556 ComponentInstance component; /* component instance ID */
557 volatile int istate; /* initialization state machine */
558 ENGINE_PTR_DECLARE_SEMICOLON /* engine pointer for the instance */
559
560 /*~~~~~~~~~~~~~~~~~~~~~~~*/
561 /* mirrored engine state */
562 /*~~~~~~~~~~~~~~~~~~~~~~~*/
563
564 UInt32 acycle;
565 Float32 krate;
566 volatile uint64_t acycleidx_kcycleidx;
567
568 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
569 /* current value of properties */
570 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
571
572 /* common to Effects and MusicDevices */
573
574 AudioUnitConnection MakeConnection[ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE];
575 Float32 CPULoad;
576 OSSpinLock lock_CPULoad;
577 AudioStreamBasicDescription OutputStreamFormat;
578 OSType SRCAlgorithm;
579 UInt32 InputElementCount;
580 UInt32 OutputElementCount;
581 Float64 Latency;
582 AUChannelInfo SupportedNumChannels[ASYS_AUDIOUNIT_SUPPORTED_FORMATS];
583 UInt32 MaximumFramesPerSlice;
584 Float64 TailTime;
585 UInt32 BypassEffect;
586 UInt32 LastBypassEffect;
587 OSStatus LastRenderError;
588 AURenderCallbackStruct SetRenderCallback[ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE];
589 asysn_audiounit_rendernotify * rendernotify;
590 OSSpinLock lock_rendernotify;
591 UInt32 RenderQuality;
592 UInt32 InPlaceProcessing;
593 AUPreset PresentPreset;
594 OSSpinLock lock_PresentPreset;
595 UInt32 OfflineRender;
596 Float64 PresentationLatency;
597 UInt32 StreamFromDisk;
598 asysn_audiounit_proplisten * proplisteners[ASYS_AUDIOUNIT_PROPLISTEN_ARRAYSIZE];
599 OSSpinLock lock_proplisteners;
600 OSSpinLock lock_sampledelivery; /* for MakeConnection and SetRenderCallback */
601
602 /* exclusive to MusicDevices and MusicEffects (?) */
603
604 UInt32 InstrumentCount;
605
606 /* properties exclusive to Effects */
607
608 AudioStreamBasicDescription InputStreamFormat[ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE];
609
610 /*~~~~~~~~~~~~~~~~~~~~*/
611 /* per-instance state */
612 /*~~~~~~~~~~~~~~~~~~~~*/
613
614 /* data output array: common to Effects and Music Devices */
615
616 Float32 * mData_Output[ASYS_AUDIOUNIT_OUTPUT_MAXCHANNELS];
617
618 /* rendering templates and data carriers: exclusive to Effects */
619
620 AudioBufferList * AudioBufferTemplate;
621 AudioBufferList * AudioBufferCarrier;
622
623 /*~~~~~~~~~~~~~~~~~~~~~*/
624 /* aup_ property state */
625 /*~~~~~~~~~~~~~~~~~~~~~*/
626
627 int num_saolparams;
628 AudioUnitParameterID * parameterlist;
629 AudioUnitParameterInfo * parameterinfo;
630 int * pvs_size;
631 char *** pvs_cstr;
632 asysn_audiounit_saolparam * saolparam;
633
634 int num_factory;
635 Float32 ** factorypreset_values;
636 AUPreset * factorypreset_info;
637 CFMutableArrayRef factorypreset_array;
638
639 /*~~~~~~~~~~~~~*/
640 /* ksync state */
641 /*~~~~~~~~~~~~~*/
642
643 UInt64 ksync_timespent; /* total time spent in one kpass */
644 Float32 ksync_normalize; /* unit translations: 1/ticks to Hz */
645 Float32 ksync_last_cpuload; /* used for missing data heuristic */
646
647 /*~~~~~~~~~~~~~~~~~~~~~~~~*/
648 /* state passed to engine */
649 /*~~~~~~~~~~~~~~~~~~~~~~~~*/
650
651 char componentname[32];
652
653 char mpipeflag[32];
654 char mpipevalue[32];
655
656 char spipeflag[32];
657 char spipevalue[32];
658
659 char * argv[5];
660 int argc;
661
662 /*~~~~~~~~~~~~~~~~~*/
663 /* aucontrol state */
664 /*~~~~~~~~~~~~~~~~~*/
665
666 int mpipepair[2];
667 int spipepair[2];
668
669 } asysn_audiounit_InstanceState;
670
671
672 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
673 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
674 /* The page-management system */
675 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
676 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
677
678 int asysn_audiounit_opencount = 0; /* number of audiounit instances */
679 OSSpinLock asysn_audiounit_lock_opencount; /* protects opencount */
680
681 /********************************************/
682 /* set memory status of a region of memory */
683 /********************************************/
684
asysn_audiounit_memstatus(void * addr,size_t len,int advice)685 void asysn_audiounit_memstatus(void * addr, size_t len, int advice)
686
687 {
688 madvise((caddr_t) addr, len, advice);
689 return;
690 }
691
692
693 /*~~~~~~~~~~~~~~~~~~~*/
694 /*~~~~~~~~~~~~~~~~~~~*/
695 /* The ksync system */
696 /*~~~~~~~~~~~~~~~~~~~*/
697 /*~~~~~~~~~~~~~~~~~~~*/
698
699 /*********************************************/
700 /* startup initialization for ksync system */
701 /*********************************************/
702
asysn_audiounit_ksyncinit(asysn_audiounit_InstanceState * My)703 void asysn_audiounit_ksyncinit(asysn_audiounit_InstanceState * My)
704
705 {
706 My->ksync_timespent = 0;
707
708 OSSpinLockLock(&(My->lock_CPULoad));
709
710 My->ksync_normalize = (Float32) (My->krate/AudioGetHostClockFrequency());
711 if (My->CPULoad)
712 My->ksync_normalize = My->ksync_normalize/My->CPULoad;
713
714 OSSpinLockUnlock(&(My->lock_CPULoad));
715
716 My->ksync_last_cpuload = 0.0F;
717 }
718
719 /********************************************/
720 /* computes cpuload value at end of a kpass */
721 /********************************************/
722
asysn_audiounit_ksync(asysn_audiounit_InstanceState * My)723 Float32 asysn_audiounit_ksync(asysn_audiounit_InstanceState * My)
724
725 {
726 UInt64 now = AudioGetCurrentHostTime();
727 Float32 ret;
728
729 ret = My->ksync_normalize*((Float32)(now - My->ksync_timespent));
730
731 if (ret > 1.0F)
732 ret = 1.0F;
733
734 if (ret < 1.0F)
735 My->ksync_last_cpuload = ret;
736 else
737 {
738 ret = My->ksync_last_cpuload;
739 My->ksync_last_cpuload = 1.0F;
740 }
741
742 My->ksync_timespent = now;
743
744 return ret;
745 }
746
747
748 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
749 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
750 /* Fast Dispatch Functions */
751 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
752 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
753
754 /***********************************************/
755 /* Helper Routine for MIDIEvent Fast Dispatch */
756 /***********************************************/
757
asysn_audiounit_sendMIDIevent(asysn_audiounit_MIDIevent * MIDIevent,asysn_audiounit_InstanceState * My)758 ComponentResult asysn_audiounit_sendMIDIevent(asysn_audiounit_MIDIevent * MIDIevent,
759 asysn_audiounit_InstanceState * My)
760
761 {
762 uint64_t acycleidx_kcycleidx;
763 int32_t acycleidx, kcycleidx;
764 int write_failed = 0;
765 int retry = 0;
766 int acount;
767
768 if (!ASYS_AUDIOUNIT_HAS_AUCONTROL)
769 return noErr;
770
771 /* on entry, MIDIevent->kcycle holds offset of event (in samples) from the */
772 /* start of the next buffer. This start time in the sfront engine is coded */
773 /* by the tuple (kcycleidx, acycleidx). */
774
775 acycleidx_kcycleidx = My->acycleidx_kcycleidx;
776 kcycleidx = (int32_t)(acycleidx_kcycleidx & 0x00000000FFFFFFFF);
777 acycleidx = (int32_t)(acycleidx_kcycleidx >> 32);
778
779 acount = acycleidx + MIDIevent->kcycleidx;
780 MIDIevent->kcycleidx = kcycleidx;
781
782 /* initialization of acycleidx_kcycleidx skirts zero-time condition issue */
783
784 while (acount >= My->acycle)
785 {
786 acount -= My->acycle;
787 MIDIevent->kcycleidx++;
788 }
789
790 while (write(My->mpipepair[1], MIDIevent, sizeof(asysn_audiounit_MIDIevent)) < 0)
791 if ((errno != EINTR) || (++retry >= ASYS_AUDIOUNIT_RETRY_MAX))
792 {
793 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING("\tSocket write error in sendMIDIevent\n\n");
794 write_failed = 1;
795 break;
796 }
797
798 return noErr;
799 }
800
801 /***********************************/
802 /* MIDIEvent Fast Dispatch Handler */
803 /***********************************/
804
asysn_audiounit_MyMIDIEventProc(void * inComponentStorage,UInt32 inStatus,UInt32 inData1,UInt32 inData2,UInt32 inOffsetSampleFrame)805 ComponentResult asysn_audiounit_MyMIDIEventProc(void * inComponentStorage,
806 UInt32 inStatus,
807 UInt32 inData1,
808 UInt32 inData2,
809 UInt32 inOffsetSampleFrame)
810 {
811 asysn_audiounit_MIDIevent MIDIevent;
812 int result;
813
814 if (!inComponentStorage) /* avoid race condition */
815 return noErr;
816
817 MIDIevent.cmd = (unsigned char) inStatus;
818 MIDIevent.d0 = (unsigned char)inData1;
819 MIDIevent.d1 = (unsigned char)inData2;
820 MIDIevent.flags = ASYS_AUDIOUNIT_MIDIFLAGS_WAITING;
821 MIDIevent.kcycleidx = (int) inOffsetSampleFrame;
822
823 result = asysn_audiounit_sendMIDIevent
824 (&MIDIevent, (asysn_audiounit_InstanceState *) inComponentStorage);
825
826 ASYS_AUDIOUNIT_WIRETAP_MIDIEVENT(inComponentStorage, inStatus, inData1,
827 inData2, inOffsetSampleFrame, "Fast Dispatch");
828
829 return result;
830 }
831
832 /**************************************************/
833 /* Helper Routine for GetParameter Fast Dispatch */
834 /**************************************************/
835
asysn_audiounit_getSASLevent(AudioUnitParameterID inID,Float32 * outValue,asysn_audiounit_InstanceState * My)836 ComponentResult asysn_audiounit_getSASLevent(AudioUnitParameterID inID,
837 Float32 * outValue,
838 asysn_audiounit_InstanceState * My)
839
840 {
841 if (inID >= My->num_saolparams)
842 return kAudioUnitErr_InvalidParameter;
843
844 *outValue = My->saolparam[inID].value;
845 return noErr;
846 }
847
848 /**************************************/
849 /* GetParameter Fast Dispatch Handler */
850 /**************************************/
851
asysn_audiounit_MyGetParameterProc(void * inComponentStorage,AudioUnitParameterID inID,AudioUnitScope inScope,AudioUnitElement inElement,Float32 * outValue)852 ComponentResult asysn_audiounit_MyGetParameterProc(void * inComponentStorage,
853 AudioUnitParameterID inID,
854 AudioUnitScope inScope,
855 AudioUnitElement inElement,
856 Float32 * outValue)
857 {
858 int result;
859
860 if (!inComponentStorage) /* avoid race condition */
861 return noErr;
862
863 if (inScope != kAudioUnitScope_Global) /* inScope */
864 return kAudioUnitErr_InvalidScope;
865
866 result = asysn_audiounit_getSASLevent
867 (inID, outValue, (asysn_audiounit_InstanceState *) inComponentStorage);
868
869 ASYS_AUDIOUNIT_WIRETAP_GETPARAMETER(inComponentStorage, inID, inScope,
870 inElement, outValue, "Fast Dispatch");
871
872 return result;
873 }
874
875 /**************************************************/
876 /* Helper Routine for SetParameter Fast Dispatch */
877 /**************************************************/
878
asysn_audiounit_sendSASLevent(asysn_audiounit_SASLevent * SASLevent,asysn_audiounit_InstanceState * My)879 ComponentResult asysn_audiounit_sendSASLevent(asysn_audiounit_SASLevent * SASLevent,
880 asysn_audiounit_InstanceState * My)
881
882 {
883 uint64_t acycleidx_kcycleidx;
884 int32_t acycleidx, kcycleidx;
885 int write_failed = 0;
886 int retry = 0;
887 int acount;
888
889 if (!ASYS_AUDIOUNIT_HAS_AUCONTROL)
890 return noErr;
891
892 /* on entry: */
893 /* SASLevent->index holds AudioUnit index (not SAOL index) and */
894 /* has been range-checked. */
895 /* */
896 /* SASLevent->value is range-checked. */
897 /* */
898 /* SASLevent->flags is not set. */
899 /* */
900 /* SASLevent->kcycle holds offset of event (in samples) from */
901 /* the start of the next buffer. This start time in the sfront */
902 /* engine is coded by the tuple (kcycleidx, acycleidx). */
903
904 SASLevent->index = My->saolparam[SASLevent->index].index;
905 SASLevent->flags = ASYS_AUDIOUNIT_SASLFLAGS_WAITING;
906
907 acycleidx_kcycleidx = My->acycleidx_kcycleidx;
908 kcycleidx = (int32_t)(acycleidx_kcycleidx & 0x00000000FFFFFFFF);
909 acycleidx = (int32_t)(acycleidx_kcycleidx >> 32);
910
911 acount = acycleidx + SASLevent->kcycleidx;
912 SASLevent->kcycleidx = kcycleidx;
913
914 /* initialization of acycleidx_kcycleidx skirts zero-time condition issue */
915
916 while (acount >= My->acycle)
917 {
918 acount -= My->acycle;
919 SASLevent->kcycleidx++;
920 }
921
922 while (write(My->spipepair[1], SASLevent, sizeof(asysn_audiounit_SASLevent)) < 0)
923 if ((errno != EINTR) || (++retry >= ASYS_AUDIOUNIT_RETRY_MAX))
924 {
925 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING("\tSocket write error in sendSASLevent\n\n");
926 write_failed = 1;
927 break;
928 }
929
930 return noErr;
931 }
932
933 /**************************************/
934 /* SetParameter Fast Dispatch Handler */
935 /**************************************/
936
asysn_audiounit_MySetParameterProc(void * inComponentStorage,AudioUnitParameterID inID,AudioUnitScope inScope,AudioUnitElement inElement,Float32 inValue,UInt32 inBufferOffsetInFrames)937 ComponentResult asysn_audiounit_MySetParameterProc(void * inComponentStorage,
938 AudioUnitParameterID inID,
939 AudioUnitScope inScope,
940 AudioUnitElement inElement,
941 Float32 inValue,
942 UInt32 inBufferOffsetInFrames)
943 {
944 asysn_audiounit_InstanceState * My;
945 asysn_audiounit_SASLevent SASLevent;
946 int result;
947
948 My = ((asysn_audiounit_InstanceState *) inComponentStorage);
949
950 if (!My) /* avoid race condition */
951 return noErr;
952
953 if ((inID < 0) || (inID >= My->num_saolparams)) /* range-check ID */
954 return kAudioUnitErr_InvalidParameter;
955
956 if (inScope != kAudioUnitScope_Global) /* inScope */
957 return kAudioUnitErr_InvalidScope;
958
959 if (inValue > My->parameterinfo[inID].maxValue)
960 inValue = My->parameterinfo[inID].maxValue;
961
962 if (inValue < My->parameterinfo[inID].minValue)
963 inValue = My->parameterinfo[inID].minValue;
964
965 SASLevent.index = inID;
966 SASLevent.value = My->saolparam[inID].value = inValue;
967 SASLevent.kcycleidx = (int)(inBufferOffsetInFrames);
968
969 result = asysn_audiounit_sendSASLevent(&SASLevent, My);
970
971 ASYS_AUDIOUNIT_WIRETAP_SETPARAMETER(My, inID, inScope,
972 inElement, inValue, inBufferOffsetInFrames,
973 "Fast Dispatch");
974
975 return result;
976 }
977
978 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
979 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
980 /* AUEventListenerNotify support */
981 /* */
982 /* To let global variable writes */
983 /* by SAOL programs be seen in UI */
984 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
985 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
986
987 /************************************************/
988 /* checks all variables, does update if needed */
989 /************************************************/
990
asysn_audiounit_eventlistenernotify(asysn_audiounit_InstanceState * My)991 void asysn_audiounit_eventlistenernotify(asysn_audiounit_InstanceState * My)
992
993 {
994 ENGINE_PTR_DECLARE_SEMICOLON
995 AudioUnitEvent event;
996 Float32 value;
997 int i;
998
999 ENGINE_PTR_ASSIGNED_TO MY_ENGINE_PTR; /* for NG() reference */
1000
1001 for (i = 0; i < My->num_saolparams; i++)
1002 if (My->saolparam[i].use & CSYS_WRITTEN)
1003 if ((value = NG(My->saolparam[i].index)) != My->saolparam[i].value)
1004 {
1005 if (value > My->parameterinfo[i].maxValue)
1006 NG(My->saolparam[i].index) = value = My->parameterinfo[i].maxValue;
1007 if (value < My->parameterinfo[i].minValue)
1008 NG(My->saolparam[i].index) = value = My->parameterinfo[i].minValue;
1009
1010 if (value != My->saolparam[i].value)
1011 {
1012 My->saolparam[i].value = value;
1013 event.mEventType = kAudioUnitEvent_ParameterValueChange;
1014 event.mArgument.mParameter.mAudioUnit = My->component;
1015 event.mArgument.mParameter.mParameterID = i;
1016 event.mArgument.mParameter.mScope = kAudioUnitScope_Global;
1017 event.mArgument.mParameter.mElement = 0;
1018 OSMemoryBarrier();
1019 AUEventListenerNotify(NULL, NULL, &event);
1020 }
1021 }
1022 }
1023
1024 /*------------------------------------------*/
1025 /* Specialized Renderers for Each AU Type */
1026 /*------------------------------------------*/
1027
1028 #if ASYS_AUDIOUNIT_MUSICDEVICE
1029
1030 /************************************************************/
1031 /* Helper Routine For Fast-Dispatch Renderer -- MusicDevice */
1032 /************************************************************/
1033
asysn_audiounit_activeo_renderer(asysn_audiounit_InstanceState * My,AudioBufferList * ioData)1034 void asysn_audiounit_activeo_renderer(asysn_audiounit_InstanceState * My,
1035 AudioBufferList * ioData)
1036
1037 {
1038 ENGINE_PTR_DECLARE_SEMICOLON
1039 UInt32 frames = ioData->mBuffers[0].mDataByteSize/sizeof(Float32);
1040 Float32 eincr, escale;
1041 UInt32 do_effect, do_bypass;
1042 Float32 * out_left, * out_right;
1043 Float32 left;
1044 #if (ASYS_AUDIOUNIT_OUTPUT_CHANNELS > ASYS_AUDIOUNIT_MONO)
1045 Float32 right;
1046 #endif
1047
1048 ENGINE_PTR_ASSIGNED_TO MY_ENGINE_PTR;
1049
1050
1051 if (My->BypassEffect == 0)
1052 {
1053 if (My->LastBypassEffect == 0)
1054 {
1055 do_effect = 1;
1056 do_bypass = 0;
1057 eincr = escale = 0.0F;
1058 }
1059 else
1060 {
1061 do_effect = 1;
1062 do_bypass = 1;
1063 eincr = escale = 1.0F/(frames + 1);
1064 My->LastBypassEffect = 0;
1065 }
1066 }
1067 else
1068 {
1069 if (My->LastBypassEffect == 1)
1070 {
1071 do_effect = 0;
1072 do_bypass = 1;
1073 eincr = escale = 0.0F;
1074 }
1075 else
1076 {
1077 do_effect = 1;
1078 do_bypass = 1;
1079 eincr = - 1.0F/(frames + 1);
1080 escale = 1.0F + eincr;
1081 My->LastBypassEffect = 1;
1082 }
1083 }
1084
1085 out_left = (Float32 *) (ioData->mBuffers[0].mData);
1086
1087 if (ioData->mNumberBuffers > ASYS_AUDIOUNIT_MONO)
1088 out_right = (Float32 *) (ioData->mBuffers[1].mData);
1089 else
1090 out_right = NULL;
1091
1092 while (frames)
1093 if (EV(acycleidx) < EV(ACYCLE))
1094 {
1095 memset(&(TB(0)), 0, ENDBUS*sizeof(ASYS_OTYPE)); /* set bus to silence */
1096 main_apass(ENGINE_PTR); /* compute samples */
1097
1098 if (do_effect)
1099 {
1100 left = TB(BUS_output_bus);
1101
1102 #if (ASYS_AUDIOUNIT_OUTPUT_CLIPPING)
1103 if ((left > 1.0F) || (left < -1.0F))
1104 left = (left > 0) ? 1.0F : -1.0F;
1105 #endif
1106 *out_left = left;
1107
1108 if (out_right)
1109 {
1110 #if (ASYS_AUDIOUNIT_OUTPUT_CHANNELS == ASYS_AUDIOUNIT_MONO)
1111 *out_right = left;
1112 #else
1113 right = TB(BUS_output_bus + 1);
1114
1115 #if (ASYS_AUDIOUNIT_OUTPUT_CLIPPING)
1116 if ((right > 1.0F) || (right < -1.0F))
1117 right = (right > 0) ? 1.0F : -1.0F;
1118 #endif
1119 *out_right = right;
1120 #endif
1121 }
1122 else
1123 {
1124 #if (ASYS_AUDIOUNIT_OUTPUT_CHANNELS > ASYS_AUDIOUNIT_MONO)
1125 right = TB(BUS_output_bus + 1);
1126
1127 #if (ASYS_AUDIOUNIT_OUTPUT_CLIPPING)
1128 if ((right > 1.0F) || (right < -1.0F))
1129 right = (right > 0) ? 1.0F : -1.0F;
1130 #endif
1131 *out_left += right;
1132 *out_left *= 0.5F;
1133 #endif
1134 }
1135
1136 if (do_bypass)
1137 {
1138 *out_left *= escale;
1139 if (out_right)
1140 *out_right *= escale;
1141 escale += eincr;
1142 }
1143 }
1144
1145 if (do_bypass && !do_effect)
1146 {
1147 *out_left = 0.0F;
1148
1149 if (out_right)
1150 *out_right = 0.0F;
1151 }
1152
1153 out_left++;
1154
1155 if (out_right)
1156 out_right++;
1157
1158 EV(acycleidx)++; frames--; /* update all positions */
1159 }
1160 else
1161 {
1162 EV(acycleidx) = 0;
1163 if (EV(pass) == APASS)
1164 {
1165 EV(cpuload) = asysn_audiounit_ksync(My);
1166 EV(kcycleidx)++; /* we run forever; don't test against endkcycle */
1167 }
1168 EV(pass) = IPASS;
1169 EV(scorebeats) = EV(scoremult)*(EV(kcycleidx) - EV(kbase)) + EV(scorebase);
1170 EV(absolutetime) = (EV(kcycleidx) - 1)*EV(KTIME);
1171 main_ipass(ENGINE_PTR);
1172 EV(pass) = KPASS;
1173 main_control(ENGINE_PTR);
1174 main_kpass(ENGINE_PTR); /* we run forever; don't check return value */
1175 if (ASYS_AUDIOUNIT_PARAMETERS_WRITTEN)
1176 asysn_audiounit_eventlistenernotify(My);
1177 EV(pass) = APASS;
1178 }
1179
1180 My->acycleidx_kcycleidx = (((uint64_t) (EV(kcycleidx))) & 0x00000000FFFFFFFF) |
1181 (((uint64_t) (EV(acycleidx))) << 32);
1182 }
1183
1184 /*****************************************/
1185 /* Fast-Dispatch Renderer -- MusicDevice */
1186 /*****************************************/
1187
asysn_audiounit_MyRenderer(void * inComponentStorage,AudioUnitRenderActionFlags * ioActionFlags,const AudioTimeStamp * inTimeStamp,UInt32 inOutputBusNumber,UInt32 inNumberFrames,AudioBufferList * ioData)1188 ComponentResult asysn_audiounit_MyRenderer(void * inComponentStorage,
1189 AudioUnitRenderActionFlags * ioActionFlags,
1190 const AudioTimeStamp * inTimeStamp,
1191 UInt32 inOutputBusNumber,
1192 UInt32 inNumberFrames,
1193 AudioBufferList * ioData)
1194 {
1195 UInt32 error_code;
1196 char message[128];
1197 asysn_audiounit_rendernotify * notify;
1198 AudioUnitRenderActionFlags action_flags;
1199 asysn_audiounit_InstanceState * My = ((asysn_audiounit_InstanceState *)
1200 inComponentStorage);
1201 int i, iresponse;
1202
1203 if (inNumberFrames > ASYS_AUDIOUNIT_FRAMES_PER_SLICE)
1204 return kAudioUnitErr_TooManyFramesToProcess;
1205
1206 if (!My)
1207 return kAudioUnitErr_Uninitialized; /* avoid race condition */
1208
1209 switch(iresponse = asysn_audiounit_realtime_enterstate(My)) {
1210 case ASYS_AUDIOUNIT_IRESPONSE_WIRE:
1211 case ASYS_AUDIOUNIT_IRESPONSE_RENDER:
1212 break;
1213 case ASYS_AUDIOUNIT_IRESPONSE_MY_IS_NULL:
1214 case ASYS_AUDIOUNIT_IRESPONSE_ERROR:
1215 default:
1216 return kAudioUnitErr_Uninitialized; /* avoid race condition, bugs */
1217 }
1218
1219 /* supply return buffers (only!) if needed */
1220
1221 for (i = 0; i < ioData->mNumberBuffers; i++)
1222 if (ioData->mBuffers[i].mData == NULL)
1223 ioData->mBuffers[i].mData = (void *) My->mData_Output[i];
1224
1225 /* do PreRender notification */
1226
1227 OSSpinLockLock(&(My->lock_rendernotify));
1228
1229 notify = My->rendernotify;
1230 while (notify)
1231 {
1232 if (notify->nproc)
1233 {
1234 action_flags = kAudioUnitRenderAction_PreRender;
1235
1236 if (error_code = ((* notify->nproc)
1237 (notify->nrefcon, &action_flags,
1238 inTimeStamp, (AudioUnitElement) 0, inNumberFrames,
1239 ioData)))
1240 {
1241 sprintf(message, "\nasysn_audiounit_MyRenderer"
1242 "\n\tError: PreRender Rendernotify callback"
1243 " returned OSType %u\n", (unsigned int) error_code);
1244 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING(message);
1245 }
1246 }
1247 notify = notify->next;
1248 }
1249
1250 OSSpinLockUnlock(&(My->lock_rendernotify));
1251
1252 /* the actual rendering done by the audio unit */
1253
1254 if (iresponse == ASYS_AUDIOUNIT_IRESPONSE_RENDER)
1255 {
1256 My->ksync_timespent = AudioGetCurrentHostTime() - My->ksync_timespent;
1257 asysn_audiounit_activeo_renderer(My, ioData);
1258 My->ksync_timespent = AudioGetCurrentHostTime() - My->ksync_timespent;
1259 }
1260 else /* for _WIRE, zero all buffers */
1261 for (i = 0; i < ioData->mNumberBuffers; i++)
1262 memset(ioData->mBuffers[i].mData, 0, sizeof(Float32)*inNumberFrames);
1263
1264 /* do PostRender notification */
1265
1266 OSSpinLockLock(&(My->lock_rendernotify));
1267
1268 notify = My->rendernotify;
1269 while (notify)
1270 {
1271 if (notify->nproc)
1272 {
1273 action_flags = kAudioUnitRenderAction_PostRender;
1274
1275 if (error_code = ((* notify->nproc)
1276 (notify->nrefcon, &action_flags,
1277 inTimeStamp, (AudioUnitElement) 0, inNumberFrames,
1278 ioData)))
1279 {
1280 sprintf(message, "\nasysn_audiounit_MyRenderer"
1281 "\n\tError: PostRender Rendernotify callback"
1282 " returned OSType %u\n", (unsigned int) error_code);
1283 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING(message);
1284 }
1285 }
1286 notify = notify->next;
1287 }
1288
1289 OSSpinLockUnlock(&(My->lock_rendernotify));
1290
1291 asysn_audiounit_realtime_exitstate(My);
1292
1293 return noErr;
1294 }
1295
1296 #endif /* ASYS_AUDIOUNIT_MUSICDEVICE */
1297
1298
1299 #if ASYS_AUDIOUNIT_EFFECT
1300
1301 /********************************************************/
1302 /* Helper Routine For Fast-Dispatch Renderer -- Effects */
1303 /********************************************************/
1304
asysn_audiounit_activeio_renderer(asysn_audiounit_InstanceState * My,AudioBufferList * ioData)1305 void asysn_audiounit_activeio_renderer(asysn_audiounit_InstanceState * My,
1306 AudioBufferList * ioData)
1307
1308 {
1309 ENGINE_PTR_DECLARE_SEMICOLON
1310 UInt32 frames = ioData->mBuffers[0].mDataByteSize/sizeof(Float32);
1311 Float32 eincr, bincr, escale, bscale;
1312 UInt32 do_effect, do_bypass;
1313 Float32 * out_left, * out_right, * in_left, * in_right;
1314 Float32 left;
1315 #if (ASYS_AUDIOUNIT_OUTPUT_CHANNELS > ASYS_AUDIOUNIT_MONO)
1316 Float32 right;
1317 #endif
1318
1319 ENGINE_PTR_ASSIGNED_TO MY_ENGINE_PTR;
1320
1321 if (My->BypassEffect == 0)
1322 {
1323 if (My->LastBypassEffect == 0)
1324 {
1325 do_effect = 1;
1326 do_bypass = 0;
1327 eincr = bincr = bscale = escale = 0.0F;
1328 }
1329 else
1330 {
1331 do_effect = 1;
1332 do_bypass = 1;
1333 eincr = escale = 1.0F/(frames + 1);
1334 bincr = - eincr;
1335 bscale = 1.0F - eincr;
1336 My->LastBypassEffect = 0;
1337 }
1338 }
1339 else
1340 {
1341 if (My->LastBypassEffect == 1)
1342 {
1343 do_effect = 0;
1344 do_bypass = 1;
1345 eincr = bincr = bscale = escale = 0.0F;
1346 }
1347 else
1348 {
1349 do_effect = 1;
1350 do_bypass = 1;
1351 bincr = bscale = 1.0F/(frames + 1);
1352 eincr = - bincr;
1353 escale = 1.0F - bincr;
1354 My->LastBypassEffect = 1;
1355 }
1356 }
1357
1358 out_left = (Float32 *) (ioData->mBuffers[0].mData);
1359
1360 if (ioData->mNumberBuffers > ASYS_AUDIOUNIT_MONO)
1361 out_right = (Float32 *) (ioData->mBuffers[1].mData);
1362 else
1363 out_right = NULL;
1364
1365 in_left = (Float32 *) (My->AudioBufferCarrier->mBuffers[0].mData);
1366
1367 if (My->AudioBufferCarrier->mNumberBuffers > ASYS_AUDIOUNIT_MONO)
1368 in_right = (Float32 *) (My->AudioBufferCarrier->mBuffers[1].mData);
1369 else
1370 in_right = NULL;
1371
1372 while (frames)
1373 if (EV(acycleidx) < EV(ACYCLE))
1374 {
1375 memset(&(TB(0)), 0, ENDBUS*sizeof(ASYS_OTYPE)); /* set bus to silence */
1376
1377 TB(BUS_input_bus) = *in_left;
1378
1379 if (in_right)
1380 {
1381 #if (ASYS_AUDIOUNIT_INPUT_CHANNELS > ASYS_AUDIOUNIT_MONO)
1382 TB(BUS_input_bus + 1) = *in_right;
1383 #else
1384 TB(BUS_input_bus) += *in_right;
1385 TB(BUS_input_bus) *= 0.5F;
1386 #endif
1387 }
1388 else
1389 {
1390 #if (ASYS_AUDIOUNIT_INPUT_CHANNELS > ASYS_AUDIOUNIT_MONO)
1391 TB(BUS_input_bus + 1) = *in_left;
1392 #endif
1393 }
1394
1395 main_apass(ENGINE_PTR); /* compute samples */
1396
1397 if (do_effect)
1398 {
1399 left = TB(BUS_output_bus);
1400
1401 #if (ASYS_AUDIOUNIT_OUTPUT_CLIPPING)
1402 if ((left > 1.0F) || (left < -1.0F))
1403 left = (left > 0) ? 1.0F : -1.0F;
1404 #endif
1405 *out_left = left;
1406
1407 if (out_right)
1408 {
1409 #if (ASYS_AUDIOUNIT_OUTPUT_CHANNELS == ASYS_AUDIOUNIT_MONO)
1410 *out_right = left;
1411 #else
1412 right = TB(BUS_output_bus + 1);
1413
1414 #if (ASYS_AUDIOUNIT_OUTPUT_CLIPPING)
1415 if ((right > 1.0F) || (right < -1.0F))
1416 right = (right > 0) ? 1.0F : -1.0F;
1417 #endif
1418 *out_right = right;
1419 #endif
1420 }
1421 else
1422 {
1423 #if (ASYS_AUDIOUNIT_OUTPUT_CHANNELS > ASYS_AUDIOUNIT_MONO)
1424 right = TB(BUS_output_bus + 1);
1425
1426 #if (ASYS_AUDIOUNIT_OUTPUT_CLIPPING)
1427 if ((right > 1.0F) || (right < -1.0F))
1428 right = (right > 0) ? 1.0F : -1.0F;
1429 #endif
1430 *out_left += right;
1431 *out_left *= 0.5F;
1432 #endif
1433 }
1434 }
1435
1436 if (do_bypass)
1437 {
1438 if (!do_effect)
1439 *out_left = *in_left;
1440 else
1441 {
1442 if (out_right || !in_right)
1443 *out_left = escale*(*out_left) + bscale*(*in_left);
1444 else
1445 *out_left = escale*(*out_left) + bscale*0.5F*(*in_left);
1446 }
1447
1448 if (out_right)
1449 {
1450 if (!do_effect)
1451 {
1452 if (in_right)
1453 *out_right = *in_right;
1454 else
1455 *out_right = *in_left;
1456 }
1457 else
1458 {
1459 if (in_right)
1460 *out_right = escale*(*out_right) + bscale*(*in_right);
1461 else
1462 *out_right = escale*(*out_right) + bscale*(*in_left);
1463 }
1464 }
1465 else
1466 {
1467 if (in_right)
1468 {
1469 if (!do_effect)
1470 *out_left = 0.5F*(*out_left + *in_right);
1471 else
1472 *out_left = *out_left + bscale*0.5F*(*in_right);
1473 }
1474 }
1475
1476 if (do_effect)
1477 {
1478 bscale += bincr;
1479 escale += eincr;
1480 }
1481 }
1482
1483 in_left++;
1484 out_left++;
1485
1486 if (in_right)
1487 in_right++;
1488
1489 if (out_right)
1490 out_right++;
1491
1492 EV(acycleidx)++; frames--; /* updates */
1493 }
1494 else
1495 {
1496 EV(acycleidx) = 0;
1497 if (EV(pass) == APASS)
1498 {
1499 EV(cpuload) = asysn_audiounit_ksync(My);
1500 EV(kcycleidx)++; /* we run forever; don't test against endkcycle */
1501 }
1502 EV(pass) = IPASS;
1503 EV(scorebeats) = EV(scoremult)*(EV(kcycleidx) - EV(kbase)) + EV(scorebase);
1504 EV(absolutetime) = (EV(kcycleidx) - 1)*EV(KTIME);
1505 main_ipass(ENGINE_PTR);
1506 EV(pass) = KPASS;
1507 main_control(ENGINE_PTR);
1508 main_kpass(ENGINE_PTR); /* we run forever; don't check return value */
1509 if (ASYS_AUDIOUNIT_PARAMETERS_WRITTEN)
1510 asysn_audiounit_eventlistenernotify(My);
1511 EV(pass) = APASS;
1512 }
1513
1514 My->acycleidx_kcycleidx = (((uint64_t) (EV(kcycleidx))) & 0x00000000FFFFFFFF) |
1515 (((uint64_t) (EV(acycleidx))) << 32);
1516 }
1517
1518 /**********************************************************/
1519 /* Helper Routine For Fast-Dispatch Renderer -- Pass-thru */
1520 /**********************************************************/
1521
asysn_audiounit_activeio_passthru(asysn_audiounit_InstanceState * My,AudioBufferList * ioData)1522 void asysn_audiounit_activeio_passthru(asysn_audiounit_InstanceState * My,
1523 AudioBufferList * ioData)
1524
1525 {
1526 UInt32 frames = ioData->mBuffers[0].mDataByteSize/sizeof(Float32);
1527 Float32 * out_left, * out_right, * in_left, * in_right;
1528
1529 out_left = (Float32 *) (ioData->mBuffers[0].mData);
1530
1531 if (ioData->mNumberBuffers > ASYS_AUDIOUNIT_MONO)
1532 out_right = (Float32 *) (ioData->mBuffers[1].mData);
1533 else
1534 out_right = NULL;
1535
1536 in_left = (Float32 *) (My->AudioBufferCarrier->mBuffers[0].mData);
1537
1538 if (My->AudioBufferCarrier->mNumberBuffers > ASYS_AUDIOUNIT_MONO)
1539 in_right = (Float32 *) (My->AudioBufferCarrier->mBuffers[1].mData);
1540 else
1541 in_right = NULL;
1542
1543 while (frames)
1544 {
1545 *out_left = *in_left;
1546
1547 if (out_right)
1548 {
1549 if (in_right)
1550 *out_right = *in_right;
1551 else
1552 *out_right = *in_left;
1553 }
1554 else
1555 if (in_right)
1556 *out_left = 0.5F*(*out_left + *in_right);
1557
1558 in_left++;
1559 out_left++;
1560
1561 if (in_right)
1562 in_right++;
1563
1564 if (out_right)
1565 out_right++;
1566
1567 frames--;
1568 }
1569 }
1570
1571
1572 /*************************************/
1573 /* Fast-Dispatch Renderer -- Effects */
1574 /*************************************/
1575
asysn_audiounit_MyRenderer(void * inComponentStorage,AudioUnitRenderActionFlags * ioActionFlags,const AudioTimeStamp * inTimeStamp,UInt32 inOutputBusNumber,UInt32 inNumberFrames,AudioBufferList * ioData)1576 ComponentResult asysn_audiounit_MyRenderer(void * inComponentStorage,
1577 AudioUnitRenderActionFlags * ioActionFlags,
1578 const AudioTimeStamp * inTimeStamp,
1579 UInt32 inOutputBusNumber,
1580 UInt32 inNumberFrames,
1581 AudioBufferList * ioData)
1582 {
1583 UInt32 error_code;
1584 char message[128];
1585 asysn_audiounit_rendernotify * notify;
1586 AudioUnitRenderActionFlags action_flags;
1587 AudioTimeStamp AudioTimeStampCarrier;
1588 asysn_audiounit_InstanceState * My = ((asysn_audiounit_InstanceState *)
1589 inComponentStorage);
1590 ComponentResult return_value;
1591 int i, iresponse;
1592
1593 if (inNumberFrames > ASYS_AUDIOUNIT_FRAMES_PER_SLICE)
1594 return kAudioUnitErr_TooManyFramesToProcess;
1595
1596 if (!My)
1597 return kAudioUnitErr_Uninitialized; /* avoid race condition */
1598
1599 switch(iresponse = asysn_audiounit_realtime_enterstate(My)) {
1600 case ASYS_AUDIOUNIT_IRESPONSE_WIRE:
1601 case ASYS_AUDIOUNIT_IRESPONSE_RENDER:
1602 break;
1603 case ASYS_AUDIOUNIT_IRESPONSE_MY_IS_NULL:
1604 case ASYS_AUDIOUNIT_IRESPONSE_ERROR:
1605 default:
1606 return kAudioUnitErr_Uninitialized; /* avoid race condition, bugs */
1607 }
1608
1609 return_value = noErr;
1610 action_flags = 0;
1611
1612 /* prepare AudioTimeStampCarrier */
1613
1614 memset(&AudioTimeStampCarrier, 0, sizeof(AudioTimeStamp));
1615 AudioTimeStampCarrier.mSampleTime = inTimeStamp->mSampleTime;
1616 AudioTimeStampCarrier.mFlags = kAudioTimeStampSampleTimeValid;
1617
1618 /* prepare AudioBufferCarrier */
1619
1620 memcpy(My->AudioBufferCarrier, My->AudioBufferTemplate,
1621 sizeof(UInt32) + My->AudioBufferTemplate->mNumberBuffers*sizeof(AudioBuffer));
1622
1623 for (i = 0; i < My->AudioBufferCarrier->mNumberBuffers; i++)
1624 My->AudioBufferCarrier->mBuffers[i].mDataByteSize =
1625 ioData->mBuffers[0].mDataByteSize;
1626
1627 /* retrieve audio samples to process, log errors */
1628 /* assumptions:
1629 - a callback returning noErr returns the amount of data we asked for
1630 */
1631
1632 OSSpinLockLock(&(My->lock_sampledelivery));
1633
1634 if (My->SetRenderCallback[0].inputProc)
1635 {
1636 if (error_code = ((* My->SetRenderCallback[0].inputProc)
1637 (My->SetRenderCallback[0].inputProcRefCon, &action_flags,
1638 &AudioTimeStampCarrier, (AudioUnitElement) 0, inNumberFrames,
1639 My->AudioBufferCarrier)))
1640 {
1641 sprintf(message, "\nMyRenderer"
1642 "\n\tError: Render callback returned OSType %u\n",
1643 (unsigned int) error_code);
1644 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING(message);
1645 return_value = kAudioUnitErr_NoConnection;
1646 }
1647 }
1648 else
1649 {
1650 if ((My->MakeConnection[0].sourceAudioUnit == 0) ||
1651 (error_code = AudioUnitRender(My->MakeConnection[0].sourceAudioUnit,
1652 &action_flags, &AudioTimeStampCarrier,
1653 My->MakeConnection[0].sourceOutputNumber,
1654 inNumberFrames, My->AudioBufferCarrier)))
1655 {
1656 if (My->MakeConnection[0].sourceAudioUnit == 0)
1657 {
1658 sprintf(message, "\nMyRenderer"
1659 "\n\tError: No connection to use with AudioUnitRender\n");
1660 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING(message);
1661 return_value = kAudioUnitErr_NoConnection;
1662 }
1663 else
1664 {
1665 sprintf(message, "\nMyRenderer\n\tError: AudioUnitRender returned:\n\t");
1666 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING(message);
1667 ASYS_AUDIOUNIT_WIRETAP_PRINT_COMPONENT_RESULT(error_code);
1668 sprintf(message, "\n");
1669 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING(message);
1670 return_value = error_code;
1671 }
1672 }
1673 }
1674
1675 OSSpinLockUnlock(&(My->lock_sampledelivery));
1676
1677 /* supply return buffers (only!) if needed */
1678
1679 for (i = 0; i < ioData->mNumberBuffers; i++) /* straight-wire, no gain */
1680 if (ioData->mBuffers[i].mData == NULL)
1681 ioData->mBuffers[i].mData = (void *) My->mData_Output[i];
1682
1683 /* do PreRender notification */
1684
1685 OSSpinLockLock(&(My->lock_rendernotify));
1686
1687 notify = My->rendernotify;
1688 while (notify)
1689 {
1690 if (notify->nproc)
1691 {
1692 action_flags = kAudioUnitRenderAction_PreRender;
1693
1694 if (error_code = ((* notify->nproc)
1695 (notify->nrefcon, &action_flags,
1696 inTimeStamp, (AudioUnitElement) 0, inNumberFrames,
1697 ioData)))
1698 {
1699 sprintf(message, "\nasysn_audiounit_MyRenderer"
1700 "\n\tError: PreRender Rendernotify callback"
1701 " returned OSType %u\n", (unsigned int) error_code);
1702 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING(message);
1703 }
1704 }
1705 notify = notify->next;
1706 }
1707
1708 OSSpinLockUnlock(&(My->lock_rendernotify));
1709
1710 /* the actual rendering done by the audio unit */
1711
1712 if (return_value == noErr)
1713 {
1714 if (iresponse == ASYS_AUDIOUNIT_IRESPONSE_RENDER)
1715 {
1716 My->ksync_timespent = AudioGetCurrentHostTime() - My->ksync_timespent;
1717 asysn_audiounit_activeio_renderer(My, ioData);
1718 My->ksync_timespent = AudioGetCurrentHostTime() - My->ksync_timespent;
1719 }
1720 else
1721 asysn_audiounit_activeio_passthru(My, ioData);
1722 }
1723 else
1724 for (i = 0; i < ioData->mNumberBuffers; i++) /* in case of error, silence */
1725 memset(ioData->mBuffers[i].mData, 0, ioData->mBuffers[i].mDataByteSize);
1726
1727 /* do PostRender notification */
1728
1729 OSSpinLockLock(&(My->lock_rendernotify));
1730
1731 notify = My->rendernotify;
1732 while (notify)
1733 {
1734 if (notify->nproc)
1735 {
1736 action_flags = kAudioUnitRenderAction_PostRender;
1737
1738 if (error_code = ((* notify->nproc)
1739 (notify->nrefcon, &action_flags,
1740 inTimeStamp, (AudioUnitElement) 0, inNumberFrames,
1741 ioData)))
1742 {
1743 sprintf(message, "\nasysn_audiounit_MyRenderer"
1744 "\n\tError: PostRender Rendernotify callback"
1745 " returned OSType %u\n", (unsigned int) error_code);
1746 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING(message);
1747 }
1748 }
1749 notify = notify->next;
1750 }
1751
1752 OSSpinLockUnlock(&(My->lock_rendernotify));
1753
1754 asysn_audiounit_realtime_exitstate(My);
1755
1756 return return_value;
1757 }
1758
1759 #endif /* ASYS_AUDIOUNIT_EFFECT */
1760
1761 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1762 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1763 /* Helper Functions for all Selector Calls */
1764 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1765 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1766
1767 /****************************************************************/
1768 /* Helper Function for Factory Presets: returns a preset name */
1769 /****************************************************************/
1770
asysn_audiounit_factorypresetname(CFIndex idx)1771 CFStringRef asysn_audiounit_factorypresetname(CFIndex idx)
1772
1773 {
1774 CFStringRef ret = NULL;
1775 char * nptr, * val_name;
1776 int i, j;
1777
1778 j = 0;
1779
1780 for (i = 0; i < CSYS_GLOBALNUM; i++)
1781 if ((csys_global[i].type == CSYS_TABLE) && csys_global[i].name &&
1782 !strncmp("aup_factory_", csys_global[i].name, strlen("aup_factory_")) &&
1783 strlen(csys_global[i].name) > strlen("aup_factory_") && ((j++) == idx))
1784 {
1785 nptr = val_name = malloc
1786 (strlen(&(csys_global[i].name[strlen("aup_factory_")])) + 1);
1787
1788 strcpy(val_name, &(csys_global[i].name[strlen("aup_factory_")]));
1789
1790 do {
1791 if (*nptr == '_')
1792 *nptr = ' ';
1793 } while (*(++nptr));
1794
1795 ret = CFStringCreateWithCString(NULL, val_name, kCFStringEncodingASCII);
1796 break;
1797 }
1798
1799 return ret;
1800 }
1801
1802 /****************************************************************/
1803 /* Helper Function for Factory Presets: returns a preset number */
1804 /****************************************************************/
1805
asysn_audiounit_factorypresetnumber(CFStringRef cfstr)1806 int asysn_audiounit_factorypresetnumber(CFStringRef cfstr)
1807
1808 {
1809 char * nptr, * val_name, * match;
1810 int i, j;
1811
1812 if (!cfstr)
1813 return -1;
1814
1815 match = calloc(CFStringGetLength(cfstr) + 1, 1);
1816 CFStringGetCString(cfstr, match, CFStringGetLength(cfstr) + 1,
1817 kCFStringEncodingASCII);
1818
1819 j = 0;
1820
1821 for (i = 0; i < CSYS_GLOBALNUM; i++)
1822 if ((csys_global[i].type == CSYS_TABLE) && csys_global[i].name &&
1823 !strncmp("aup_factory_", csys_global[i].name, strlen("aup_factory_")) &&
1824 strlen(csys_global[i].name) > strlen("aup_factory_"))
1825 {
1826 nptr = val_name = malloc
1827 (strlen(&(csys_global[i].name[strlen("aup_factory_")])) + 1);
1828
1829 strcpy(val_name, &(csys_global[i].name[strlen("aup_factory_")]));
1830
1831 do {
1832 if (*nptr == '_')
1833 *nptr = ' ';
1834 } while (*(++nptr));
1835
1836 if (!strcmp(match, val_name))
1837 return j;
1838
1839 j++;
1840 }
1841
1842 return -1;
1843 }
1844
1845
1846 /***********************************************************************/
1847 /* Helper Function for GetProperty: Create ParameterValueStrings array */
1848 /***********************************************************************/
1849
asysn_audiounit_parametervaluestrings_create(asysn_audiounit_InstanceState * My,AudioUnitParameterID i)1850 CFMutableArrayRef asysn_audiounit_parametervaluestrings_create
1851 (asysn_audiounit_InstanceState * My, AudioUnitParameterID i)
1852
1853 {
1854 CFMutableArrayRef array;
1855 int j;
1856
1857 if ((i < 0) || (i >= My->num_saolparams) || (My->pvs_size[i] == 0))
1858 return NULL;
1859
1860 array = CFArrayCreateMutable(NULL, My->pvs_size[i], &kCFTypeArrayCallBacks);
1861
1862 for (j = 0; j < My->pvs_size[i]; j++)
1863 CFArrayInsertValueAtIndex(array, j, CFStringCreateWithCString
1864 (NULL, My->pvs_cstr[i][j], kCFStringEncodingASCII));
1865
1866 return array;
1867 }
1868
1869 /*****************************************************************/
1870 /* Pre-engine-execution passes for initialize_parametersystem() */
1871 /*****************************************************************/
1872
asysn_audiounit_earlypass_parametersystem(asysn_audiounit_InstanceState * My)1873 ComponentResult asysn_audiounit_earlypass_parametersystem
1874 (asysn_audiounit_InstanceState * My)
1875
1876 {
1877 int i, j, msize;
1878 char * nptr;
1879
1880 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1881 /* Pass 1 on csys_global[]: count parameters and factory presets */
1882 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1883
1884 for (i = 0; i < CSYS_GLOBALNUM; i++)
1885 if (csys_global[i].name &&
1886 (!strncmp(csys_global[i].name, "aup_", 4)) &&
1887 (strlen(csys_global[i].name) > 4))
1888 switch (csys_global[i].type) {
1889 case CSYS_IRATE:
1890 case CSYS_KRATE:
1891 if (csys_global[i].width != 1)
1892 break;
1893
1894 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1895 /* change sfront/src/writepre.c line 3206 */
1896 /* when the code below changes */
1897 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1898
1899 /* skip over reserved names */
1900
1901 if ((nptr = strstr(&(csys_global[i].name[4]), "_idx")) &&
1902 (strlen(nptr) > 6) && (nptr[4] >= '0') && (nptr[4] <= '9'))
1903 break;
1904
1905 if (strstr(&(csys_global[i].name[4]), "_unit_"))
1906 break;
1907
1908 if ((strstr(&(csys_global[i].name[4]), "_slider_squarelaw")) ||
1909 (strstr(&(csys_global[i].name[4]), "_slider_cubic")) ||
1910 (strstr(&(csys_global[i].name[4]), "_slider_squareroot")) ||
1911 (strstr(&(csys_global[i].name[4]), "_slider_cuberoot")) ||
1912 (strstr(&(csys_global[i].name[4]), "_slider_log")) ||
1913 (strstr(&(csys_global[i].name[4]), "_slider_exp")) ||
1914 (strstr(&(csys_global[i].name[4]), "_slider_linear")) ||
1915 (strstr(&(csys_global[i].name[4]), "_slider")) ||
1916 (strstr(&(csys_global[i].name[4]), "_checkbox")) ||
1917 (strstr(&(csys_global[i].name[4]), "_menu")) ||
1918 (strstr(&(csys_global[i].name[4]), "_display_number")) ||
1919 (strstr(&(csys_global[i].name[4]), "_display_checkbox")) ||
1920 (strstr(&(csys_global[i].name[4]), "_display_menu")))
1921 break;
1922
1923 My->num_saolparams++;
1924 break;
1925 case CSYS_TABLE:
1926 if (!strncmp("aup_factory_", csys_global[i].name, strlen("aup_factory_"))
1927 && (strlen(csys_global[i].name) > strlen("aup_factory_")))
1928 My->num_factory++;
1929 break;
1930 default:
1931 break;
1932 }
1933
1934 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1935 /* Create data structures for parameters, factory presets, etc */
1936 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1937
1938 if (My->num_saolparams == 0)
1939 return noErr;
1940
1941 if (!(My->parameterlist = (AudioUnitParameterID *)
1942 malloc(My->num_saolparams*sizeof(AudioUnitParameterID))))
1943 return kAudioUnitErr_FailedInitialization;
1944
1945 for (i = 0; i < My->num_saolparams; i++)
1946 My->parameterlist[i] = i;
1947
1948 if (!(My->parameterinfo = (AudioUnitParameterInfo *)
1949 calloc(My->num_saolparams, sizeof(AudioUnitParameterInfo))))
1950 return kAudioUnitErr_FailedInitialization;
1951
1952 if (!(My->pvs_size = (int *) calloc(My->num_saolparams, sizeof(int))))
1953 return kAudioUnitErr_FailedInitialization;
1954
1955 if (!(My->pvs_cstr = (char ***) calloc(My->num_saolparams, sizeof(char **))))
1956 return kAudioUnitErr_FailedInitialization;
1957
1958 msize = My->num_saolparams*sizeof(asysn_audiounit_saolparam);
1959 if (!(My->saolparam = (asysn_audiounit_saolparam *) malloc(msize)))
1960 return kAudioUnitErr_FailedInitialization;
1961 asysn_audiounit_memstatus(My->saolparam, msize, MADV_WILLNEED);
1962
1963 if (My->num_factory)
1964 {
1965 if (!(My->factorypreset_info = (AUPreset *)
1966 calloc(My->num_factory, sizeof(AUPreset))))
1967 return kAudioUnitErr_FailedInitialization;
1968
1969 msize = My->num_factory*sizeof(Float32 *);
1970 if (!(My->factorypreset_values = (Float32 **) calloc(1, msize)))
1971 return kAudioUnitErr_FailedInitialization;
1972 asysn_audiounit_memstatus(My->factorypreset_values, msize, MADV_WILLNEED);
1973
1974 for (i = 0; i < My->num_factory; i++)
1975 {
1976 msize = My->num_saolparams*sizeof(Float32);
1977 if (!(My->factorypreset_values[i] = (Float32 *) malloc(msize)))
1978 return kAudioUnitErr_FailedInitialization;
1979 asysn_audiounit_memstatus(My->factorypreset_values[i], msize, MADV_WILLNEED);
1980 }
1981 }
1982
1983 /* todo: add parameter value strings data structures */
1984
1985 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1986 /* Pass 2 on csys_global[]: Initialize parameter names */
1987 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1988
1989 j = 0;
1990
1991 for (i = 0; i < CSYS_GLOBALNUM; i++)
1992 if (csys_global[i].name &&
1993 (!strncmp(csys_global[i].name, "aup_", 4)) &&
1994 (strlen(csys_global[i].name) > 4))
1995 switch (csys_global[i].type) {
1996 case CSYS_IRATE:
1997 case CSYS_KRATE:
1998 if (csys_global[i].width != 1)
1999 break;
2000
2001 /* skip over reserved names */
2002
2003 if ((nptr = strstr(&(csys_global[i].name[4]), "_idx")) &&
2004 (strlen(nptr) > 6) && (nptr[4] >= '0') && (nptr[4] <= '9'))
2005 break;
2006
2007 if (strstr(&(csys_global[i].name[4]), "_unit_"))
2008 break;
2009
2010 if ((strstr(&(csys_global[i].name[4]), "_slider_squarelaw")) ||
2011 (strstr(&(csys_global[i].name[4]), "_slider_cubic")) ||
2012 (strstr(&(csys_global[i].name[4]), "_slider_squareroot")) ||
2013 (strstr(&(csys_global[i].name[4]), "_slider_cuberoot")) ||
2014 (strstr(&(csys_global[i].name[4]), "_slider_log")) ||
2015 (strstr(&(csys_global[i].name[4]), "_slider_exp")) ||
2016 (strstr(&(csys_global[i].name[4]), "_slider_linear")) ||
2017 (strstr(&(csys_global[i].name[4]), "_slider")) ||
2018 (strstr(&(csys_global[i].name[4]), "_checkbox")) ||
2019 (strstr(&(csys_global[i].name[4]), "_menu")) ||
2020 (strstr(&(csys_global[i].name[4]), "_display_number")) ||
2021 (strstr(&(csys_global[i].name[4]), "_display_checkbox")) ||
2022 (strstr(&(csys_global[i].name[4]), "_display_menu")))
2023 break;
2024
2025 /* Do all initialization that may be done early */
2026
2027 strncpy(My->parameterinfo[j].name, &(csys_global[i].name[4]), 60);
2028 My->parameterinfo[j].name[59] = '\0';
2029
2030 My->parameterinfo[j].unit = ASYS_AUDIOUNIT_PARAMETER_DEFAULT_UNIT;
2031 My->parameterinfo[j].minValue = ASYS_AUDIOUNIT_PARAMETER_DEFAULT_MINIMUM;
2032 My->parameterinfo[j].maxValue = ASYS_AUDIOUNIT_PARAMETER_DEFAULT_MAXIMUM;
2033 My->parameterinfo[j].defaultValue = ASYS_AUDIOUNIT_PARAMETER_DEFAULT_DEFAULT;
2034
2035 My->parameterinfo[j].flags = kAudioUnitParameterFlag_HasCFNameString |
2036 kAudioUnitParameterFlag_IsReadable | kAudioUnitParameterFlag_IsWritable |
2037 kAudioUnitParameterFlag_CFNameRelease;
2038
2039 My->saolparam[j].index = csys_global[i].index;
2040 My->saolparam[j].use = csys_global[i].use;
2041
2042 j++;
2043 break;
2044 default:
2045 break;
2046 }
2047
2048 return noErr;
2049 }
2050
2051
2052 /******************************************************************/
2053 /* Parameter-value strings pass for initialize_parametersystem() */
2054 /******************************************************************/
2055
asysn_audiounit_parametervaluestrings_parametersystem(asysn_audiounit_InstanceState * My)2056 ComponentResult asysn_audiounit_parametervaluestrings_parametersystem
2057 (asysn_audiounit_InstanceState * My)
2058
2059 {
2060 int i, j, k, str_idx, len;
2061 char * nptr, * match;
2062
2063 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2064 /* Create parameter-value strings for Indexed parameters */
2065 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2066
2067 for (j = 0; j < My->num_saolparams; j++)
2068 if (My->parameterinfo[j].unit == kAudioUnitParameterUnit_Indexed)
2069 {
2070 My->pvs_size[j] = (My->parameterinfo[j].maxValue
2071 - My->parameterinfo[j].minValue + 1);
2072
2073 My->pvs_cstr[j] = (char **) calloc(My->pvs_size[j], sizeof(char *));
2074
2075 if (!(My->pvs_cstr[j]))
2076 return kAudioUnitErr_FailedInitialization;
2077
2078 /* create array and default values */
2079
2080 for (k = 0; k < My->pvs_size[j]; k++)
2081 {
2082 My->pvs_cstr[j][k] = (char *)calloc(strlen("4294967295") + 1, sizeof(char));
2083
2084 if (!(My->pvs_cstr[j][k]))
2085 return kAudioUnitErr_FailedInitialization;
2086
2087 sprintf(My->pvs_cstr[j][k], "%u", k);
2088 }
2089
2090 /* overwrite default values with custom strings */
2091
2092 len = strlen("aup_") + strlen(My->parameterinfo[j].name) + strlen("_idx");
2093
2094 if (!(match = malloc(len + 1)))
2095 return kAudioUnitErr_FailedInitialization;
2096
2097 sprintf((nptr = match), "aup_%s_idx", My->parameterinfo[j].name);
2098
2099 do {
2100 if (*nptr == ' ')
2101 *nptr = '_';
2102 } while (*(++nptr));
2103
2104 for (i = 0; i < CSYS_GLOBALNUM; i++)
2105 if (csys_global[i].name && (csys_global[j].width == 1) &&
2106 ((csys_global[i].type == CSYS_IRATE) ||
2107 (csys_global[i].type == CSYS_KRATE)) &&
2108 (!strncmp(csys_global[i].name, match, len)) &&
2109 (strlen(csys_global[i].name) > len) &&
2110 (sscanf(&(csys_global[i].name[len]), "%u_", &k) == 1) &&
2111 (k >= 0) && (k <= My->pvs_size[j]))
2112 {
2113 str_idx = len;
2114 while (csys_global[i].name[str_idx++] != '_');
2115
2116 if (csys_global[i].name[str_idx] != '\0')
2117 {
2118 free(My->pvs_cstr[j][k]);
2119
2120 nptr = My->pvs_cstr[j][k]
2121 = malloc(strlen(&(csys_global[i].name[str_idx])) + 1);
2122
2123 if (!nptr)
2124 return kAudioUnitErr_FailedInitialization;
2125
2126 strcpy(My->pvs_cstr[j][k], &(csys_global[i].name[str_idx]));
2127
2128 do {
2129 if (*nptr == '_')
2130 *nptr = ' ';
2131 } while (*(++nptr));
2132 }
2133 }
2134
2135 free(match);
2136 }
2137
2138 return noErr;
2139 }
2140
2141 /*********************************************************/
2142 /* Factory preset pass for initialize_parametersystem() */
2143 /*********************************************************/
2144
asysn_audiounit_factorypreset_parametersystem(ENGINE_PTR_DECLARE_COMMA asysn_audiounit_InstanceState * My)2145 ComponentResult asysn_audiounit_factorypreset_parametersystem
2146 (ENGINE_PTR_DECLARE_COMMA
2147 asysn_audiounit_InstanceState * My)
2148
2149 {
2150 int i, j, k, idx;
2151 char * nptr, * match;
2152
2153 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2154 /* initialize factory preset data structures */
2155 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2156
2157 if (My->num_factory)
2158 {
2159 j = 0;
2160 My->factorypreset_array = CFArrayCreateMutable(NULL, My->num_factory, NULL);
2161
2162 if (!(My->factorypreset_array))
2163 return kAudioUnitErr_FailedInitialization;
2164
2165 for (i = 0; i < CSYS_GLOBALNUM; i++)
2166 if ((csys_global[i].type == CSYS_TABLE) && csys_global[i].name &&
2167 !strncmp("aup_factory_", csys_global[i].name, strlen("aup_factory_")) &&
2168 strlen(csys_global[i].name) > strlen("aup_factory_"))
2169 {
2170 nptr = match = malloc
2171 (strlen(&(csys_global[i].name[strlen("aup_factory_")])) + 1);
2172
2173 if (!nptr)
2174 return kAudioUnitErr_FailedInitialization;
2175
2176 strcpy(match, &(csys_global[i].name[strlen("aup_factory_")]));
2177 do {
2178 if (*nptr == '_')
2179 *nptr = ' ';
2180 } while (*(++nptr));
2181
2182 My->factorypreset_info[j].presetNumber = j;
2183 My->factorypreset_info[j].presetName = CFStringCreateWithCString
2184 (NULL, match, kCFStringEncodingASCII);
2185
2186 if (!(My->factorypreset_info[j].presetName))
2187 return kAudioUnitErr_FailedInitialization;
2188
2189 CFArrayAppendValue(My->factorypreset_array, &(My->factorypreset_info[j]));
2190
2191 free(match);
2192
2193 for (k = 0; k < My->num_saolparams; k++)
2194 My->factorypreset_values[j][k] = My->parameterinfo[k].defaultValue;
2195
2196 if (EV(gtables)[idx = csys_global[i].index].t)
2197 for (k = 0; (k < EV(gtables)[idx].len) && (k < My->num_saolparams); k++)
2198 {
2199 My->factorypreset_values[j][k] = EV(gtables)[idx].t[k];
2200 My->factorypreset_values[j][k] =
2201 (My->factorypreset_values[j][k] < My->parameterinfo[k].minValue)
2202 ? My->parameterinfo[k].minValue : My->factorypreset_values[j][k];
2203 My->factorypreset_values[j][k] =
2204 (My->factorypreset_values[j][k] > My->parameterinfo[k].maxValue)
2205 ? My->parameterinfo[k].maxValue : My->factorypreset_values[j][k];
2206 }
2207
2208 j++;
2209 }
2210 }
2211
2212 return noErr;
2213 }
2214
2215 /************************************************************/
2216 /* Helper for Open Selector: Initializes parameter system. */
2217 /************************************************************/
2218
asysn_audiounit_initialize_parametersystem(asysn_audiounit_InstanceState * My)2219 ComponentResult asysn_audiounit_initialize_parametersystem
2220 (asysn_audiounit_InstanceState * My)
2221
2222 {
2223 int i, j, k, ret, match_len, unit_num;
2224 char * nptr, * kptr, * match;
2225 ENGINE_PTR_DECLARE_SEMICOLON
2226
2227 if ((ASYS_AUDIOUNIT_HAS_AUCONTROL == 0) || (CSYS_GLOBALNUM == 0))
2228 return noErr;
2229
2230 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2231 /* Parameter initialization passes that precede engine start */
2232 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2233
2234 if ((ret = asysn_audiounit_earlypass_parametersystem(My)) != noErr)
2235 return ret;
2236
2237 if (My->num_saolparams == 0)
2238 return noErr;
2239
2240 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2241 /* Execute engine to define parameters and factory presets */
2242 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2243
2244 ENGINE_PTR_ASSIGNED_TO system_init(My->argc, My->argv,
2245 My->OutputStreamFormat.mSampleRate);
2246
2247 if (ENGINE_PTR_IS_NULL)
2248 return kAudioUnitErr_FailedInitialization;
2249
2250 effects_init(ENGINE_PTR);
2251 main_initpass(ENGINE_PTR);
2252 asysn_audiounit_ksyncinit(My);
2253
2254 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2255 /* Use engine results to complete parameter data structures */
2256 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2257
2258 for (j = 0; j < My->num_saolparams; j++)
2259 {
2260 match = malloc(strlen("aup_") + strlen(My->parameterinfo[j].name) +
2261 strlen("_pinfo") + 1);
2262
2263 if (!match)
2264 {
2265 shut_down(ENGINE_PTR);
2266 return kAudioUnitErr_FailedInitialization;
2267 }
2268
2269 sprintf(match, "aup_%s_pinfo", My->parameterinfo[j].name);
2270
2271 for (i = 0; i < CSYS_GLOBALNUM; i++)
2272 if ((csys_global[i].type == CSYS_TABLE) && csys_global[i].name &&
2273 !strcmp(match, csys_global[i].name))
2274 {
2275 k = csys_global[i].index;
2276
2277 if (EV(gtables)[k].t && (EV(gtables)[k].len >= 3) &&
2278 (EV(gtables)[k].t[0] <= EV(gtables)[k].t[1]) &&
2279 (EV(gtables)[k].t[1] <= EV(gtables)[k].t[2]))
2280 {
2281 My->parameterinfo[j].minValue = EV(gtables)[k].t[0];
2282 My->parameterinfo[j].defaultValue = EV(gtables)[k].t[1];
2283 My->parameterinfo[j].maxValue = EV(gtables)[k].t[2];
2284
2285 if (My->parameterinfo[j].minValue > My->parameterinfo[j].maxValue)
2286 {
2287 My->parameterinfo[j].minValue = EV(gtables)[k].t[2];
2288 My->parameterinfo[j].maxValue = EV(gtables)[k].t[0];
2289 }
2290
2291 if (My->parameterinfo[j].defaultValue > My->parameterinfo[j].maxValue)
2292 My->parameterinfo[j].defaultValue = EV(gtables)[k].t[2];
2293
2294 if (My->parameterinfo[j].defaultValue < My->parameterinfo[j].minValue)
2295 My->parameterinfo[j].defaultValue = EV(gtables)[k].t[0];
2296 }
2297 break;
2298 }
2299
2300 free(match);
2301
2302 match = malloc((match_len = strlen("aup_") + strlen(My->parameterinfo[j].name) +
2303 strlen("_unit_")) + 1);
2304
2305 if (!match)
2306 {
2307 shut_down(ENGINE_PTR);
2308 return kAudioUnitErr_FailedInitialization;
2309 }
2310
2311 sprintf(match, "aup_%s_unit_", My->parameterinfo[j].name);
2312
2313 for (i = 0; i < CSYS_GLOBALNUM; i++)
2314 if (((csys_global[i].type == CSYS_IRATE) ||
2315 (csys_global[i].type == CSYS_KRATE)) &&
2316 (csys_global[i].width == 1) &&
2317 csys_global[i].name &&
2318 !strncmp(match, csys_global[i].name, match_len))
2319 {
2320 if (strlen(csys_global[i].name) <= match_len)
2321 continue;
2322
2323 nptr = &(csys_global[i].name[match_len]);
2324
2325 /* for now, only support custom units */
2326
2327 kptr = malloc(strlen(nptr) + 1);
2328
2329 if (!kptr)
2330 {
2331 shut_down(ENGINE_PTR);
2332 return kAudioUnitErr_FailedInitialization;
2333 }
2334
2335 strcpy(kptr, &(csys_global[i].name[match_len]));
2336
2337 nptr = kptr;
2338 do {
2339 if (*nptr == '_')
2340 *nptr = ' ';
2341 } while (*(++nptr));
2342
2343 My->parameterinfo[j].unitName = CFStringCreateWithCString
2344 (NULL, kptr, kCFStringEncodingASCII);
2345
2346 if (!(My->parameterinfo[j].unitName))
2347 {
2348 shut_down(ENGINE_PTR);
2349 return kAudioUnitErr_FailedInitialization;
2350 }
2351
2352 My->parameterinfo[j].unit = kAudioUnitParameterUnit_CustomUnit;
2353
2354 free(kptr);
2355 break;
2356 }
2357
2358 free(match);
2359
2360 match = malloc((match_len = strlen("aup_") + strlen(My->parameterinfo[j].name) +
2361 strlen("_")) + 1);
2362
2363 if (!match)
2364 {
2365 shut_down(ENGINE_PTR);
2366 return kAudioUnitErr_FailedInitialization;
2367 }
2368
2369 sprintf(match, "aup_%s_", My->parameterinfo[j].name);
2370
2371 for (i = 0; i < CSYS_GLOBALNUM; i++)
2372
2373 if (((csys_global[i].type == CSYS_IRATE) ||
2374 (csys_global[i].type == CSYS_KRATE)) &&
2375 (csys_global[i].width == 1) &&
2376 csys_global[i].name &&
2377 !strncmp(match, csys_global[i].name, match_len))
2378 {
2379 if (strlen(csys_global[i].name) <= match_len)
2380 continue;
2381
2382 nptr = &(csys_global[i].name[match_len]);
2383
2384 if (!strcmp(nptr, "slider_squarelaw"))
2385 My->parameterinfo[j].flags |=
2386 kAudioUnitParameterFlag_DisplaySquared;
2387 else
2388 if (!strcmp(nptr, "slider_cubic"))
2389 My->parameterinfo[j].flags |=
2390 kAudioUnitParameterFlag_DisplayCubed;
2391 else
2392 if (!strcmp(nptr, "slider_squareroot"))
2393 My->parameterinfo[j].flags |=
2394 kAudioUnitParameterFlag_DisplaySquareRoot;
2395 else
2396 if (!strcmp(nptr, "slider_cuberoot"))
2397 My->parameterinfo[j].flags |=
2398 kAudioUnitParameterFlag_DisplayCubeRoot;
2399 else
2400 if (!strcmp(nptr, "slider_log"))
2401 My->parameterinfo[j].flags |=
2402 kAudioUnitParameterFlag_DisplayLogarithmic;
2403 else
2404 if (!strcmp(nptr, "slider_exp"))
2405 My->parameterinfo[j].flags |=
2406 kAudioUnitParameterFlag_DisplayExponential;
2407 else
2408 if (!strcmp(nptr, "menu") || !strcmp(nptr, "display_menu"))
2409 {
2410 if (!strcmp(nptr, "display_menu"))
2411 My->parameterinfo[j].flags &=
2412 ~ kAudioUnitParameterFlag_IsWritable;
2413
2414 My->parameterinfo[j].unit =
2415 kAudioUnitParameterUnit_Indexed;
2416 if (My->parameterinfo[j].unitName)
2417 {
2418 CFRelease(My->parameterinfo[j].unitName);
2419 My->parameterinfo[j].unitName = NULL;
2420 }
2421 }
2422 else
2423 if (!strcmp(nptr, "checkbox") ||
2424 !strcmp(nptr, "display_checkbox"))
2425 {
2426 if (!strcmp(nptr, "display_checkbox"))
2427 My->parameterinfo[j].flags &=
2428 ~ kAudioUnitParameterFlag_IsWritable;
2429
2430 My->parameterinfo[j].unit =
2431 kAudioUnitParameterUnit_Boolean;
2432 if (My->parameterinfo[j].unitName)
2433 {
2434 CFRelease(My->parameterinfo[j].unitName);
2435 My->parameterinfo[j].unitName = NULL;
2436 }
2437 }
2438 else
2439 if (!strcmp(nptr, "display_number"))
2440 {
2441 My->parameterinfo[j].flags &=
2442 ~ kAudioUnitParameterFlag_IsWritable;
2443 }
2444 else
2445 if ((strcmp(nptr, "slider_linear") != 0) &&
2446 (strcmp(nptr, "slider") != 0))
2447 continue;
2448 break;
2449 }
2450
2451 free(match);
2452
2453 My->saolparam[j].value = My->parameterinfo[j].defaultValue;
2454
2455 nptr = &(My->parameterinfo[j].name[0]);
2456 do {
2457 if (*nptr == '_')
2458 *nptr = ' ';
2459 } while (*(++nptr));
2460
2461 My->parameterinfo[j].cfNameString = CFStringCreateWithCString
2462 (NULL, My->parameterinfo[j].name, kCFStringEncodingASCII);
2463
2464 if (!(My->parameterinfo[j].cfNameString))
2465 {
2466 shut_down(ENGINE_PTR);
2467 return kAudioUnitErr_FailedInitialization;
2468 }
2469 }
2470
2471 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2472 /* Create parameter-value strings for Indexed parameters */
2473 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2474
2475 if ((ret = asysn_audiounit_parametervaluestrings_parametersystem(My)) != noErr)
2476 {
2477 shut_down(ENGINE_PTR);
2478 return ret;
2479 }
2480
2481 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2482 /* initialize factory preset data structures */
2483 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2484
2485 if ((ret = asysn_audiounit_factorypreset_parametersystem
2486 (ENGINE_PTR_COMMA My)) != noErr)
2487 {
2488 shut_down(ENGINE_PTR);
2489 return ret;
2490 }
2491
2492 /*~~~~~~~~~~~~~~~~~~~*/
2493 /* Shut down engine */
2494 /*~~~~~~~~~~~~~~~~~~~*/
2495
2496 shut_down(ENGINE_PTR);
2497 return noErr;
2498 }
2499
2500
2501 /************************************************************/
2502 /* Helper for Open Selector: Initializes property variables */
2503 /************************************************************/
2504
asysn_audiounit_initialize_properties(asysn_audiounit_InstanceState * My)2505 ComponentResult asysn_audiounit_initialize_properties
2506 (asysn_audiounit_InstanceState * My)
2507
2508 {
2509 int i;
2510
2511 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2512 /* the first set of parameters define the signal flow */
2513 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2514
2515 /* the preferred audiounit bus widths */
2516
2517 My->InputElementCount = ASYS_AUDIOUNIT_ELEMENT_INPUTPREF;
2518 My->OutputElementCount = ASYS_AUDIOUNIT_ELEMENT_OUTPUTPREF;
2519
2520 /* defines fixed channel widths. todo: turn into an array of formats */
2521
2522 if (ASYS_AUDIOUNIT_EFFECT)
2523 {
2524 My->SupportedNumChannels[0].inChannels = ASYS_AUDIOUNIT_MONO;
2525 My->SupportedNumChannels[0].outChannels = ASYS_AUDIOUNIT_MONO;
2526 My->SupportedNumChannels[1].inChannels = ASYS_AUDIOUNIT_MONO;
2527 My->SupportedNumChannels[1].outChannels = ASYS_AUDIOUNIT_STEREO;
2528 My->SupportedNumChannels[2].inChannels = ASYS_AUDIOUNIT_STEREO;
2529 My->SupportedNumChannels[2].outChannels = ASYS_AUDIOUNIT_MONO;
2530 My->SupportedNumChannels[3].inChannels = ASYS_AUDIOUNIT_STEREO;
2531 My->SupportedNumChannels[3].outChannels = ASYS_AUDIOUNIT_STEREO;
2532 }
2533 else
2534 {
2535 My->SupportedNumChannels[0].inChannels = ASYS_AUDIOUNIT_NULL;
2536 My->SupportedNumChannels[0].outChannels = ASYS_AUDIOUNIT_MONO;
2537 My->SupportedNumChannels[1].inChannels = ASYS_AUDIOUNIT_NULL;
2538 My->SupportedNumChannels[1].outChannels = ASYS_AUDIOUNIT_STEREO;
2539 }
2540
2541
2542 /* maximum audio sample chunk -- augment with other variables to resize buffers */
2543
2544 My->MaximumFramesPerSlice = ASYS_AUDIOUNIT_FRAMES_PER_SLICE;
2545
2546 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2547 /* our desired input and output stream format */
2548 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2549
2550 for (i=0; i < ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE; i++)
2551 {
2552 /* mChannelsPerFrame code mono, stereo, etc */
2553
2554 My->InputStreamFormat[i].mChannelsPerFrame = ASYS_AUDIOUNIT_INPUT_CHANNELS;
2555
2556 /* could also be kAudioStreamAnyRate, once we support setproperty over-ride */
2557
2558 My->InputStreamFormat[i].mSampleRate = SAOL_SRATE;
2559
2560 /* a set of non-interleaved mono channels -- do not touch these */
2561
2562 My->InputStreamFormat[i].mFormatID = kAudioFormatLinearPCM;
2563
2564 My->InputStreamFormat[i].mFormatFlags = (kAudioFormatFlagIsFloat |
2565 kAudioFormatFlagIsPacked |
2566 kAudioFormatFlagIsNonInterleaved);
2567
2568 if (ASYS_AUDIOUNIT_FLOAT32_BIGENDIAN)
2569 My->InputStreamFormat[i].mFormatFlags |= kAudioFormatFlagIsBigEndian;
2570
2571 My->InputStreamFormat[i].mBytesPerPacket = 4;
2572 My->InputStreamFormat[i].mBytesPerFrame = 4;
2573 My->InputStreamFormat[i].mFramesPerPacket = 1;
2574 My->InputStreamFormat[i].mBitsPerChannel = 32;
2575
2576 My->InputStreamFormat[i].mReserved = 0;
2577 }
2578
2579 /* mChannelsPerFrame code mono, stereo, etc */
2580
2581 My->OutputStreamFormat.mChannelsPerFrame = ASYS_AUDIOUNIT_OUTPUT_CHANNELS;
2582
2583 /* could also be kAudioStreamAnyRate, once we support setproperty over-ride */
2584
2585 My->OutputStreamFormat.mSampleRate = SAOL_SRATE;
2586
2587 My->acycle = ((int)(SAOL_SRATE))/((int)(SAOL_KRATE));
2588 My->krate = SAOL_KRATE;
2589 My->acycleidx_kcycleidx = 1; /* acycleidx = 0, kcycleidx = 1 */
2590
2591 /* a set of non-interleaved mono channels -- do not touch these */
2592
2593 My->OutputStreamFormat.mFormatID = kAudioFormatLinearPCM;
2594
2595 My->OutputStreamFormat.mFormatFlags = (kAudioFormatFlagIsFloat |
2596 kAudioFormatFlagIsPacked |
2597 kAudioFormatFlagIsNonInterleaved);
2598
2599 if (ASYS_AUDIOUNIT_FLOAT32_BIGENDIAN)
2600 My->OutputStreamFormat.mFormatFlags |= kAudioFormatFlagIsBigEndian;
2601
2602 My->OutputStreamFormat.mBytesPerPacket = 4;
2603 My->OutputStreamFormat.mBytesPerFrame = 4;
2604 My->OutputStreamFormat.mFramesPerPacket = 1;
2605 My->OutputStreamFormat.mBitsPerChannel = 32;
2606
2607 My->OutputStreamFormat.mReserved = 0;
2608
2609 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2610 /* end of streamformat property */
2611 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2612
2613 /* tracks if the audio unit is currently bypassed */
2614
2615 My->BypassEffect = 0;
2616 My->LastBypassEffect = 0;
2617
2618 /* set to 1 if we renderer returns the buffers use for SetRenderCallback */
2619
2620 My->InPlaceProcessing = ASYS_AUDIOUNIT_INPLACE_PROCESSING;
2621
2622 /* define the null preset */
2623
2624 My->PresentPreset.presetName = CFStringCreateWithCString(NULL, "Untitled",
2625 kCFStringEncodingASCII);
2626 if (!(My->PresentPreset.presetName))
2627 return kAudioUnitErr_FailedInitialization;
2628
2629 My->PresentPreset.presetNumber = -1;
2630
2631 My->lock_PresentPreset = 0;
2632
2633 /* number of instruments offered by the music device */
2634
2635 if (ASYS_AUDIOUNIT_MUSICDEVICE)
2636 My->InstrumentCount = ASYS_AUDIOUNIT_INSTRUMENT_COUNT;
2637 else
2638 My->InstrumentCount = 0;
2639
2640 /* 1 if the audio unit intends to stream samples off of the disk */
2641
2642 My->StreamFromDisk = 0;
2643
2644 /* the function pointer and parameters SetRenderCallback provides */
2645
2646 for (i=0; i < ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE; i++)
2647 {
2648 My->SetRenderCallback[i].inputProc = NULL;
2649 My->SetRenderCallback[i].inputProcRefCon = NULL;
2650 }
2651
2652 /* how the host tells us who is driving us */
2653
2654 for (i=0; i < ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE; i++)
2655 {
2656 My->MakeConnection[i].sourceAudioUnit = 0;
2657 My->MakeConnection[i].sourceOutputNumber = 0;
2658 My->MakeConnection[i].destInputNumber = 0;
2659 }
2660
2661 /* lock for both SetRenderCallback and MakeConnection */
2662
2663 My->lock_sampledelivery = 0;
2664
2665 /* the function pointer and parameters RenderNotify provides, and its lock */
2666
2667 My->rendernotify = NULL;
2668 My->lock_rendernotify = 0;
2669
2670 /* tracks last rendering error for the rendering proc - clear after returning it */
2671
2672 My->LastRenderError = noErr;
2673
2674 /* for now, assume AU algorithm has no latency */
2675
2676 My->Latency = 0.0;
2677
2678 /* tail time (in a reverb sense) for the audio unit */
2679
2680 My->TailTime = 0.0;
2681
2682 /* to be used for selecting sfront's sample-rate conversion algorithm */
2683
2684 My->SRCAlgorithm = kAudioUnitSRCAlgorithm_Polyphase;
2685
2686 /* request for render quality, using 0-127 scaled enum in AudioUnitProperties.h */
2687
2688 My->RenderQuality = kRenderQuality_Max;
2689
2690 /* the % of total CPU load the host allots to us, 0 codes no limit */
2691
2692 My->CPULoad = 0.0;
2693 My->lock_CPULoad = 0;
2694 My->ksync_normalize = (Float32) (My->krate/AudioGetHostClockFrequency());
2695
2696 /* a heads-up for off-line operation, sent by host */
2697
2698 My->OfflineRender = 0;
2699
2700 /* a heads-up for the presentation latency, sent by host */
2701
2702 My->PresentationLatency = 0.0;
2703
2704 /* listener callback lists for each supported property */
2705
2706 for (i = 0; i < ASYS_AUDIOUNIT_PROPLISTEN_ARRAYSIZE; i++)
2707 My->proplisteners[i] = NULL;
2708
2709 My->lock_proplisteners = 0;
2710
2711 /*~~~~~~~~~~~~~~~~~~~~~*/
2712 /* aup_ property state */
2713 /*~~~~~~~~~~~~~~~~~~~~~*/
2714
2715 My->num_saolparams = 0;
2716 My->parameterlist = NULL;
2717 My->parameterinfo = NULL;
2718 My->pvs_size = NULL;
2719 My->pvs_cstr = NULL;
2720 My->saolparam = NULL;
2721 My->num_factory = 0;
2722 My->factorypreset_values = NULL;
2723 My->factorypreset_info = NULL;
2724 My->factorypreset_array = NULL;
2725
2726 return noErr;
2727 }
2728
2729 /************************************************************/
2730 /* Helper for Open Selector: Memstatus for global variables */
2731 /************************************************************/
2732
asysn_audiounit_globalvars_memstatus(int advice)2733 void asysn_audiounit_globalvars_memstatus(int advice)
2734
2735 {
2736 int msize, i, j;
2737
2738 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2739 /* global arrays used by main_ipass */
2740 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2741
2742 #if (defined(CSYS_MAXEXTCHAN) && (CSYS_MAXEXTCHAN > 0))
2743 msize = CSYS_MAXEXTCHAN*sizeof(int);
2744 asysn_audiounit_memstatus(cme_preset, msize, advice);
2745 #endif
2746
2747 #if (defined(CSYS_MAXSASLINSTR) && (CSYS_MAXSASLINSTR > 0))
2748 msize = CSYS_MAXSASLINSTR*sizeof(int);
2749 asysn_audiounit_memstatus(csys_instrtablesize, msize, advice);
2750 asysn_audiounit_memstatus(csys_instrvarsize, msize, advice);
2751 #endif
2752
2753 /*~~~~~~~~~~~~~~~~~~~~~*/
2754 /* global table arrays */
2755 /*~~~~~~~~~~~~~~~~~~~~~*/
2756
2757 #if (defined(CSYS_TABLE_CATALOG_SIZE) && (CSYS_TABLE_CATALOG_SIZE > 0))
2758 for (i = 0; i < CSYS_TABLE_CATALOG_SIZE; i++)
2759 {
2760 msize = csys_table_catalog[i].num*sizeof(float);
2761 asysn_audiounit_memstatus(csys_table_catalog[i].t, msize, advice);
2762 }
2763 #endif
2764
2765 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2766 /* reflection interface variables */
2767 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2768
2769 #if (defined(CSYS_GLOBALNUM) && (CSYS_GLOBALNUM > 0))
2770 msize = CSYS_GLOBALNUM*sizeof(csys_varstruct);
2771 asysn_audiounit_memstatus(csys_global, msize, advice);
2772 #endif
2773
2774 #if (defined(CSYS_TARGETNUM) && (CSYS_TARGETNUM > 0))
2775 msize = CSYS_TARGETNUM*sizeof(csys_targetstruct);
2776 asysn_audiounit_memstatus(csys_target, msize, advice);
2777 #endif
2778
2779 #if (defined(CSYS_LABELNUM) && (CSYS_LABELNUM > 0))
2780 msize = CSYS_LABELNUM*sizeof(csys_labelstruct);
2781 asysn_audiounit_memstatus(csys_labels, msize, advice);
2782 #endif
2783
2784 #if (defined(CSYS_PRESETNUM) && (CSYS_PRESETNUM > 0))
2785 msize = CSYS_PRESETNUM*sizeof(csys_presetstruct);
2786 asysn_audiounit_memstatus(csys_presets, msize, advice);
2787 #endif
2788
2789 #if (defined(CSYS_SAMPLENUM) && (CSYS_SAMPLENUM > 0))
2790 msize = CSYS_SAMPLENUM*sizeof(csys_samplestruct);
2791 asysn_audiounit_memstatus(csys_samples, msize, advice);
2792 #endif
2793
2794 #if (defined(CSYS_BUSNUM) && (CSYS_BUSNUM > 0))
2795 msize = CSYS_BUSNUM*sizeof(csys_busstruct);
2796 asysn_audiounit_memstatus(csys_bus, msize, advice);
2797 #endif
2798
2799 #if (defined(CSYS_ROUTENUM) && (CSYS_ROUTENUM > 0))
2800 msize = CSYS_ROUTENUM*sizeof(csys_routestruct);
2801 asysn_audiounit_memstatus(csys_route, msize, advice);
2802 #endif
2803
2804 #if (defined(CSYS_SENDNUM) && (CSYS_SENDNUM > 0))
2805 msize = CSYS_SENDNUM*sizeof(csys_sendstruct);
2806 asysn_audiounit_memstatus(csys_send, msize, advice);
2807 for (i = 0; i < CSYS_SENDNUM; i++)
2808 if (csys_send[i].bus)
2809 {
2810 msize = csys_send[i].nbus*sizeof(int);
2811 asysn_audiounit_memstatus(csys_send[i].bus, msize, advice);
2812 }
2813 #endif
2814
2815 #if (defined(CSYS_INSTRNUM) && (CSYS_INSTRNUM > 0))
2816 msize = CSYS_INSTRNUM*sizeof(csys_instrstruct);
2817 asysn_audiounit_memstatus(csys_instr, msize, advice);
2818 for (i = 0; i < CSYS_INSTRNUM; i++)
2819 {
2820 if (csys_instr[i].name)
2821 {
2822 msize = (strlen(csys_instr[i].name) + 1)*sizeof(char);
2823 asysn_audiounit_memstatus(csys_instr[i].name, msize, advice);
2824 }
2825 if (csys_instr[i].vars)
2826 {
2827 msize = csys_instr[i].numvars*sizeof(csys_varstruct);
2828 asysn_audiounit_memstatus(csys_instr[i].vars, msize, advice);
2829 for (j = 0; j < csys_instr[i].numvars; j++)
2830 if (csys_instr[i].vars[j].name)
2831 {
2832 msize = (strlen(csys_instr[i].vars[j].name) + 1)*sizeof(char);
2833 asysn_audiounit_memstatus(csys_instr[i].vars[j].name, msize, advice);
2834 }
2835 }
2836 }
2837 #endif
2838
2839 }
2840
2841 /************************************************************/
2842 /* Helper for Open Selector: Recover from a failed open. */
2843 /************************************************************/
2844
asysn_audiounit_instance_cleanup(ComponentParameters * p,asysn_audiounit_InstanceState * My)2845 ComponentResult asysn_audiounit_instance_cleanup
2846 (ComponentParameters * p, asysn_audiounit_InstanceState * My)
2847
2848 {
2849 int i, k, msize;
2850
2851 if (My)
2852 {
2853 if (My->PresentPreset.presetName)
2854 CFRelease(My->PresentPreset.presetName);
2855
2856 if (My->AudioBufferCarrier)
2857 {
2858 msize = sizeof(UInt32) + sizeof(AudioBuffer)*ASYS_AUDIOUNIT_INPUT_MAXCHANNELS;
2859 asysn_audiounit_memstatus(My->AudioBufferCarrier, msize, MADV_FREE);
2860 free(My->AudioBufferCarrier);
2861 }
2862
2863 if (My->AudioBufferTemplate)
2864 {
2865 msize = sizeof(Float32)*ASYS_AUDIOUNIT_FRAMES_PER_SLICE;
2866 for(i = 0; i < ASYS_AUDIOUNIT_INPUT_MAXCHANNELS; i++)
2867 if (My->AudioBufferTemplate->mBuffers[i].mData)
2868 {
2869 asysn_audiounit_memstatus(My->AudioBufferTemplate->mBuffers[i].mData,
2870 msize, MADV_FREE);
2871 free(My->AudioBufferTemplate->mBuffers[i].mData);
2872 }
2873 msize = sizeof(UInt32) + sizeof(AudioBuffer)*ASYS_AUDIOUNIT_INPUT_MAXCHANNELS;
2874 asysn_audiounit_memstatus(My->AudioBufferTemplate, msize, MADV_FREE);
2875 free(My->AudioBufferTemplate);
2876 }
2877
2878 for(i = 0; i < ASYS_AUDIOUNIT_OUTPUT_MAXCHANNELS; i++)
2879 if (My->mData_Output[i])
2880 {
2881 msize = sizeof(Float32)*ASYS_AUDIOUNIT_FRAMES_PER_SLICE;
2882 asysn_audiounit_memstatus(My->mData_Output[i], msize, MADV_FREE);
2883 free(My->mData_Output[i]);
2884 }
2885
2886 if (My->mpipepair[0])
2887 close(My->mpipepair[0]);
2888 if (My->mpipepair[1])
2889 close(My->mpipepair[1]);
2890 if (My->spipepair[0])
2891 close(My->spipepair[0]);
2892 if (My->spipepair[1])
2893 close(My->spipepair[1]);
2894
2895 if (My->parameterlist)
2896 free(My->parameterlist);
2897
2898 if (My->parameterinfo)
2899 {
2900 for (i = 0; i < My->num_saolparams; i++)
2901 {
2902 if (My->parameterinfo[i].cfNameString)
2903 CFRelease(My->parameterinfo[i].cfNameString);
2904 if (My->parameterinfo[i].unitName)
2905 CFRelease(My->parameterinfo[i].unitName);
2906 }
2907 free(My->parameterinfo);
2908 }
2909
2910 if (My->pvs_size)
2911 {
2912 if (My->pvs_cstr)
2913 {
2914 for (i = 0; i < My->num_saolparams; i++)
2915 if (My->pvs_cstr[i])
2916 {
2917 for (k = 0; k < My->pvs_size[i]; k++)
2918 if (My->pvs_cstr[i][k])
2919 free(My->pvs_cstr[i][k]);
2920 free(My->pvs_cstr[i]);
2921 }
2922 free(My->pvs_cstr);
2923 }
2924 free(My->pvs_size);
2925 }
2926
2927 if (My->saolparam)
2928 {
2929 msize = My->num_saolparams*sizeof(asysn_audiounit_saolparam);
2930 asysn_audiounit_memstatus(My->saolparam, msize, MADV_FREE);
2931 free(My->saolparam);
2932 }
2933
2934 if (My->factorypreset_info)
2935 {
2936 for (i = 0; i < My->num_factory; i++)
2937 if (My->factorypreset_info[i].presetName)
2938 CFRelease(My->factorypreset_info[i].presetName);
2939 free(My->factorypreset_info);
2940 }
2941
2942 if (My->factorypreset_values)
2943 {
2944 msize = My->num_saolparams*sizeof(Float32);
2945 for (i = 0; i < My->num_factory; i++)
2946 if (My->factorypreset_values[i])
2947 {
2948 asysn_audiounit_memstatus(My->factorypreset_values[i], msize, MADV_FREE);
2949 free(My->factorypreset_values[i]);
2950 }
2951
2952 msize = My->num_factory*sizeof(Float32 *);
2953 asysn_audiounit_memstatus(My->factorypreset_values, msize, MADV_FREE);
2954 free(My->factorypreset_values);
2955 }
2956
2957 if (My->factorypreset_array)
2958 CFRelease(My->factorypreset_array);
2959
2960 msize = sizeof(asysn_audiounit_InstanceState);
2961 asysn_audiounit_memstatus(My, msize, MADV_FREE);
2962 free(My);
2963 }
2964
2965 SetComponentInstanceStorage((ComponentInstance) p->params[0], (Handle) NULL);
2966 return kAudioUnitErr_FailedInitialization;
2967 }
2968
2969 /**********************************************************************/
2970 /* Helper for Initialize Selector: Send all parameters to SAOL engine */
2971 /**********************************************************************/
2972
asysn_audiounit_engine_parameter_update(asysn_audiounit_InstanceState * My)2973 ComponentResult asysn_audiounit_engine_parameter_update
2974 (asysn_audiounit_InstanceState * My)
2975
2976 {
2977 asysn_audiounit_SASLevent SASLevent;
2978 int result = noErr;
2979 int i;
2980
2981 for (i = 0; i < My->num_saolparams; i++)
2982 {
2983 SASLevent.index = i;
2984 SASLevent.value = My->saolparam[i].value;
2985 SASLevent.kcycleidx = 0;
2986 result |= asysn_audiounit_sendSASLevent(&SASLevent, My);
2987 }
2988
2989 return result;
2990 }
2991
2992 /***************************************************************/
2993 /* Helper for Uninitialize Selector: empty MIDI and SASL pipes */
2994 /***************************************************************/
2995
asysn_audiounit_engine_emptypipes(asysn_audiounit_InstanceState * My)2996 void asysn_audiounit_engine_emptypipes
2997 (asysn_audiounit_InstanceState * My)
2998 {
2999 asysn_audiounit_MIDIevent mdummy;
3000 asysn_audiounit_SASLevent sdummy;
3001 int retry = 0;
3002
3003 if (ASYS_AUDIOUNIT_MIDISUPPORT && My->mpipepair[0])
3004 do {
3005 if (retry++ > ASYS_AUDIOUNIT_RETRY_MAX)
3006 break;
3007 } while ((read(My->mpipepair[0], &mdummy,
3008 sizeof(asysn_audiounit_MIDIevent)) > 0) || (errno == EINTR));
3009
3010 retry == 0;
3011
3012 if (My->spipepair[0])
3013 do {
3014 if (retry++ > ASYS_AUDIOUNIT_RETRY_MAX)
3015 break;
3016 } while ((read(My->spipepair[0], &sdummy,
3017 sizeof(asysn_audiounit_SASLevent)) > 0) || (errno == EINTR));
3018 }
3019
3020 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3021 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3022 /* Helper Functions for the GetProperty Selector Helper for ClassInfo */
3023 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3024 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3025
3026 /***********************************************/
3027 /* Big-endian int append to a CFMutableDataRef */
3028 /***********************************************/
3029
asysn_audiounit_classinfo_pdata_intwrite(CFMutableDataRef pdata,SInt32 value)3030 void asysn_audiounit_classinfo_pdata_intwrite(CFMutableDataRef pdata, SInt32 value)
3031
3032 {
3033 unsigned char p[4];
3034
3035 p[0] = 0x000000FF & (value >> 24);
3036 p[1] = 0x000000FF & (value >> 16);
3037 p[2] = 0x000000FF & (value >> 8);
3038 p[3] = 0x000000FF & (value);
3039
3040 CFDataAppendBytes(pdata, (UInt8 *) p, 4);
3041 }
3042
3043 /***************************************************/
3044 /* Big-endian float append to a CFMutableDataRef */
3045 /* Assumes int and float share an enddian-ness */
3046 /***************************************************/
3047
asysn_audiounit_classinfo_pdata_floatwrite(CFMutableDataRef pdata,Float32 fval)3048 void asysn_audiounit_classinfo_pdata_floatwrite(CFMutableDataRef pdata, Float32 fval)
3049
3050 {
3051 union { int i; float f ; } u;
3052 unsigned char p[4];
3053
3054 u.f = fval;
3055
3056 p[0] = 0x000000FF & (u.i >> 24);
3057 p[1] = 0x000000FF & (u.i >> 16);
3058 p[2] = 0x000000FF & (u.i >> 8);
3059 p[3] = 0x000000FF & (u.i);
3060
3061 CFDataAppendBytes(pdata, (UInt8 *) p, 4);
3062 }
3063
3064 /************************************/
3065 /* Adds integer item to a ClassInfo */
3066 /************************************/
3067
asysn_audiounit_classinfo_addint(CFMutableDictionaryRef ClassInfo,char * ckey,SInt32 value)3068 int asysn_audiounit_classinfo_addint(CFMutableDictionaryRef ClassInfo,
3069 char * ckey, SInt32 value)
3070
3071 {
3072 CFStringRef key;
3073 CFNumberRef num;
3074 int errcode = -1;
3075
3076 key = CFStringCreateWithCString(NULL, ckey, kCFStringEncodingASCII);
3077 if (key)
3078 {
3079 num = CFNumberCreate(NULL, kCFNumberSInt32Type, &value);
3080 if (num)
3081 {
3082 CFDictionarySetValue(ClassInfo, key, num);
3083 CFRelease(num);
3084 errcode = 0;
3085 }
3086 CFRelease(key);
3087 }
3088
3089 return errcode;
3090 }
3091
3092 /************************************/
3093 /* Adds float item to a ClassInfo */
3094 /************************************/
3095
asysn_audiounit_classinfo_addfloat(CFMutableDictionaryRef ClassInfo,char * ckey,Float32 fval)3096 int asysn_audiounit_classinfo_addfloat(CFMutableDictionaryRef ClassInfo,
3097 char * ckey, Float32 fval)
3098
3099 {
3100 CFStringRef key;
3101 CFNumberRef num;
3102 int errcode = -1;
3103
3104 key = CFStringCreateWithCString(NULL, ckey, kCFStringEncodingASCII);
3105 if (key)
3106 {
3107 num = CFNumberCreate(NULL, kCFNumberFloatType, &fval);
3108 if (num)
3109 {
3110 CFDictionarySetValue(ClassInfo, key, num);
3111 CFRelease(num);
3112 errcode = 0;
3113 }
3114 CFRelease(key);
3115 }
3116
3117 return errcode;
3118 }
3119
3120 /*************************************/
3121 /* Adds CFString item to a ClassInfo */
3122 /*************************************/
3123
asysn_audiounit_classinfo_addcfstr(CFMutableDictionaryRef ClassInfo,char * ckey,CFStringRef cfstr)3124 int asysn_audiounit_classinfo_addcfstr(CFMutableDictionaryRef ClassInfo,
3125 char * ckey, CFStringRef cfstr)
3126
3127 {
3128 CFStringRef key;
3129 int errcode = -1;
3130
3131 key = CFStringCreateWithCString(NULL, ckey, kCFStringEncodingASCII);
3132 if (key)
3133 {
3134 CFDictionarySetValue(ClassInfo, key, cfstr);
3135 CFRelease(key);
3136 errcode = 0;
3137 }
3138
3139 return errcode;
3140 }
3141
3142 /************************************************************************/
3143 /* Helper for GetProperty Selector: Create ClassInfo for use by AU host */
3144 /************************************************************************/
3145
asysn_audiounit_classinfo_create(asysn_audiounit_InstanceState * My)3146 CFMutableDictionaryRef asysn_audiounit_classinfo_create
3147 (asysn_audiounit_InstanceState * My)
3148
3149 {
3150 CFMutableDictionaryRef ClassInfo;
3151 CFMutableDataRef pdata;
3152 CFStringRef key;
3153 int i;
3154
3155 ClassInfo = CFDictionaryCreateMutable
3156 (NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
3157
3158 /* component definitions adapted from volume.r */
3159
3160 asysn_audiounit_classinfo_addint(ClassInfo, kAUPresetVersionKey,
3161 0); /* version 0 */
3162 asysn_audiounit_classinfo_addint(ClassInfo, kAUPresetTypeKey,
3163 ASYS_AUDIOUNIT_COMP_TYPE);
3164 asysn_audiounit_classinfo_addint(ClassInfo, kAUPresetSubtypeKey,
3165 ASYS_AUDIOUNIT_COMP_SUBTYPE);
3166 asysn_audiounit_classinfo_addint(ClassInfo, kAUPresetManufacturerKey,
3167 ASYS_AUDIOUNIT_COMP_MANU);
3168
3169 /* parameter data */
3170
3171 if ((pdata = CFDataCreateMutable(NULL, 0)) && My->num_saolparams)
3172 {
3173 asysn_audiounit_classinfo_pdata_intwrite(pdata,
3174 kAudioUnitScope_Global); /* global scope */
3175 asysn_audiounit_classinfo_pdata_intwrite(pdata,
3176 0); /* element (bus) 0 */
3177 asysn_audiounit_classinfo_pdata_intwrite(pdata,
3178 My->num_saolparams); /* number of parameters */
3179
3180 for (i = 0; i < My->num_saolparams; i++)
3181 {
3182 /* parameter index */
3183
3184 asysn_audiounit_classinfo_pdata_intwrite(pdata, i);
3185
3186 /* value */
3187
3188 asysn_audiounit_classinfo_pdata_floatwrite
3189 (pdata,
3190 (My->parameterinfo[i].flags & kAudioUnitParameterFlag_IsWritable) ?
3191 My->saolparam[i].value : My->parameterinfo[i].defaultValue);
3192 }
3193 }
3194
3195 if (pdata)
3196 {
3197 key = CFStringCreateWithCString(NULL, kAUPresetDataKey, kCFStringEncodingASCII);
3198 if (key)
3199 {
3200 CFDictionarySetValue(ClassInfo, key, pdata);
3201 CFRelease(key);
3202 }
3203 CFRelease(pdata);
3204 }
3205
3206 asysn_audiounit_classinfo_addcfstr(ClassInfo, kAUPresetNameKey,
3207 My->PresentPreset.presetName);
3208 asysn_audiounit_classinfo_addint(ClassInfo, kAUPresetRenderQualityKey,
3209 (SInt32) (My->RenderQuality));
3210 asysn_audiounit_classinfo_addfloat(ClassInfo, kAUPresetCPULoadKey,
3211 My->CPULoad);
3212
3213 /* add kAUPresetElementNameKey here if named elements/buses are supported */
3214
3215 return ClassInfo;
3216 }
3217
3218 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3219 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3220 /* Helper Functions for the SetProperty Selector Helper for ClassInfo */
3221 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3222 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3223
3224 /**************************************/
3225 /* Read integer item from a ClassInfo */
3226 /**************************************/
3227
asysn_audiounit_classinfo_readint(CFMutableDictionaryRef ClassInfo,char * ckey,SInt32 * value)3228 int asysn_audiounit_classinfo_readint(CFMutableDictionaryRef ClassInfo,
3229 char * ckey, SInt32 * value)
3230
3231 {
3232 CFStringRef key;
3233 CFNumberRef num;
3234 SInt32 newval;
3235 int errcode = -1;
3236
3237 key = CFStringCreateWithCString(NULL, ckey, kCFStringEncodingASCII);
3238 if (key)
3239 {
3240 num = CFDictionaryGetValue(ClassInfo, key);
3241 if (num && CFNumberGetValue(num, kCFNumberSInt32Type, &newval))
3242 {
3243 errcode = 0;
3244 *value = newval;
3245 }
3246 CFRelease(key);
3247 }
3248 return errcode;
3249 }
3250
3251 /**************************************/
3252 /* Read float item from a ClassInfo */
3253 /**************************************/
3254
asysn_audiounit_classinfo_readfloat(CFMutableDictionaryRef ClassInfo,char * ckey,Float32 * value)3255 int asysn_audiounit_classinfo_readfloat(CFMutableDictionaryRef ClassInfo,
3256 char * ckey, Float32 * value)
3257
3258 {
3259 CFStringRef key;
3260 CFNumberRef num;
3261 Float32 newval;
3262 int errcode = -1;
3263
3264 key = CFStringCreateWithCString(NULL, ckey, kCFStringEncodingASCII);
3265 if (key)
3266 {
3267 num = CFDictionaryGetValue(ClassInfo, key);
3268 if (num && CFNumberGetValue(num, kCFNumberFloat32Type, &newval))
3269 {
3270 errcode = 0;
3271 *value = newval;
3272 }
3273 CFRelease(key);
3274 }
3275 return errcode;
3276 }
3277
3278 /***************************************/
3279 /* Read CFString item from a ClassInfo */
3280 /***************************************/
3281
asysn_audiounit_classinfo_readcfstr(CFMutableDictionaryRef ClassInfo,char * ckey,CFStringRef * cfstr)3282 int asysn_audiounit_classinfo_readcfstr(CFMutableDictionaryRef ClassInfo,
3283 char * ckey, CFStringRef * cfstr)
3284
3285 {
3286 CFStringRef key;
3287 CFNumberRef num;
3288 CFStringRef newstr;
3289 int errcode = -1;
3290
3291 key = CFStringCreateWithCString(NULL, ckey, kCFStringEncodingASCII);
3292 if (key)
3293 {
3294 if (newstr = CFDictionaryGetValue(ClassInfo, key))
3295 {
3296 errcode = 0;
3297 CFRetain(newstr);
3298 if (*cfstr)
3299 CFRelease(*cfstr);
3300 *cfstr = newstr;
3301 }
3302 CFRelease(key);
3303 }
3304 return errcode;
3305 }
3306
3307 /***********************************************/
3308 /* Big-endian int read from a CFMutableDataRef */
3309 /***********************************************/
3310
asysn_audiounit_classinfo_pdata_intread(CFMutableDataRef pdata,UInt8 ** p)3311 SInt32 asysn_audiounit_classinfo_pdata_intread(CFMutableDataRef pdata, UInt8 ** p)
3312
3313 {
3314 SInt32 value;
3315
3316 value = ((*p)[0] << 24) | ((*p)[1] << 16) | ((*p)[2] << 8) | ((*p)[3]);
3317 (*p) += 4;
3318 return value;
3319 }
3320
3321 /*************************************************/
3322 /* Big-endian float read from a CFMutableDataRef */
3323 /*************************************************/
3324
asysn_audiounit_classinfo_pdata_floatread(CFMutableDataRef pdata,UInt8 ** p)3325 Float32 asysn_audiounit_classinfo_pdata_floatread(CFMutableDataRef pdata, UInt8 ** p)
3326
3327 {
3328 union { SInt32 i; Float32 f ; } u;
3329
3330 u.i = ((*p)[0] << 24) | ((*p)[1] << 16) | ((*p)[2] << 8) | ((*p)[3]);
3331 (*p) += 4;
3332 return u.f;
3333 }
3334
3335 /****************************************/
3336 /* Read parameter data from a ClassInfo */
3337 /****************************************/
3338
asysn_audiounit_classinfo_readpdata(asysn_audiounit_InstanceState * My,CFMutableDictionaryRef ClassInfo)3339 int asysn_audiounit_classinfo_readpdata(asysn_audiounit_InstanceState * My,
3340 CFMutableDictionaryRef ClassInfo)
3341
3342 {
3343 int errcode = -1;
3344 CFStringRef key;
3345 CFMutableDataRef pdata;
3346 UInt8 * p, * pmax;
3347 UInt32 scope, bus, count, idx;
3348 Float32 fval;
3349
3350 key = CFStringCreateWithCString(NULL, kAUPresetDataKey, kCFStringEncodingASCII);
3351
3352 if (key && (pdata = (CFMutableDataRef) CFDictionaryGetValue(ClassInfo, key)))
3353 {
3354 p = (UInt8 *) CFDataGetBytePtr(pdata);
3355 pmax = p + CFDataGetLength(pdata);
3356
3357 do {
3358 if (p == pmax)
3359 {
3360 errcode = 0;
3361 break;
3362 }
3363 if ((pmax - p) >= 12)
3364 {
3365 scope = asysn_audiounit_classinfo_pdata_intread(pdata, &p);
3366 bus = asysn_audiounit_classinfo_pdata_intread(pdata, &p);
3367 count = asysn_audiounit_classinfo_pdata_intread(pdata, &p);
3368 if ((pmax - p) >= count*(sizeof(SInt32) + sizeof(Float32)))
3369 if ((scope == kAudioUnitScope_Global) && !bus)
3370 while (count--)
3371 {
3372 idx = asysn_audiounit_classinfo_pdata_intread(pdata, &p);
3373 fval = asysn_audiounit_classinfo_pdata_floatread(pdata, &p);
3374 if (idx < My->num_saolparams)
3375 {
3376 if (fval > My->parameterinfo[idx].maxValue)
3377 fval = My->parameterinfo[idx].maxValue;
3378
3379 if (fval < My->parameterinfo[idx].minValue)
3380 fval = My->parameterinfo[idx].minValue;
3381
3382 My->saolparam[idx].value = fval;
3383 }
3384 }
3385 else
3386 p += count*(sizeof(SInt32) + sizeof(Float32));
3387 else
3388 break;
3389 }
3390 else
3391 break;
3392 } while (1);
3393
3394 CFRelease(key);
3395 }
3396
3397 return errcode;
3398 }
3399
3400 /************************************************************************/
3401 /* Helper for SetProperty Selector: Reads ClassInfo returned by AU host */
3402 /************************************************************************/
3403
asysn_audiounit_classinfo_read(asysn_audiounit_InstanceState * My,CFMutableDictionaryRef ClassInfo)3404 void asysn_audiounit_classinfo_read(asysn_audiounit_InstanceState * My,
3405 CFMutableDictionaryRef ClassInfo)
3406
3407 {
3408 asysn_audiounit_classinfo_readpdata(My, ClassInfo);
3409
3410 asysn_audiounit_engine_parameter_update(My);
3411
3412 asysn_audiounit_classinfo_readint(ClassInfo, kAUPresetRenderQualityKey,
3413 (SInt32 *) &(My->RenderQuality));
3414
3415
3416 OSSpinLockLock(&(My->lock_CPULoad));
3417
3418 asysn_audiounit_classinfo_readfloat(ClassInfo, kAUPresetCPULoadKey,
3419 &(My->CPULoad));
3420 My->ksync_normalize = (Float32) (My->krate/AudioGetHostClockFrequency());
3421 if (My->CPULoad)
3422 My->ksync_normalize = My->ksync_normalize/My->CPULoad;
3423
3424 OSSpinLockUnlock(&(My->lock_CPULoad));
3425
3426
3427 OSSpinLockLock(&(My->lock_PresentPreset));
3428
3429 asysn_audiounit_classinfo_readcfstr(ClassInfo, kAUPresetNameKey,
3430 &(My->PresentPreset.presetName));
3431
3432 My->PresentPreset.presetNumber =
3433 asysn_audiounit_factorypresetnumber(My->PresentPreset.presetName);
3434
3435 OSSpinLockUnlock(&(My->lock_PresentPreset));
3436
3437
3438 /* add kAUPresetElementNameKey here if named elements/buses are supported */
3439 }
3440
3441 /********************************************************************/
3442 /* Helper Function for SetProperty: PresentProperty Factory Presets */
3443 /********************************************************************/
3444
asysn_audiounit_presentproperty_setfactory(asysn_audiounit_InstanceState * My)3445 void asysn_audiounit_presentproperty_setfactory
3446 (asysn_audiounit_InstanceState * My)
3447
3448 {
3449 int j, k;
3450
3451 j = My->PresentPreset.presetNumber;
3452
3453 if ((j < 0) || (j > My->num_factory))
3454 return;
3455
3456 for (k = 0; k < My->num_saolparams; k++)
3457 My->saolparam[k].value = My->factorypreset_values[j][k];
3458
3459 asysn_audiounit_engine_parameter_update(My);
3460 }
3461
3462 /*********************************************************************/
3463 /* Helper for Property Selectors: returns 1 for supported properties */
3464 /*********************************************************************/
3465
asysn_audiounit_supported_property(AudioUnitPropertyID id,AudioUnitScope scope)3466 int asysn_audiounit_supported_property(AudioUnitPropertyID id, AudioUnitScope scope)
3467
3468 {
3469 switch (id) {
3470 case kAudioUnitProperty_ClassInfo: /* 0 */
3471 return 1;
3472 case kAudioUnitProperty_MakeConnection: /* 1 */
3473 return 1;
3474 case kAudioUnitProperty_SampleRate: /* 2 */
3475 switch (scope) {
3476 case kAudioUnitScope_Input:
3477 return (ASYS_AUDIOUNIT_EFFECT) ? 1 : 0;
3478 case kAudioUnitScope_Global:
3479 case kAudioUnitScope_Output:
3480 return 1;
3481 default:
3482 return 0;
3483 }
3484 case kAudioUnitProperty_ParameterList: /* 3 */
3485 return (scope == kAudioUnitScope_Global);
3486 case kAudioUnitProperty_ParameterInfo: /* 4 */
3487 return 1;
3488 case kAudioUnitProperty_FastDispatch: /* 5 */
3489 return 1;
3490 case kAudioUnitProperty_CPULoad: /* 6 */
3491 return (scope == kAudioUnitScope_Global) ?
3492 ASYS_AUDIOUNIT_SUPPORT_PROPERTY_CPULOAD : 0;
3493 case kAudioUnitProperty_StreamFormat: /* 8 */
3494 switch (scope) {
3495 case kAudioUnitScope_Input:
3496 return (ASYS_AUDIOUNIT_EFFECT) ? 1 : 0;
3497 case kAudioUnitScope_Global:
3498 case kAudioUnitScope_Output:
3499 return 1;
3500 default:
3501 return 0;
3502 }
3503 case kAudioUnitProperty_SRCAlgorithm: /* 9 */
3504 return 1;
3505 case kAudioUnitProperty_ElementCount: /* 11, also kAudioUnitProperty_BusCount */
3506 return 1;
3507 case kAudioUnitProperty_Latency: /* 12 */
3508 return (scope == kAudioUnitScope_Global) ? 1 : 0;
3509 case kAudioUnitProperty_SupportedNumChannels: /* 13 */
3510 return (scope == kAudioUnitScope_Global) ? 1 : 0;
3511 case kAudioUnitProperty_MaximumFramesPerSlice: /* 14 */
3512 return (scope == kAudioUnitScope_Global) ? 1 : 0;
3513 case kAudioUnitProperty_ParameterValueStrings: /* 16 */
3514 return (scope == kAudioUnitScope_Global) ? 1 : 0;
3515 case kAudioUnitProperty_TailTime: /* 20 */
3516 return (scope == kAudioUnitScope_Global) ? 1 : 0;
3517 case kAudioUnitProperty_BypassEffect: /* 21 */
3518 return (scope == kAudioUnitScope_Global) ? 1 : 0;
3519 case kAudioUnitProperty_LastRenderError: /* 22 */
3520 return (scope == kAudioUnitScope_Global) ? 1 : 0;
3521 case kAudioUnitProperty_SetRenderCallback: /* 23 */
3522 return 1;
3523 case kAudioUnitProperty_FactoryPresets: /* 24 */
3524 return 1;
3525 case kAudioUnitProperty_RenderQuality: /* 26 */
3526 return (scope == kAudioUnitScope_Global) ?
3527 ASYS_AUDIOUNIT_SUPPORT_PROPERTY_RENDERQUALITY : 0;
3528 case kAudioUnitProperty_InPlaceProcessing: /* 29 */
3529 return 1;
3530 case kAudioUnitProperty_CocoaUI: /* 31 */
3531 #if defined(ASYS_AUDIOUNIT_VIEW_BUNDLECF)
3532 return 1;
3533 #else
3534 return 0;
3535 #endif
3536 case kAudioUnitProperty_OfflineRender: /* 37 */
3537 return 1;
3538 case kAudioUnitProperty_PresentPreset: /* 36 */
3539 return 1;
3540 case kAudioUnitProperty_PresentationLatency: /* 40 */
3541 return 1;
3542 case kMusicDeviceProperty_InstrumentCount: /* 1000 */
3543 switch (scope) {
3544 case kAudioUnitScope_Global:
3545 case kAudioUnitScope_Input:
3546 return ASYS_AUDIOUNIT_MUSICDEVICE ? 1 : 0;
3547 default:
3548 return 0;
3549 }
3550 case kMusicDeviceProperty_StreamFromDisk: /* 1011 */
3551 return ASYS_AUDIOUNIT_SUPPORT_PROPERTY_STREAMFROMDISK;
3552 default:
3553 return 0;
3554 }
3555 }
3556
3557 /*******************************************************************/
3558 /* Helper for property Selectors: returns property size (in bytes) */
3559 /*******************************************************************/
3560
asysn_audiounit_property_size(AudioUnitPropertyID id,asysn_audiounit_InstanceState * My)3561 unsigned int asysn_audiounit_property_size(AudioUnitPropertyID id,
3562 asysn_audiounit_InstanceState * My)
3563
3564 {
3565 switch (id) {
3566 case kAudioUnitProperty_ClassInfo: /* 0 */
3567 return sizeof(CFPropertyListRef);
3568 case kAudioUnitProperty_MakeConnection: /* 1 */
3569 return sizeof(AudioUnitConnection);
3570 case kAudioUnitProperty_SampleRate: /* 2 */
3571 return sizeof(Float64);
3572 case kAudioUnitProperty_ParameterList: /* 3 */
3573 return My->num_saolparams*sizeof(AudioUnitParameterID);
3574 case kAudioUnitProperty_ParameterInfo: /* 4 */
3575 return sizeof(AudioUnitParameterInfo);
3576 case kAudioUnitProperty_FastDispatch: /* 5 */
3577 return sizeof(void *);
3578 case kAudioUnitProperty_CPULoad: /* 6 */
3579 return sizeof(Float32);
3580 case kAudioUnitProperty_StreamFormat: /* 8 */
3581 return sizeof(AudioStreamBasicDescription);
3582 case kAudioUnitProperty_SRCAlgorithm: /* 9 */
3583 return sizeof(OSType);
3584 case kAudioUnitProperty_ElementCount: /* 11, also kAudioUnitProperty_BusCount */
3585 return sizeof(UInt32);
3586 case kAudioUnitProperty_Latency: /* 12 */
3587 return sizeof(Float64);
3588 case kAudioUnitProperty_SupportedNumChannels: /* 13 */
3589 return ASYS_AUDIOUNIT_SUPPORTED_FORMATS*sizeof(AUChannelInfo);
3590 case kAudioUnitProperty_MaximumFramesPerSlice: /* 14 */
3591 return sizeof(UInt32);
3592 case kAudioUnitProperty_ParameterValueStrings: /* 16 */
3593 return sizeof(CFArrayRef);
3594 case kAudioUnitProperty_TailTime: /* 20 */
3595 return sizeof(Float64);
3596 case kAudioUnitProperty_BypassEffect: /* 21 */
3597 return sizeof(UInt32);
3598 case kAudioUnitProperty_LastRenderError: /* 22 */
3599 return sizeof(OSStatus);
3600 case kAudioUnitProperty_SetRenderCallback: /* 23 */
3601 return sizeof(AURenderCallbackStruct);
3602 case kAudioUnitProperty_FactoryPresets: /* 24 */
3603 return sizeof(CFArrayRef);
3604 case kAudioUnitProperty_RenderQuality: /* 26 */
3605 return sizeof(UInt32);
3606 case kAudioUnitProperty_InPlaceProcessing: /* 29 */
3607 return sizeof(UInt32);
3608 case kAudioUnitProperty_CocoaUI: /* 31 */
3609 #if defined(ASYS_AUDIOUNIT_VIEW_BUNDLECF)
3610 return sizeof(AudioUnitCocoaViewInfo);
3611 #else
3612 break;
3613 #endif
3614 case kAudioUnitProperty_PresentPreset: /* 36 */
3615 return sizeof(AUPreset);
3616 case kAudioUnitProperty_OfflineRender: /* 37 */
3617 return sizeof(UInt32);
3618 case kAudioUnitProperty_PresentationLatency: /* 40 */
3619 return sizeof(Float64);
3620 case kMusicDeviceProperty_InstrumentCount: /* 1000 */
3621 return sizeof(UInt32);
3622 case kMusicDeviceProperty_StreamFromDisk: /* 1011 */
3623 return sizeof(UInt32);
3624 default: /* no entries here -- all cases above should specify datasize */
3625 break;
3626 }
3627
3628 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING("WARNING: asysn_audiounit_property_size()"
3629 "called on an unsupported property\n");
3630 return 0;
3631 }
3632
3633 /***************************************************************/
3634 /* Helper for Property Listener: returns proplisteners[] index */
3635 /***************************************************************/
3636
asysn_audiounit_proplisteners_index(AudioUnitPropertyID id)3637 int asysn_audiounit_proplisteners_index(AudioUnitPropertyID id)
3638
3639 {
3640 int property = -1;
3641
3642 switch (id) {
3643 case kAudioUnitProperty_ParameterList: /* 3 */
3644 property = ASYS_AUDIOUNIT_PROPLISTEN_PARAMETERLIST;
3645 break;
3646 case kAudioUnitProperty_ParameterInfo: /* 4 */
3647 property = ASYS_AUDIOUNIT_PROPLISTEN_PARAMETERINFO;
3648 break;
3649 case kAudioUnitProperty_CPULoad: /* 6 */
3650 property = ASYS_AUDIOUNIT_PROPLISTEN_CPULOAD;
3651 break;
3652 case kAudioUnitProperty_Latency: /* 12 */
3653 property = ASYS_AUDIOUNIT_PROPLISTEN_LATENCY;
3654 break;
3655 case kAudioUnitProperty_MaximumFramesPerSlice: /* 14 */
3656 property = ASYS_AUDIOUNIT_PROPLISTEN_MAXIMUMFRAMESPERSLICE;
3657 break;
3658 case kAudioUnitProperty_TailTime: /* 20 */
3659 property = ASYS_AUDIOUNIT_PROPLISTEN_TAILTIME;
3660 break;
3661 case kAudioUnitProperty_FactoryPresets: /* 24 */
3662 property = ASYS_AUDIOUNIT_PROPLISTEN_FACTORYPRESETS;
3663 break;
3664 case kAudioUnitProperty_RenderQuality: /* 26 */
3665 property = ASYS_AUDIOUNIT_PROPLISTEN_RENDERQUALITY;
3666 break;
3667 case kAudioUnitProperty_CurrentPreset: /* 28 */
3668 property = ASYS_AUDIOUNIT_PROPLISTEN_CURRENTPRESET;
3669 break;
3670 case kAudioUnitProperty_PresentPreset: /* 36 */
3671 property = ASYS_AUDIOUNIT_PROPLISTEN_PRESENTPRESET;
3672 break;
3673 case kMusicDeviceProperty_StreamFromDisk: /* 1011 */
3674 property = ASYS_AUDIOUNIT_PROPLISTEN_STREAMFROMDISK;
3675 break;
3676 }
3677
3678 return property;
3679 }
3680
3681 /***************************************************************/
3682 /* Helper for properties: informs listeners of a status change */
3683 /***************************************************************/
3684
asysn_audiounit_proplisteners_update(asysn_audiounit_InstanceState * My,AudioUnitPropertyID id,AudioUnitScope scope,AudioUnitElement element)3685 void asysn_audiounit_proplisteners_update(
3686 asysn_audiounit_InstanceState * My,
3687 AudioUnitPropertyID id,
3688 AudioUnitScope scope,
3689 AudioUnitElement element)
3690
3691 {
3692 int idx = asysn_audiounit_proplisteners_index(id);
3693 asysn_audiounit_proplisten * lp;
3694
3695 if (idx < 0)
3696 return;
3697
3698 OSSpinLockLock(&(My->lock_proplisteners));
3699
3700 for (lp = My->proplisteners[idx]; lp != NULL; lp = lp->next)
3701 (*(lp->lproc))(lp->lrefcon, My->component, id, scope, element);
3702
3703 /* some apps are buggy and need a double-send ... */
3704
3705 for (lp = My->proplisteners[idx]; lp != NULL; lp = lp->next)
3706 (*(lp->lproc))(lp->lrefcon, My->component, id, scope, element);
3707
3708 OSSpinLockUnlock(&(My->lock_proplisteners));
3709
3710 return;
3711 }
3712
3713
3714 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3715 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3716 /* The istate state transition functions */
3717 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3718 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3719
3720 /***************************************************************/
3721 /* State transition diagram on entrance to InitializeSelect: */
3722 /* */
3723 /* ABSENT: Return _MY_IS_NULL. */
3724 /* INSTANCE: Set FLUX, return _INITIALIZE. */
3725 /* INSTANCE_PASSING: Set FLUX_PASSING, return _INITIALIZE. */
3726 /* FLUX: Spin to INSTANCE* or ENGINE*. */
3727 /* FLUX_PASSING: Spin to INSTANCE* or ENGINE*. */
3728 /* ENGINE: Return _REINITIALIZE. */
3729 /* ENGINE_PASSING: Return _REINITIALIZE. */
3730 /* ENGINE_RENDER: Return _REINITIALIZE. */
3731 /***************************************************************/
3732
asysn_audiounit_initializeselect_enterstate(asysn_audiounit_InstanceState * My)3733 int asysn_audiounit_initializeselect_enterstate(asysn_audiounit_InstanceState * My)
3734
3735 {
3736 int ret;
3737
3738 do
3739 {
3740 switch(My->istate) {
3741 case ASYS_AUDIOUNIT_ISTATE_ABSENT:
3742 ret = ASYS_AUDIOUNIT_IRESPONSE_MY_IS_NULL;
3743 break;
3744 case ASYS_AUDIOUNIT_ISTATE_INSTANCE:
3745 if (!OSAtomicCompareAndSwap32Barrier
3746 (ASYS_AUDIOUNIT_ISTATE_INSTANCE,
3747 ASYS_AUDIOUNIT_ISTATE_FLUX,
3748 (int32_t *) &(My->istate)))
3749 continue;
3750 ret = ASYS_AUDIOUNIT_IRESPONSE_INITIALIZE;
3751 break;
3752 case ASYS_AUDIOUNIT_ISTATE_INSTANCE_PASSING:
3753 if (!OSAtomicCompareAndSwap32Barrier
3754 (ASYS_AUDIOUNIT_ISTATE_INSTANCE_PASSING,
3755 ASYS_AUDIOUNIT_ISTATE_FLUX_PASSING,
3756 (int32_t *) &(My->istate)))
3757 continue;
3758 ret = ASYS_AUDIOUNIT_IRESPONSE_INITIALIZE;
3759 break;
3760 case ASYS_AUDIOUNIT_ISTATE_FLUX:
3761 case ASYS_AUDIOUNIT_ISTATE_FLUX_PASSING:
3762 OSMemoryBarrier();
3763 continue; /* spin to _INSTANCE or _ENGINE */
3764 break;
3765 case ASYS_AUDIOUNIT_ISTATE_ENGINE:
3766 case ASYS_AUDIOUNIT_ISTATE_ENGINE_PASSING:
3767 case ASYS_AUDIOUNIT_ISTATE_ENGINE_RENDER:
3768 ret = ASYS_AUDIOUNIT_IRESPONSE_REINITIALIZE;
3769 break;
3770 default:
3771 ret = ASYS_AUDIOUNIT_IRESPONSE_ERROR;
3772 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
3773 ("\tBad transition - initializeselect_entrance (default)\n\n");
3774 break;
3775 }
3776 } while (0);
3777
3778 return ret;
3779 }
3780
3781 /***************************************************************/
3782 /* State transition diagram on exit from InitializeSelect: */
3783 /* */
3784 /* */
3785 /* ABSENT: Return _ERROR. */
3786 /* INSTANCE: Return _ERROR. */
3787 /* INSTANCE_PASSING: Return _ERROR. */
3788 /* FLUX: Set ENGINE, return _COMPLETE. */
3789 /* FLUX_PASSING: Set ENGINE_PASSING, return _COMPLETE. */
3790 /* ENGINE: Return _ERROR. */
3791 /* ENGINE_PASSING: Return _ERROR. */
3792 /* ENGINE_RENDER: Return _ERROR. */
3793 /* */
3794 /***************************************************************/
3795
asysn_audiounit_initializeselect_exitstate(asysn_audiounit_InstanceState * My)3796 int asysn_audiounit_initializeselect_exitstate(asysn_audiounit_InstanceState * My)
3797
3798 {
3799 int ret;
3800
3801 do
3802 {
3803 switch(My->istate) {
3804 case ASYS_AUDIOUNIT_ISTATE_ABSENT:
3805 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
3806 ("\tBad transition - initializeselect_exit (absent)\n\n");
3807 ret = ASYS_AUDIOUNIT_IRESPONSE_ERROR;
3808 break;
3809 case ASYS_AUDIOUNIT_ISTATE_INSTANCE:
3810 case ASYS_AUDIOUNIT_ISTATE_INSTANCE_PASSING:
3811 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
3812 ("\tBad transition - initializeselect_exit (instance*)\n\n");
3813 ret = ASYS_AUDIOUNIT_IRESPONSE_ERROR;
3814 break;
3815 case ASYS_AUDIOUNIT_ISTATE_FLUX:
3816 if (!OSAtomicCompareAndSwap32Barrier
3817 (ASYS_AUDIOUNIT_ISTATE_FLUX,
3818 ASYS_AUDIOUNIT_ISTATE_ENGINE,
3819 (int32_t *) &(My->istate)))
3820 continue;
3821 ret = ASYS_AUDIOUNIT_IRESPONSE_COMPLETE;
3822 break;
3823 case ASYS_AUDIOUNIT_ISTATE_FLUX_PASSING:
3824 if (!OSAtomicCompareAndSwap32Barrier
3825 (ASYS_AUDIOUNIT_ISTATE_FLUX_PASSING,
3826 ASYS_AUDIOUNIT_ISTATE_ENGINE_PASSING,
3827 (int32_t *) &(My->istate)))
3828 continue;
3829 ret = ASYS_AUDIOUNIT_IRESPONSE_COMPLETE;
3830 break;
3831 case ASYS_AUDIOUNIT_ISTATE_ENGINE:
3832 case ASYS_AUDIOUNIT_ISTATE_ENGINE_PASSING:
3833 case ASYS_AUDIOUNIT_ISTATE_ENGINE_RENDER:
3834 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
3835 ("\tBad transition - initializeselect_exit (engine*)\n\n");
3836 ret = ASYS_AUDIOUNIT_IRESPONSE_ERROR;
3837 break;
3838 default:
3839 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
3840 ("\tBad transition - initializeselect_exit (default)\n\n");
3841 ret = ASYS_AUDIOUNIT_IRESPONSE_ERROR;
3842 break;
3843 }
3844 } while (0);
3845
3846 return ret;
3847 }
3848
3849
3850 /********************************************************************/
3851 /* State transition diagram on entrance to UninitializeSelect: */
3852 /* */
3853 /* ABSENT: Return _MY_IS_NULL. */
3854 /* INSTANCE: Return _REUNINITIALIZE. */
3855 /* INSTANCE_PASSING: Return _REUNINITIALIZE. */
3856 /* FLUX: Spin to INSTANCE* or ENGINE*. */
3857 /* FLUX_PASSING: Spin to INSTANCE* or ENGINE*. */
3858 /* ENGINE: Set FLUX, return _UNINITIALIZE */
3859 /* ENGINE_PASSING: Spin to ENGINE. */
3860 /* ENGINE_RENDER: Spin to ENGINE. */
3861 /********************************************************************/
3862
asysn_audiounit_uninitializeselect_enterstate(asysn_audiounit_InstanceState * My)3863 int asysn_audiounit_uninitializeselect_enterstate(asysn_audiounit_InstanceState * My)
3864
3865 {
3866 int ret;
3867
3868 do
3869 {
3870 switch(My->istate) {
3871 case ASYS_AUDIOUNIT_ISTATE_ABSENT:
3872 ret = ASYS_AUDIOUNIT_IRESPONSE_MY_IS_NULL;
3873 break;
3874 case ASYS_AUDIOUNIT_ISTATE_INSTANCE:
3875 case ASYS_AUDIOUNIT_ISTATE_INSTANCE_PASSING:
3876 ret = ASYS_AUDIOUNIT_IRESPONSE_REUNINITIALIZE;
3877 break;
3878 case ASYS_AUDIOUNIT_ISTATE_FLUX:
3879 case ASYS_AUDIOUNIT_ISTATE_FLUX_PASSING:
3880 OSMemoryBarrier();
3881 continue; /* spin to _INSTANCE or _ENGINE */
3882 break;
3883 case ASYS_AUDIOUNIT_ISTATE_ENGINE:
3884 if (!OSAtomicCompareAndSwap32Barrier
3885 (ASYS_AUDIOUNIT_ISTATE_ENGINE,
3886 ASYS_AUDIOUNIT_ISTATE_FLUX,
3887 (int32_t *) &(My->istate)))
3888 continue;
3889 ret = ASYS_AUDIOUNIT_IRESPONSE_UNINITIALIZE;
3890 break;
3891 case ASYS_AUDIOUNIT_ISTATE_ENGINE_PASSING:
3892 case ASYS_AUDIOUNIT_ISTATE_ENGINE_RENDER:
3893 OSMemoryBarrier();
3894 continue; /* spin to _ENGINE */
3895 default:
3896 ret = ASYS_AUDIOUNIT_IRESPONSE_ERROR;
3897 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
3898 ("\tBad transition - uninitializeselect_entrance\n\n");
3899 break;
3900 }
3901 } while (0);
3902
3903 return ret;
3904 }
3905
3906
3907 /***************************************************************/
3908 /* State transition diagram on exit from UninitializeSelect: */
3909 /* */
3910 /* ABSENT: Return _ERROR. */
3911 /* INSTANCE: Return _ERROR. */
3912 /* INSTANCE_PASSING: Return _ERROR. */
3913 /* FLUX: Set INSTANCE, return _COMPLETE. */
3914 /* FLUX_PASSING: Set INSTANCE_PASSING, return _COMPLETE. */
3915 /* ENGINE: Return _ERROR. */
3916 /* ENGINE_PASSING: Return _ERROR. */
3917 /* ENGINE_RENDER: Return _ERROR. */
3918 /* */
3919 /***************************************************************/
3920
asysn_audiounit_uninitializeselect_exitstate(asysn_audiounit_InstanceState * My)3921 int asysn_audiounit_uninitializeselect_exitstate(asysn_audiounit_InstanceState * My)
3922
3923 {
3924 int ret;
3925
3926 do
3927 {
3928 switch(My->istate) {
3929 case ASYS_AUDIOUNIT_ISTATE_ABSENT:
3930 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
3931 ("\tBad transition - uninitializeselect_exit (absent)\n\n");
3932 ret = ASYS_AUDIOUNIT_IRESPONSE_ERROR;
3933 break;
3934 case ASYS_AUDIOUNIT_ISTATE_INSTANCE:
3935 case ASYS_AUDIOUNIT_ISTATE_INSTANCE_PASSING:
3936 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
3937 ("\tBad transition - uninitializeselect_exit (instance*)\n\n");
3938 ret = ASYS_AUDIOUNIT_IRESPONSE_ERROR;
3939 break;
3940 case ASYS_AUDIOUNIT_ISTATE_FLUX:
3941 if (!OSAtomicCompareAndSwap32Barrier
3942 (ASYS_AUDIOUNIT_ISTATE_FLUX,
3943 ASYS_AUDIOUNIT_ISTATE_INSTANCE,
3944 (int32_t *) &(My->istate)))
3945 continue;
3946 ret = ASYS_AUDIOUNIT_IRESPONSE_COMPLETE;
3947 break;
3948 case ASYS_AUDIOUNIT_ISTATE_FLUX_PASSING:
3949 if (!OSAtomicCompareAndSwap32Barrier
3950 (ASYS_AUDIOUNIT_ISTATE_FLUX_PASSING,
3951 ASYS_AUDIOUNIT_ISTATE_INSTANCE_PASSING,
3952 (int32_t *) &(My->istate)))
3953 continue;
3954 ret = ASYS_AUDIOUNIT_IRESPONSE_COMPLETE;
3955 break;
3956 case ASYS_AUDIOUNIT_ISTATE_ENGINE:
3957 case ASYS_AUDIOUNIT_ISTATE_ENGINE_PASSING:
3958 case ASYS_AUDIOUNIT_ISTATE_ENGINE_RENDER:
3959 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
3960 ("\tBad transition - uninitializeselect_exit (engine*)\n\n");
3961 ret = ASYS_AUDIOUNIT_IRESPONSE_ERROR;
3962 break;
3963 default:
3964 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
3965 ("\tBad transition - uninitializeselect_exit (default)\n\n");
3966 ret = ASYS_AUDIOUNIT_IRESPONSE_ERROR;
3967 break;
3968 }
3969 } while (0);
3970
3971 return ret;
3972 }
3973
3974 /*****************************************************************/
3975 /* State transition diagram on entrance to CloseSelect: */
3976 /* */
3977 /* ABSENT: Return _MY_IS_NULL. */
3978 /* INSTANCE: Set ABSENT, return _CLOSE. */
3979 /* INSTANCE_PASSING: Spin to INSTANCE */
3980 /* FLUX: Spin to INSTANCE or ENGINE */
3981 /* FLUX_PASSING: Spin to INSTANCE or ENGINE */
3982 /* ENGINE: Set ABSENT, return UNINITIALIZE_AND_CLOSE */
3983 /* ENGINE_PASSING: Spin to ENGINE */
3984 /* ENGINE_RENDER: Spin to ENGINE */
3985 /*****************************************************************/
3986
asysn_audiounit_closeselect_enterstate(asysn_audiounit_InstanceState * My)3987 int asysn_audiounit_closeselect_enterstate(asysn_audiounit_InstanceState * My)
3988
3989 {
3990 int ret;
3991
3992 do
3993 {
3994 switch(My->istate) {
3995 case ASYS_AUDIOUNIT_ISTATE_ABSENT:
3996 ret = ASYS_AUDIOUNIT_IRESPONSE_MY_IS_NULL;
3997 break;
3998 case ASYS_AUDIOUNIT_ISTATE_INSTANCE:
3999 if (!OSAtomicCompareAndSwap32Barrier
4000 (ASYS_AUDIOUNIT_ISTATE_INSTANCE,
4001 ASYS_AUDIOUNIT_ISTATE_ABSENT,
4002 (int32_t *) &(My->istate)))
4003 continue;
4004 ret = ASYS_AUDIOUNIT_IRESPONSE_CLOSE;
4005 break;
4006 case ASYS_AUDIOUNIT_ISTATE_INSTANCE_PASSING:
4007 OSMemoryBarrier();
4008 continue; /* spin to _INSTANCE */
4009 break;
4010 case ASYS_AUDIOUNIT_ISTATE_FLUX:
4011 case ASYS_AUDIOUNIT_ISTATE_FLUX_PASSING:
4012 OSMemoryBarrier();
4013 continue; /* spin to _INSTANCE or _ENGINE */
4014 break;
4015 case ASYS_AUDIOUNIT_ISTATE_ENGINE:
4016 if (!OSAtomicCompareAndSwap32Barrier
4017 (ASYS_AUDIOUNIT_ISTATE_ENGINE,
4018 ASYS_AUDIOUNIT_ISTATE_ABSENT,
4019 (int32_t *) &(My->istate)))
4020 continue;
4021 ret = ASYS_AUDIOUNIT_IRESPONSE_UNINITIALIZE_AND_CLOSE;
4022 break;
4023 case ASYS_AUDIOUNIT_ISTATE_ENGINE_PASSING:
4024 case ASYS_AUDIOUNIT_ISTATE_ENGINE_RENDER:
4025 OSMemoryBarrier();
4026 continue; /* spin to _ENGINE */
4027 break;
4028 default:
4029 ret = ASYS_AUDIOUNIT_IRESPONSE_ERROR;
4030 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4031 ("\tBad transition - closeselect_enter\n\n");
4032 break;
4033 }
4034 } while (0);
4035
4036 return ret;
4037 }
4038
4039 /******************************************************************/
4040 /* State transition diagram on entrance to real-time thread: */
4041 /* */
4042 /* ABSENT: Return _MY_IS_NULL (abnormal) */
4043 /* INSTANCE: Set INSTANCE_PASSING, return _WIRE */
4044 /* INSTANCE_PASSING: Set INSTANCE, return _WIRE (abnormal) */
4045 /* FLUX: Set FLUX_PASSING, return _WIRE */
4046 /* FLUX_PASSING: Set FLUX, return _WIRE (abnormal) */
4047 /* ENGINE: Set ENGINE_RENDER, return _RENDER */
4048 /* ENGINE_PASSING: Set ENGINE_RENDER, return _RENDER (abnormal) */
4049 /* ENGINE_RENDER: Return _RENDER (abnormal) */
4050 /******************************************************************/
4051
asysn_audiounit_realtime_enterstate(asysn_audiounit_InstanceState * My)4052 int asysn_audiounit_realtime_enterstate(asysn_audiounit_InstanceState * My)
4053
4054 {
4055 int ret;
4056
4057 do
4058 {
4059 switch(My->istate) {
4060 case ASYS_AUDIOUNIT_ISTATE_ABSENT:
4061 ret = ASYS_AUDIOUNIT_IRESPONSE_MY_IS_NULL;
4062 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4063 ("\tBad transition - realtime_entrance (absent)\n\n");
4064 break;
4065 case ASYS_AUDIOUNIT_ISTATE_INSTANCE:
4066 if (!OSAtomicCompareAndSwap32Barrier
4067 (ASYS_AUDIOUNIT_ISTATE_INSTANCE,
4068 ASYS_AUDIOUNIT_ISTATE_INSTANCE_PASSING,
4069 (int32_t *) &(My->istate)))
4070 continue;
4071 ret = ASYS_AUDIOUNIT_IRESPONSE_WIRE;
4072 break;
4073 case ASYS_AUDIOUNIT_ISTATE_INSTANCE_PASSING:
4074 if (!OSAtomicCompareAndSwap32Barrier
4075 (ASYS_AUDIOUNIT_ISTATE_INSTANCE_PASSING,
4076 ASYS_AUDIOUNIT_ISTATE_INSTANCE,
4077 (int32_t *) &(My->istate)))
4078 continue;
4079 ret = ASYS_AUDIOUNIT_IRESPONSE_WIRE;
4080 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4081 ("\tBad transition - realtime_entrance (instance_passing)\n\n");
4082 break;
4083 case ASYS_AUDIOUNIT_ISTATE_FLUX:
4084 if (!OSAtomicCompareAndSwap32Barrier
4085 (ASYS_AUDIOUNIT_ISTATE_FLUX,
4086 ASYS_AUDIOUNIT_ISTATE_FLUX_PASSING,
4087 (int32_t *) &(My->istate)))
4088 continue;
4089 ret = ASYS_AUDIOUNIT_IRESPONSE_WIRE;
4090 break;
4091 case ASYS_AUDIOUNIT_ISTATE_FLUX_PASSING:
4092 if (!OSAtomicCompareAndSwap32Barrier
4093 (ASYS_AUDIOUNIT_ISTATE_FLUX_PASSING,
4094 ASYS_AUDIOUNIT_ISTATE_FLUX,
4095 (int32_t *) &(My->istate)))
4096 continue;
4097 ret = ASYS_AUDIOUNIT_IRESPONSE_WIRE;
4098 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4099 ("\tBad transition - realtime_entrance (flux_passing)\n\n");
4100 break;
4101 case ASYS_AUDIOUNIT_ISTATE_ENGINE:
4102 if (!OSAtomicCompareAndSwap32Barrier
4103 (ASYS_AUDIOUNIT_ISTATE_ENGINE,
4104 ASYS_AUDIOUNIT_ISTATE_ENGINE_PASSING,
4105 (int32_t *) &(My->istate)))
4106 continue;
4107 ret = ASYS_AUDIOUNIT_IRESPONSE_RENDER;
4108 break;
4109 case ASYS_AUDIOUNIT_ISTATE_ENGINE_PASSING:
4110 if (!OSAtomicCompareAndSwap32Barrier
4111 (ASYS_AUDIOUNIT_ISTATE_ENGINE_PASSING,
4112 ASYS_AUDIOUNIT_ISTATE_ENGINE,
4113 (int32_t *) &(My->istate)))
4114 continue;
4115 ret = ASYS_AUDIOUNIT_IRESPONSE_RENDER;
4116 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4117 ("\tBad transition - realtime_entrance (engine_passing)\n\n");
4118 break;
4119 case ASYS_AUDIOUNIT_ISTATE_ENGINE_RENDER:
4120 if (!OSAtomicCompareAndSwap32Barrier
4121 (ASYS_AUDIOUNIT_ISTATE_ENGINE_RENDER,
4122 ASYS_AUDIOUNIT_ISTATE_ENGINE,
4123 (int32_t *) &(My->istate)))
4124 continue;
4125 ret = ASYS_AUDIOUNIT_IRESPONSE_RENDER;
4126 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4127 ("\tBad transition - realtime_entrance (engine_render)\n\n");
4128 break;
4129 default:
4130 ret = ASYS_AUDIOUNIT_IRESPONSE_ERROR;
4131 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4132 ("\tBad transition - realtime_entrance (default)\n\n");
4133 break;
4134 }
4135 } while (0);
4136
4137 return ret;
4138 }
4139
4140 /************************************************************/
4141 /* State transition diagram on exit from real-time thread: */
4142 /* */
4143 /* ABSENT: Return _MY_IS_NULL (abnormal) */
4144 /* INSTANCE: Return _COMPLETE (abnormal) */
4145 /* INSTANCE_PASSING: Set INSTANCE, return _COMPLETE */
4146 /* FLUX: Return _COMPLETE (abnormal) */
4147 /* FLUX_PASSING: Set FLUX, return _COMPLETE */
4148 /* ENGINE: Return _COMPLETE (abnormal) */
4149 /* ENGINE_PASSING: Set ENGINE, return _COMPLETE */
4150 /* ENGINE_RENDER: Set ENGINE, return _COMPLETE */
4151 /************************************************************/
4152
asysn_audiounit_realtime_exitstate(asysn_audiounit_InstanceState * My)4153 int asysn_audiounit_realtime_exitstate(asysn_audiounit_InstanceState * My)
4154
4155 {
4156 int ret;
4157
4158 do
4159 {
4160 switch(My->istate) {
4161 case ASYS_AUDIOUNIT_ISTATE_ABSENT:
4162 ret = ASYS_AUDIOUNIT_IRESPONSE_MY_IS_NULL;
4163 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4164 ("\tBad transition - realtime_exit (absent)\n\n");
4165 break;
4166 case ASYS_AUDIOUNIT_ISTATE_INSTANCE:
4167 ret = ASYS_AUDIOUNIT_IRESPONSE_COMPLETE;
4168 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4169 ("\tBad transition - realtime_exit (instance)\n\n");
4170 break;
4171 case ASYS_AUDIOUNIT_ISTATE_INSTANCE_PASSING:
4172 if (!OSAtomicCompareAndSwap32Barrier
4173 (ASYS_AUDIOUNIT_ISTATE_INSTANCE_PASSING,
4174 ASYS_AUDIOUNIT_ISTATE_INSTANCE,
4175 (int32_t *) &(My->istate)))
4176 continue;
4177 ret = ASYS_AUDIOUNIT_IRESPONSE_COMPLETE;
4178 break;
4179 case ASYS_AUDIOUNIT_ISTATE_FLUX:
4180 ret = ASYS_AUDIOUNIT_IRESPONSE_COMPLETE;
4181 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4182 ("\tBad transition - realtime_exit (flux)\n\n");
4183 break;
4184 case ASYS_AUDIOUNIT_ISTATE_FLUX_PASSING:
4185 if (!OSAtomicCompareAndSwap32Barrier
4186 (ASYS_AUDIOUNIT_ISTATE_FLUX_PASSING,
4187 ASYS_AUDIOUNIT_ISTATE_FLUX,
4188 (int32_t *) &(My->istate)))
4189 continue;
4190 ret = ASYS_AUDIOUNIT_IRESPONSE_COMPLETE;
4191 break;
4192 case ASYS_AUDIOUNIT_ISTATE_ENGINE:
4193 ret = ASYS_AUDIOUNIT_IRESPONSE_COMPLETE;
4194 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4195 ("\tBad transition - realtime_exit (engine)\n\n");
4196 break;
4197 case ASYS_AUDIOUNIT_ISTATE_ENGINE_PASSING:
4198 if (!OSAtomicCompareAndSwap32Barrier
4199 (ASYS_AUDIOUNIT_ISTATE_ENGINE_PASSING,
4200 ASYS_AUDIOUNIT_ISTATE_ENGINE,
4201 (int32_t *) &(My->istate)))
4202 continue;
4203 ret = ASYS_AUDIOUNIT_IRESPONSE_COMPLETE;
4204 break;
4205 case ASYS_AUDIOUNIT_ISTATE_ENGINE_RENDER:
4206 if (!OSAtomicCompareAndSwap32Barrier
4207 (ASYS_AUDIOUNIT_ISTATE_ENGINE_RENDER,
4208 ASYS_AUDIOUNIT_ISTATE_ENGINE,
4209 (int32_t *) &(My->istate)))
4210 continue;
4211 ret = ASYS_AUDIOUNIT_IRESPONSE_COMPLETE;
4212 break;
4213 default:
4214 ret = ASYS_AUDIOUNIT_IRESPONSE_ERROR;
4215 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4216 ("\tBad transition - realtime_exit (default)\n\n");
4217 break;
4218 }
4219 } while (0);
4220
4221 return ret;
4222 }
4223
4224 /*~~~~~~~~~~~~~~~~~~~~~~~~*/
4225 /*~~~~~~~~~~~~~~~~~~~~~~~~*/
4226 /* The Selector Calls */
4227 /*~~~~~~~~~~~~~~~~~~~~~~~~*/
4228 /*~~~~~~~~~~~~~~~~~~~~~~~~*/
4229
4230 /**************************************/
4231 /* Selector: Open */
4232 /* */
4233 /* params[0]: ComponentInstance ci */
4234 /* */
4235 /**************************************/
4236
asysn_audiounit_kComponentOpenSelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)4237 ComponentResult asysn_audiounit_kComponentOpenSelect(ComponentParameters * p,
4238 asysn_audiounit_InstanceState * My)
4239 {
4240 int socket_flags;
4241 int i, msize;
4242
4243 msize = sizeof(asysn_audiounit_InstanceState);
4244 if (!(My = (asysn_audiounit_InstanceState *) calloc(1, msize)))
4245 return asysn_audiounit_instance_cleanup(p, My);
4246 asysn_audiounit_memstatus(My, msize, MADV_WILLNEED);
4247
4248 My->component = (ComponentInstance) (p->params[0]);
4249 sprintf(My->componentname, "c%u", (unsigned int) My->component);
4250 My->argv[0] = My->componentname;
4251
4252 if (asysn_audiounit_initialize_properties(My) != noErr)
4253 return asysn_audiounit_instance_cleanup(p, My);
4254
4255 if (ASYS_AUDIOUNIT_EFFECT)
4256 {
4257 msize = (sizeof(UInt32) + sizeof(AudioBuffer)*ASYS_AUDIOUNIT_INPUT_MAXCHANNELS);
4258
4259 if (!(My->AudioBufferCarrier = calloc(msize, 1)))
4260 return asysn_audiounit_instance_cleanup(p, My);
4261
4262 if (!(My->AudioBufferTemplate = calloc(msize, 1)))
4263 return asysn_audiounit_instance_cleanup(p, My);
4264
4265 asysn_audiounit_memstatus(My->AudioBufferCarrier, msize, MADV_WILLNEED);
4266 asysn_audiounit_memstatus(My->AudioBufferTemplate, msize, MADV_WILLNEED);
4267
4268 My->AudioBufferTemplate->mNumberBuffers = ASYS_AUDIOUNIT_INPUT_CHANNELS;
4269
4270 msize = sizeof(Float32)*ASYS_AUDIOUNIT_FRAMES_PER_SLICE;
4271
4272 for(i = 0; i < ASYS_AUDIOUNIT_INPUT_MAXCHANNELS; i++)
4273 {
4274 My->AudioBufferTemplate->mBuffers[i].mNumberChannels = 1;
4275
4276 if (!(My->AudioBufferTemplate->mBuffers[i].mData = malloc(msize)))
4277 return asysn_audiounit_instance_cleanup(p, My);
4278
4279 asysn_audiounit_memstatus(My->AudioBufferTemplate->mBuffers[i].mData,
4280 msize, MADV_WILLNEED);
4281 }
4282 }
4283
4284 msize = sizeof(Float32)*ASYS_AUDIOUNIT_FRAMES_PER_SLICE;
4285
4286 for(i = 0; i < ASYS_AUDIOUNIT_OUTPUT_MAXCHANNELS; i++)
4287 {
4288 if (!(My->mData_Output[i] = (Float32 *) malloc(msize)))
4289 return asysn_audiounit_instance_cleanup(p, My);
4290 asysn_audiounit_memstatus(My->mData_Output[i], msize, MADV_WILLNEED);
4291 }
4292
4293 if (ASYS_AUDIOUNIT_HAS_AUCONTROL)
4294 {
4295 /*~~~~~~~~~~~~~~~~~~~~*/
4296 /* set up MIDI socket */
4297 /*--------------------*/
4298
4299 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, My->mpipepair))
4300 {
4301 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4302 ("\n\tIn OpenSelect: Error during MIDI socketpair() call.\n");
4303 return asysn_audiounit_instance_cleanup(p, My);
4304 }
4305
4306 if ((socket_flags = fcntl(My->mpipepair[0], F_GETFL, 0)) == -1)
4307 {
4308 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4309 ("\n\tIn OpenSelect: Error during mpipepair[0] F_GETFL fcntl() call.\n");
4310 return asysn_audiounit_instance_cleanup(p, My);
4311 }
4312
4313 if (fcntl(My->mpipepair[0], F_SETFL, socket_flags | O_NONBLOCK) == -1)
4314 {
4315 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4316 ("\n\tIn OpenSelect: Error during mpipepair[0] F_SETFL fcntl() call.\n");
4317 return asysn_audiounit_instance_cleanup(p, My);
4318 }
4319
4320 /*~~~~~~~~~~~~~~~~~~~~*/
4321 /* set up SASL socket */
4322 /*--------------------*/
4323
4324 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, My->spipepair))
4325 {
4326 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4327 ("\n\tIn OpenSelect: Error during SASL socketpair() call.\n");
4328 return asysn_audiounit_instance_cleanup(p, My);
4329 }
4330
4331 if ((socket_flags = fcntl(My->spipepair[0], F_GETFL, 0)) == -1)
4332 {
4333 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4334 ("\n\tIn OpenSelect: Error during spipepair[0] F_GETFL fcntl() call.\n");
4335 return asysn_audiounit_instance_cleanup(p, My);
4336 }
4337
4338 if (fcntl(My->spipepair[0], F_SETFL, socket_flags | O_NONBLOCK) == -1)
4339 {
4340 ASYS_AUDIOUNIT_WIRETAP_PUTSTRING
4341 ("\n\tIn OpenSelect: Error during spipepair[0] F_SETFL fcntl() call.\n");
4342 return asysn_audiounit_instance_cleanup(p, My);
4343 }
4344
4345 /*~~~~~~~~~~~~~~~~~~~~~~*/
4346 /* set up argc and argv */
4347 /*----------------------*/
4348
4349 My->argc = 5;
4350
4351 My->argv[1] = My->mpipeflag;
4352 My->argv[2] = My->mpipevalue;
4353
4354 sprintf(My->mpipeflag, "-asys_audiounit_mpipe");
4355 sprintf(My->mpipevalue, "%i", My->mpipepair[0]);
4356
4357 My->argv[3] = My->spipeflag;
4358 My->argv[4] = My->spipevalue;
4359
4360 sprintf(My->spipeflag, "-asys_audiounit_spipe");
4361 sprintf(My->spipevalue, "%i", My->spipepair[0]);
4362 }
4363 else
4364 {
4365 My->argc = 1;
4366
4367 My->argv[1] = My->argv[2] = NULL;
4368 My->mpipepair[0] = My->mpipepair[1] = 0;
4369
4370 My->argv[3] = My->argv[4] = NULL;
4371 My->spipepair[0] = My->spipepair[1] = 0;
4372 }
4373
4374 if (asysn_audiounit_initialize_parametersystem(My) != noErr)
4375 return asysn_audiounit_instance_cleanup(p, My);
4376
4377 OSSpinLockLock(&asysn_audiounit_lock_opencount);
4378
4379 if (!(asysn_audiounit_opencount++))
4380 asysn_audiounit_globalvars_memstatus(MADV_WILLNEED);
4381
4382 OSSpinLockUnlock(&asysn_audiounit_lock_opencount);
4383
4384 My->istate = ASYS_AUDIOUNIT_ISTATE_INSTANCE;
4385
4386 SetComponentInstanceStorage((ComponentInstance) p->params[0], (Handle) My);
4387
4388 return noErr;
4389 }
4390
4391 /**************************************/
4392 /* Selector: Close */
4393 /* */
4394 /* params[0]: ComponentInstance ci */
4395 /* */
4396 /**************************************/
4397
asysn_audiounit_kComponentCloseSelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)4398 ComponentResult asysn_audiounit_kComponentCloseSelect(ComponentParameters * p,
4399 asysn_audiounit_InstanceState * My)
4400 {
4401 ENGINE_PTR_DECLARE_SEMICOLON
4402 asysn_audiounit_proplisten * remove;
4403 asysn_audiounit_rendernotify * notify;
4404 int i, k, msize, ret;
4405
4406 ret = asysn_audiounit_closeselect_enterstate(My);
4407
4408 SetComponentInstanceStorage((ComponentInstance) p->params[0], (Handle) NULL);
4409
4410 switch (ret) {
4411 case ASYS_AUDIOUNIT_IRESPONSE_UNINITIALIZE_AND_CLOSE:
4412 ENGINE_PTR_ASSIGNED_TO MY_ENGINE_PTR;
4413 ENGINE_MEMSTATUS_SEMICOLON(MADV_FREE)
4414 shut_down(ENGINE_PTR);
4415 MY_ENGINE_PTR_ASSIGNED_TO NULL;
4416 break;
4417 case ASYS_AUDIOUNIT_IRESPONSE_CLOSE:
4418 break;
4419 case ASYS_AUDIOUNIT_IRESPONSE_MY_IS_NULL:
4420 case ASYS_AUDIOUNIT_IRESPONSE_ERROR:
4421 default:
4422 return noErr;
4423 }
4424
4425 if (ASYS_AUDIOUNIT_HAS_AUCONTROL)
4426 {
4427 close(My->mpipepair[0]);
4428 close(My->mpipepair[1]);
4429 close(My->spipepair[0]);
4430 close(My->spipepair[1]);
4431
4432 if (My->num_saolparams)
4433 {
4434 free(My->parameterlist);
4435 for (i = 0; i < My->num_saolparams; i++)
4436 {
4437 if (My->parameterinfo[i].cfNameString)
4438 CFRelease(My->parameterinfo[i].cfNameString);
4439 if (My->parameterinfo[i].unitName)
4440 CFRelease(My->parameterinfo[i].unitName);
4441 }
4442 free(My->parameterinfo);
4443
4444 for (i = 0; i < My->num_saolparams; i++)
4445 if (My->pvs_size[i])
4446 {
4447 for (k = 0; k < My->pvs_size[i]; k++)
4448 free(My->pvs_cstr[i][k]);
4449 free(My->pvs_cstr[i]);
4450 }
4451 free(My->pvs_size);
4452 free(My->pvs_cstr);
4453
4454 msize = My->num_saolparams*sizeof(asysn_audiounit_saolparam);
4455 asysn_audiounit_memstatus(My->saolparam, msize, MADV_FREE);
4456 free(My->saolparam);
4457 }
4458
4459 if (My->num_factory)
4460 {
4461 for (i = 0; i < My->num_factory; i++)
4462 {
4463 if (My->factorypreset_values[i])
4464 {
4465 msize = My->num_saolparams*sizeof(Float32);
4466 asysn_audiounit_memstatus(My->factorypreset_values[i],
4467 msize, MADV_FREE);
4468 free(My->factorypreset_values[i]);
4469 }
4470
4471 if (My->factorypreset_info[i].presetName)
4472 CFRelease(My->factorypreset_info[i].presetName);
4473 }
4474
4475 msize = My->num_factory*sizeof(Float32 *);
4476 asysn_audiounit_memstatus(My->factorypreset_values, msize, MADV_FREE);
4477 free(My->factorypreset_values);
4478
4479 free(My->factorypreset_info);
4480 CFRelease(My->factorypreset_array);
4481 }
4482 }
4483
4484
4485 OSSpinLockLock(&(My->lock_PresentPreset));
4486
4487 CFRelease(My->PresentPreset.presetName);
4488
4489 OSSpinLockUnlock(&(My->lock_PresentPreset));
4490
4491
4492 OSSpinLockLock(&(My->lock_proplisteners));
4493
4494 for (i = 0; i < ASYS_AUDIOUNIT_PROPLISTEN_ARRAYSIZE; i++)
4495 while (My->proplisteners[i] != NULL)
4496 {
4497 remove = My->proplisteners[i];
4498 My->proplisteners[i] = My->proplisteners[i]->next;
4499 msize = sizeof(asysn_audiounit_proplisten);
4500 asysn_audiounit_memstatus(remove, msize, MADV_FREE);
4501 free(remove);
4502 }
4503
4504 OSSpinLockUnlock(&(My->lock_proplisteners));
4505
4506
4507 OSSpinLockLock(&(My->lock_rendernotify));
4508
4509 while (My->rendernotify)
4510 {
4511 notify = My->rendernotify;
4512 My->rendernotify = notify->next;
4513 msize = sizeof(asysn_audiounit_rendernotify);
4514 asysn_audiounit_memstatus(notify, msize, MADV_FREE);
4515 free(notify);
4516 }
4517
4518 OSSpinLockUnlock(&(My->lock_rendernotify));
4519
4520
4521 if (ASYS_AUDIOUNIT_EFFECT)
4522 {
4523 msize = (sizeof(UInt32) + sizeof(AudioBuffer)*ASYS_AUDIOUNIT_INPUT_MAXCHANNELS);
4524 asysn_audiounit_memstatus(My->AudioBufferCarrier, msize, MADV_FREE);
4525 free(My->AudioBufferCarrier);
4526
4527 msize = sizeof(Float32)*ASYS_AUDIOUNIT_FRAMES_PER_SLICE;
4528 for(i = 0; i < ASYS_AUDIOUNIT_INPUT_MAXCHANNELS; i++)
4529 {
4530 asysn_audiounit_memstatus(My->AudioBufferTemplate->mBuffers[i].mData,
4531 msize, MADV_FREE);
4532 free(My->AudioBufferTemplate->mBuffers[i].mData);
4533 }
4534
4535 msize = (sizeof(UInt32) + sizeof(AudioBuffer)*ASYS_AUDIOUNIT_INPUT_MAXCHANNELS);
4536 asysn_audiounit_memstatus(My->AudioBufferTemplate, msize, MADV_FREE);
4537 free(My->AudioBufferTemplate);
4538 }
4539
4540 for(i = 0; i < ASYS_AUDIOUNIT_OUTPUT_MAXCHANNELS; i++)
4541 {
4542 msize = sizeof(Float32)*ASYS_AUDIOUNIT_FRAMES_PER_SLICE;
4543 asysn_audiounit_memstatus(My->mData_Output[i], msize, MADV_FREE);
4544 free(My->mData_Output[i]);
4545 }
4546
4547 msize = sizeof(asysn_audiounit_InstanceState);
4548 asysn_audiounit_memstatus(My, msize, MADV_FREE);
4549 free(My);
4550
4551 OSSpinLockLock(&asysn_audiounit_lock_opencount);
4552
4553 if (!(--asysn_audiounit_opencount))
4554 asysn_audiounit_globalvars_memstatus(MADV_FREE);
4555
4556 if (asysn_audiounit_opencount < 0) /* should never be true */
4557 asysn_audiounit_opencount = 0;
4558
4559 OSSpinLockUnlock(&asysn_audiounit_lock_opencount);
4560
4561 return noErr;
4562 }
4563
4564 /************************/
4565 /* Selector: Initialize */
4566 /* */
4567 /************************/
4568
asysn_audiounit_kAudioUnitInitializeSelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)4569 ComponentResult asysn_audiounit_kAudioUnitInitializeSelect(ComponentParameters * p,
4570 asysn_audiounit_InstanceState * My)
4571 {
4572 ENGINE_PTR_DECLARE_SEMICOLON
4573
4574 switch (asysn_audiounit_initializeselect_enterstate(My)) {
4575 case ASYS_AUDIOUNIT_IRESPONSE_INITIALIZE:
4576 break;
4577 case ASYS_AUDIOUNIT_IRESPONSE_MY_IS_NULL:
4578 case ASYS_AUDIOUNIT_IRESPONSE_REINITIALIZE:
4579 default:
4580 return noErr;
4581 }
4582
4583 ENGINE_PTR_ASSIGNED_TO system_init(My->argc, My->argv,
4584 My->OutputStreamFormat.mSampleRate);
4585
4586 MY_ENGINE_PTR_ASSIGNED_TO ENGINE_PTR;
4587
4588 if (ENGINE_PTR_IS_NULL)
4589 return kAudioUnitErr_FailedInitialization;
4590
4591 ENGINE_MEMSTATUS_SEMICOLON(MADV_WILLNEED)
4592
4593 effects_init(ENGINE_PTR);
4594 main_initpass(ENGINE_PTR);
4595 asysn_audiounit_ksyncinit(My);
4596
4597 EV(kcycleidx) = EV(kbase);
4598 EV(acycleidx) = EV(ACYCLE) + 1; /* +1 denotes zero-time condition */
4599 EV(pass) = IPASS;
4600
4601 My->acycle = EV(ACYCLE);
4602
4603 OSSpinLockLock(&(My->lock_CPULoad));
4604
4605 My->krate = EV(KRATE);
4606
4607 My->ksync_normalize = (Float32) (My->krate/AudioGetHostClockFrequency());
4608 if (My->CPULoad)
4609 My->ksync_normalize = My->ksync_normalize/My->CPULoad;
4610
4611 OSSpinLockUnlock(&(My->lock_CPULoad));
4612
4613 My->acycleidx_kcycleidx = 1; /* acycleidx = 0, kcycleidx = 1 */
4614
4615 if (ASYS_AUDIOUNIT_HAS_AUCONTROL)
4616 asysn_audiounit_engine_parameter_update(My);
4617
4618 asysn_audiounit_initializeselect_exitstate(My);
4619
4620 return noErr;
4621 }
4622
4623 /**************************/
4624 /* Selector: Uninitialize */
4625 /* */
4626 /**************************/
4627
asysn_audiounit_kAudioUnitUninitializeSelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)4628 ComponentResult asysn_audiounit_kAudioUnitUninitializeSelect(ComponentParameters * p,
4629 asysn_audiounit_InstanceState * My)
4630 {
4631 int j;
4632 ENGINE_PTR_DECLARE_SEMICOLON
4633
4634 switch (asysn_audiounit_uninitializeselect_enterstate(My)) {
4635 case ASYS_AUDIOUNIT_IRESPONSE_UNINITIALIZE:
4636 break;
4637 case ASYS_AUDIOUNIT_IRESPONSE_MY_IS_NULL:
4638 case ASYS_AUDIOUNIT_IRESPONSE_REUNINITIALIZE:
4639 default:
4640 return noErr;
4641 }
4642
4643 ENGINE_PTR_ASSIGNED_TO MY_ENGINE_PTR;
4644 ENGINE_MEMSTATUS_SEMICOLON(MADV_FREE)
4645 shut_down(ENGINE_PTR);
4646 MY_ENGINE_PTR_ASSIGNED_TO NULL;
4647
4648 My->acycle = ((int)(SAOL_SRATE))/((int)(SAOL_KRATE));
4649
4650 OSSpinLockLock(&(My->lock_CPULoad));
4651
4652 My->krate = SAOL_KRATE;
4653
4654 My->ksync_normalize = (Float32) (My->krate/AudioGetHostClockFrequency());
4655 if (My->CPULoad)
4656 My->ksync_normalize = My->ksync_normalize/My->CPULoad;
4657
4658 OSSpinLockUnlock(&(My->lock_CPULoad));
4659
4660 My->acycleidx_kcycleidx = 1; /* acycleidx = 0, kcycleidx = 1 */
4661
4662 asysn_audiounit_uninitializeselect_exitstate(My);
4663 asysn_audiounit_engine_emptypipes(My);
4664
4665 return noErr;
4666 }
4667
4668 /********************************************/
4669 /* Selector: GetPropertyInfo */
4670 /* */
4671 /* params[0]: Boolean * outWritable; */
4672 /* params[1]: UInt32 * outDataSize; */
4673 /* params[2]: AudioUnitElement inElement; */
4674 /* params[3]: AudioUnitScope inScope; */
4675 /* params[4]: AudioUnitPropertyID inID; */
4676 /* */
4677 /********************************************/
4678
asysn_audiounit_kAudioUnitGetPropertyInfoSelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)4679 ComponentResult asysn_audiounit_kAudioUnitGetPropertyInfoSelect
4680 (ComponentParameters * p, asysn_audiounit_InstanceState * My)
4681
4682 {
4683 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
4684 /* return early for invalid properties */
4685 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
4686
4687 if (!asysn_audiounit_supported_property((AudioUnitPropertyID)(p->params[4]),
4688 (AudioUnitScope)(p->params[3])))
4689 return kAudioUnitErr_InvalidProperty;
4690
4691 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
4692 /* provide datasize if requested by a non-null pointer */
4693 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
4694
4695 if (p->params[1])
4696 *((UInt32 *)(p->params[1])) = asysn_audiounit_property_size(p->params[4], My);
4697
4698 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
4699 /* provide writable status if requested by a non-null pointer */
4700 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
4701
4702 if (p->params[0])
4703 {
4704 switch (p->params[4] /* property ID */) {
4705 case kAudioUnitProperty_ParameterList: /* 3 */
4706 case kAudioUnitProperty_ParameterInfo: /* 4 */
4707 case kAudioUnitProperty_FastDispatch: /* 5 */
4708 *((Boolean *)(p->params[0])) = 0;
4709 break;
4710 case kAudioUnitProperty_ElementCount: /* 11, also kAudioUnitProperty_BusCount */
4711 /* for hosts that require AUs to support side-chaining */
4712 *((Boolean *)(p->params[0])) = (p->params[3] == kAudioUnitScope_Input);
4713 break;
4714 case kAudioUnitProperty_SupportedNumChannels: /* 13 */
4715 case kAudioUnitProperty_ParameterValueStrings: /* 16 */
4716 case kAudioUnitProperty_FactoryPresets: /* 24 */
4717 case kAudioUnitProperty_CocoaUI: /* 31 */
4718 *((Boolean *)(p->params[0])) = 0;
4719 break;
4720 default:
4721 *((Boolean *)(p->params[0])) = 1;
4722 break;
4723 }
4724 }
4725
4726 return noErr;
4727 }
4728
4729 /********************************************/
4730 /* Selector: GetProperty */
4731 /* */
4732 /* params[0]: UInt32 * ioDataSize; */
4733 /* params[1]: void * outData; */
4734 /* params[2]: AudioUnitElement inElement; */
4735 /* params[3]: AudioUnitScope inScope; */
4736 /* params[4]: AudioUnitPropertyID inID; */
4737 /* */
4738 /********************************************/
4739
asysn_audiounit_kAudioUnitGetPropertySelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)4740 ComponentResult asysn_audiounit_kAudioUnitGetPropertySelect(ComponentParameters * p,
4741 asysn_audiounit_InstanceState * My)
4742 {
4743 ComponentResult result = noErr;
4744 CFBundleRef au_bundle = NULL;
4745 CFURLRef view_bundle_url = NULL;
4746 UInt32 size;
4747
4748 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
4749 /* return early for invalid properties */
4750 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
4751
4752 if (!asysn_audiounit_supported_property((AudioUnitPropertyID)(p->params[4]),
4753 (AudioUnitScope)(p->params[3])))
4754 return kAudioUnitErr_InvalidProperty;
4755
4756 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
4757 /* check size of property storage */
4758 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
4759
4760 if (*((UInt32 *)(p->params[0])) !=
4761 (size = asysn_audiounit_property_size(p->params[4], My)))
4762 if (*((UInt32 *)(p->params[0])) > size)
4763 *((UInt32 *)(p->params[0])) = size;
4764 else
4765 return kAudioUnitErr_InvalidPropertyValue;
4766
4767 /*~~~~~~~~~~~~~~~~~~~~~~~*/
4768 /* assign property value */
4769 /*~~~~~~~~~~~~~~~~~~~~~~~*/
4770
4771 switch (p->params[4] /* property ID */) {
4772 case kAudioUnitProperty_ClassInfo: /* 0 */
4773 *((CFPropertyListRef *)((void *)(p->params[1]))) =
4774 asysn_audiounit_classinfo_create(My);
4775 break;
4776 case kAudioUnitProperty_MakeConnection: /* 1 */
4777 if ((p->params[2] >= ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE) ||
4778 (p->params[2] < 0))
4779 {
4780 result = kAudioUnitErr_InvalidProperty;
4781 break;
4782 }
4783 OSSpinLockLock(&(My->lock_sampledelivery));
4784 ((AudioUnitConnection *)((void *)(p->params[1])))->sourceAudioUnit
4785 = My->MakeConnection[p->params[2]].sourceAudioUnit;
4786 ((AudioUnitConnection *)((void *)(p->params[1])))->sourceOutputNumber
4787 = My->MakeConnection[p->params[2]].sourceOutputNumber;
4788 ((AudioUnitConnection *)((void *)(p->params[1])))->destInputNumber
4789 = My->MakeConnection[p->params[2]].destInputNumber;
4790 OSSpinLockUnlock(&(My->lock_sampledelivery));
4791 break;
4792 case kAudioUnitProperty_SampleRate: /* 2 */
4793 switch (p->params[3] /* inScope */ ) {
4794 case kAudioUnitScope_Input:
4795 if (!(ASYS_AUDIOUNIT_EFFECT) ||
4796 (p->params[2] >= ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE) ||
4797 (p->params[2] < 0))
4798 {
4799 result = kAudioUnitErr_InvalidProperty;
4800 break;
4801 }
4802 *((Float64 *)((void *)(p->params[1]))) =
4803 My->InputStreamFormat[p->params[2]].mSampleRate;
4804 break;
4805 case kAudioUnitScope_Global:
4806 case kAudioUnitScope_Output:
4807 *((Float64 *)((void *)(p->params[1]))) = My->OutputStreamFormat.mSampleRate;
4808 break;
4809 default:
4810 result = kAudioUnitErr_InvalidProperty;
4811 break;
4812 }
4813 break;
4814 case kAudioUnitProperty_ParameterList: /* 3 */
4815 memcpy(((AudioUnitParameterID *)((void *)(p->params[1]))), My->parameterlist,
4816 sizeof(AudioUnitParameterID)*My->num_saolparams);
4817 break;
4818 case kAudioUnitProperty_ParameterInfo: /* 4 */
4819 if (p->params[2] < My->num_saolparams) /* p->param[2] requests ParameterID. */
4820 {
4821 if (My->parameterinfo[p->params[2]].cfNameString)
4822 CFRetain(My->parameterinfo[p->params[2]].cfNameString);
4823 if (My->parameterinfo[p->params[2]].unitName)
4824 CFRetain(My->parameterinfo[p->params[2]].unitName);
4825 memcpy(((AudioUnitParameterInfo *)((void *)(p->params[1]))),
4826 &(My->parameterinfo[p->params[2]]), sizeof(AudioUnitParameterInfo));
4827 }
4828 else
4829 result = kAudioUnitErr_InvalidProperty;
4830 break;
4831 case kAudioUnitProperty_FastDispatch: /* 5 */
4832 switch (p->params[2] /* inElement */ ) {
4833 case kAudioUnitRenderSelect:
4834 *((AudioUnitRenderProc *)(p->params[1])) = asysn_audiounit_MyRenderer;
4835 break;
4836 case kMusicDeviceMIDIEventSelect:
4837 if (ASYS_AUDIOUNIT_MIDISUPPORT)
4838 *((MusicDeviceMIDIEventProc *)(p->params[1])) = asysn_audiounit_MyMIDIEventProc;
4839 else
4840 result = kAudioUnitErr_InvalidProperty;
4841 break;
4842 case kAudioUnitGetParameterSelect:
4843 *((AudioUnitGetParameterProc *)(p->params[1])) =
4844 asysn_audiounit_MyGetParameterProc;
4845 break;
4846 case kAudioUnitSetParameterSelect:
4847 *((AudioUnitSetParameterProc *)(p->params[1])) =
4848 asysn_audiounit_MySetParameterProc;
4849 break;
4850 default:
4851 result = kAudioUnitErr_InvalidProperty;
4852 break;
4853 }
4854 break;
4855 case kAudioUnitProperty_CPULoad: /* 6 */
4856 *((Float32 *)((void *)(p->params[1]))) = My->CPULoad;
4857 break;
4858 case kAudioUnitProperty_StreamFormat: /* 8 */
4859 switch (p->params[3] /* inScope */ ) {
4860 case kAudioUnitScope_Input:
4861 if (!(ASYS_AUDIOUNIT_EFFECT) ||
4862 (p->params[2] >= ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE) ||
4863 (p->params[2] < 0))
4864 {
4865 result = kAudioUnitErr_InvalidProperty;
4866 break;
4867 }
4868 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mChannelsPerFrame
4869 = My->InputStreamFormat[p->params[2]].mChannelsPerFrame;
4870 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mSampleRate
4871 = My->InputStreamFormat[p->params[2]].mSampleRate;
4872 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mFormatID
4873 = My->InputStreamFormat[p->params[2]].mFormatID;
4874 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mFormatFlags
4875 = My->InputStreamFormat[p->params[2]].mFormatFlags;
4876 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mBytesPerPacket
4877 = My->InputStreamFormat[p->params[2]].mBytesPerPacket;
4878 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mBytesPerFrame
4879 = My->InputStreamFormat[p->params[2]].mBytesPerFrame;
4880 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mFramesPerPacket
4881 = My->InputStreamFormat[p->params[2]].mFramesPerPacket;
4882 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mBitsPerChannel
4883 = My->InputStreamFormat[p->params[2]].mBitsPerChannel;
4884 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mReserved
4885 = My->InputStreamFormat[p->params[2]].mReserved;
4886 break;
4887 case kAudioUnitScope_Global:
4888 case kAudioUnitScope_Output:
4889 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mChannelsPerFrame
4890 = My->OutputStreamFormat.mChannelsPerFrame;
4891 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mSampleRate
4892 = My->OutputStreamFormat.mSampleRate;
4893 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mFormatID
4894 = My->OutputStreamFormat.mFormatID;
4895 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mFormatFlags
4896 = My->OutputStreamFormat.mFormatFlags;
4897 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mBytesPerPacket
4898 = My->OutputStreamFormat.mBytesPerPacket;
4899 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mBytesPerFrame
4900 = My->OutputStreamFormat.mBytesPerFrame;
4901 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mFramesPerPacket
4902 = My->OutputStreamFormat.mFramesPerPacket;
4903 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mBitsPerChannel
4904 = My->OutputStreamFormat.mBitsPerChannel;
4905 ((AudioStreamBasicDescription *)((void *)(p->params[1])))->mReserved
4906 = My->OutputStreamFormat.mReserved;
4907 break;
4908 default:
4909 result = kAudioUnitErr_InvalidProperty;
4910 break;
4911 }
4912 break;
4913 case kAudioUnitProperty_SRCAlgorithm: /* 9 */
4914 *((OSType *)((void *)(p->params[1]))) = My->SRCAlgorithm;
4915 break;
4916 case kAudioUnitProperty_ElementCount: /* 11, also kAudioUnitProperty_BusCount */
4917 switch (p->params[3] /* inScope */ ) {
4918 case kAudioUnitScope_Input:
4919 *((UInt32 *)((void *)(p->params[1]))) = My->InputElementCount;
4920 break;
4921 case kAudioUnitScope_Global:
4922 case kAudioUnitScope_Output:
4923 *((UInt32 *)((void *)(p->params[1]))) = My->OutputElementCount;
4924 break;
4925 case kAudioUnitScope_Part:
4926 case kAudioUnitScope_Group:
4927 *((UInt32 *)((void *)(p->params[1]))) = 0;
4928 break;
4929 default:
4930 result = kAudioUnitErr_InvalidProperty;
4931 break;
4932 }
4933 break;
4934 case kAudioUnitProperty_Latency: /* 12 */
4935 *((Float64 *)((void *)(p->params[1]))) = My->Latency;
4936 break;
4937 case kAudioUnitProperty_SupportedNumChannels: /* 13 */
4938 memcpy(((AudioUnitParameterID *)((void *)(p->params[1]))), My->SupportedNumChannels,
4939 ASYS_AUDIOUNIT_SUPPORTED_FORMATS*sizeof(AUChannelInfo));
4940 break;
4941 case kAudioUnitProperty_MaximumFramesPerSlice: /* 14 */
4942 *((UInt32 *)((void *)(p->params[1]))) = My->MaximumFramesPerSlice;
4943 break;
4944 case kAudioUnitProperty_ParameterValueStrings: /* 16 */
4945 if ((*((CFMutableArrayRef *)((void *)(p->params[1]))) =
4946 asysn_audiounit_parametervaluestrings_create(My, p->params[2])) == NULL)
4947 result = kAudioUnitErr_InvalidProperty;
4948 break;
4949 case kAudioUnitProperty_TailTime: /* 20 */
4950 *((Float64 *)((void *)(p->params[1]))) = My->TailTime;
4951 break;
4952 case kAudioUnitProperty_BypassEffect: /* 21 */
4953 *((UInt32 *)((void *)(p->params[1]))) = My->BypassEffect;
4954 break;
4955 case kAudioUnitProperty_LastRenderError: /* 22 */
4956 *((OSStatus *)((void *)(p->params[1]))) = My->LastRenderError;
4957 My->LastRenderError = noErr;
4958 break;
4959 case kAudioUnitProperty_SetRenderCallback: /* 23 */
4960 if ((p->params[2] >= ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE) ||
4961 (p->params[2] < 0))
4962 {
4963 result = kAudioUnitErr_InvalidProperty;
4964 break;
4965 }
4966 OSSpinLockLock(&(My->lock_sampledelivery));
4967 ((AURenderCallbackStruct *)((void *)(p->params[1])))->inputProc
4968 = My->SetRenderCallback[p->params[2]].inputProc;
4969 ((AURenderCallbackStruct *)((void *)(p->params[1])))->inputProcRefCon
4970 = My->SetRenderCallback[p->params[2]].inputProcRefCon;
4971 OSSpinLockUnlock(&(My->lock_sampledelivery));
4972 break;
4973 case kAudioUnitProperty_FactoryPresets: /* 24 */
4974 if (My->num_factory)
4975 {
4976 CFRetain(My->factorypreset_array);
4977 *((CFPropertyListRef *)((void *)(p->params[1]))) = My->factorypreset_array;
4978 }
4979 else
4980 result = kAudioUnitErr_InvalidProperty;
4981 break;
4982 case kAudioUnitProperty_RenderQuality: /* 26 */
4983 *((UInt32 *)((void *)(p->params[1]))) = My->RenderQuality;
4984 break;
4985 case kAudioUnitProperty_InPlaceProcessing: /* 29 */
4986 *((UInt32 *)((void *)(p->params[1]))) = My->InPlaceProcessing;
4987 break;
4988 case kAudioUnitProperty_CocoaUI: /* 31 */
4989 #if defined(ASYS_AUDIOUNIT_VIEW_BUNDLECF)
4990
4991 if ((au_bundle = CFBundleGetBundleWithIdentifier(ASYS_AUDIOUNIT_AU_BUNDLECF)))
4992 CFRetain(au_bundle);
4993 else
4994 {
4995 result = kAudioUnitErr_InvalidProperty;
4996 break;
4997 }
4998
4999 view_bundle_url = CFBundleCopyResourceURL(au_bundle,
5000 ASYS_AUDIOUNIT_VIEW_BUNDLECF,
5001 CFSTR("bundle"), NULL);
5002 CFRelease(au_bundle);
5003
5004 if (!view_bundle_url)
5005 {
5006 result = kAudioUnitErr_InvalidProperty;
5007 break;
5008 }
5009
5010 ((AudioUnitCocoaViewInfo *)(p->params[1]))->mCocoaAUViewBundleLocation =
5011 view_bundle_url;
5012
5013 ((AudioUnitCocoaViewInfo *)(p->params[1]))->mCocoaAUViewClass[0] =
5014 CFStringCreateCopy(NULL, ASYS_AUDIOUNIT_VIEW_BASECLASSCF);
5015 #else
5016 result = kAudioUnitErr_InvalidProperty;
5017 #endif
5018 break;
5019 case kAudioUnitProperty_PresentPreset: /* 36 */
5020 OSSpinLockLock(&(My->lock_PresentPreset));
5021 ((AUPreset *)(p->params[1]))->presetNumber = My->PresentPreset.presetNumber;
5022 ((AUPreset *)(p->params[1]))->presetName = My->PresentPreset.presetName;
5023 CFRetain(My->PresentPreset.presetName);
5024 OSSpinLockUnlock(&(My->lock_PresentPreset));
5025 break;
5026 case kAudioUnitProperty_OfflineRender: /* 37 */
5027 *((UInt32 *)((void *)(p->params[1]))) = My->OfflineRender;
5028 break;
5029 case kAudioUnitProperty_PresentationLatency: /* 40 */
5030 *((Float64 *)((void *)(p->params[1]))) = My->PresentationLatency;
5031 break;
5032 case kMusicDeviceProperty_InstrumentCount: /* 1000 */
5033 if (ASYS_AUDIOUNIT_MUSICDEVICE)
5034 *((UInt32 *)((void *)(p->params[1]))) = My->InstrumentCount;
5035 else
5036 result = kAudioUnitErr_InvalidProperty;
5037 break;
5038 case kMusicDeviceProperty_StreamFromDisk: /* 1011 */
5039 *((UInt32 *)((void *)(p->params[1]))) = My->StreamFromDisk;
5040 break;
5041 default: /* should never happen */
5042 result = kAudioUnitErr_InvalidProperty;
5043 break;
5044 }
5045
5046 return result;
5047 }
5048
5049 /********************************************/
5050 /* Selector: SetProperty */
5051 /* */
5052 /* params[0]: UInt32 inDataSize; */
5053 /* params[1]: const void * inData; */
5054 /* params[2]: AudioUnitElement inElement; */
5055 /* params[3]: AudioUnitScope inScope; */
5056 /* params[4]: AudioUnitPropertyID inID; */
5057 /* */
5058 /********************************************/
5059
asysn_audiounit_kAudioUnitSetPropertySelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)5060 ComponentResult asysn_audiounit_kAudioUnitSetPropertySelect(ComponentParameters * p,
5061 asysn_audiounit_InstanceState * My)
5062 {
5063 ComponentResult result = noErr;
5064 CFStringRef key;
5065
5066 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5067 /* return early for invalid properties */
5068 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5069
5070 if (!asysn_audiounit_supported_property((AudioUnitPropertyID)(p->params[4]),
5071 (AudioUnitScope)(p->params[3])))
5072 return kAudioUnitErr_InvalidProperty;
5073
5074 switch (p->params[4] /* property ID */) {
5075 case kAudioUnitProperty_ClassInfo: /* 0 */
5076 asysn_audiounit_classinfo_read(
5077 My, *((CFMutableDictionaryRef *)((void *)(p->params[1]))));
5078 asysn_audiounit_proplisteners_update(My, kAudioUnitProperty_PresentPreset,
5079 kAudioUnitScope_Global, (AudioUnitElement) 0);
5080 asysn_audiounit_proplisteners_update(My, kAudioUnitProperty_RenderQuality,
5081 kAudioUnitScope_Global, (AudioUnitElement) 0);
5082 asysn_audiounit_proplisteners_update(My, kAudioUnitProperty_CPULoad,
5083 kAudioUnitScope_Global, (AudioUnitElement) 0);
5084 break;
5085 case kAudioUnitProperty_MakeConnection: /* 1 */
5086 if ((p->params[2] >= ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE) ||
5087 (p->params[2] < 0))
5088 {
5089 result = kAudioUnitErr_InvalidProperty;
5090 break;
5091 }
5092 OSSpinLockLock(&(My->lock_sampledelivery));
5093 My->MakeConnection[p->params[2]].sourceAudioUnit =
5094 ((AudioUnitConnection *)((void *)(p->params[1])))->sourceAudioUnit;
5095 My->MakeConnection[p->params[2]].sourceOutputNumber =
5096 ((AudioUnitConnection *)((void *)(p->params[1])))->sourceOutputNumber;
5097 My->MakeConnection[p->params[2]].destInputNumber =
5098 ((AudioUnitConnection *)((void *)(p->params[1])))->destInputNumber;
5099 OSSpinLockUnlock(&(My->lock_sampledelivery));
5100 break;
5101 case kAudioUnitProperty_SampleRate: /* 2 */
5102 switch (p->params[3] /* inScope */ ) {
5103 case kAudioUnitScope_Input:
5104 if (!(ASYS_AUDIOUNIT_EFFECT) ||
5105 (p->params[2] >= ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE) ||
5106 (p->params[2] < 0))
5107 {
5108 result = kAudioUnitErr_InvalidProperty;
5109 break;
5110 }
5111 My->InputStreamFormat[p->params[2]].mSampleRate =
5112 *((Float64 *)((void *)(p->params[1])));
5113 break;
5114 case kAudioUnitScope_Output:
5115 My->OutputStreamFormat.mSampleRate = *((Float64 *)((void *)(p->params[1])));
5116 break;
5117 case kAudioUnitScope_Global:
5118 if ((ASYS_AUDIOUNIT_EFFECT) &&
5119 (p->params[2] < ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE) ||
5120 (p->params[2] >= 0))
5121 My->InputStreamFormat[p->params[2]].mSampleRate =
5122 *((Float64 *)((void *)(p->params[1])));
5123 My->OutputStreamFormat.mSampleRate = *((Float64 *)((void *)(p->params[1])));
5124 break;
5125 default:
5126 result = kAudioUnitErr_InvalidProperty;
5127 break;
5128 }
5129 break;
5130 case kAudioUnitProperty_ParameterList: /* 3 */
5131 result = kAudioUnitErr_InvalidProperty;
5132 break; /* hosts not permitted to change Parameter List */
5133 case kAudioUnitProperty_ParameterInfo: /* 4 */
5134 result = kAudioUnitErr_InvalidProperty;
5135 break; /* hosts not permitted to change Parameter Info */
5136 case kAudioUnitProperty_FastDispatch: /* 5 */
5137 result = kAudioUnitErr_InvalidProperty;
5138 break; /* hosts not permitted to set the dispatch routines */
5139 case kAudioUnitProperty_CPULoad: /* 6 */
5140
5141 OSSpinLockLock(&(My->lock_CPULoad));
5142
5143 My->CPULoad = *((Float32 *)((void *)(p->params[1])));
5144 My->ksync_normalize = (Float32) (My->krate/AudioGetHostClockFrequency());
5145 if (My->CPULoad)
5146 My->ksync_normalize = My->ksync_normalize/My->CPULoad;
5147
5148 OSSpinLockUnlock(&(My->lock_CPULoad));
5149
5150 asysn_audiounit_proplisteners_update(My, kAudioUnitProperty_CPULoad,
5151 kAudioUnitScope_Global, (AudioUnitElement) 0);
5152 break;
5153 case kAudioUnitProperty_StreamFormat: /* 8 */
5154
5155 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5156 /* reject non-native endian-ness */
5157 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5158
5159 if (ASYS_AUDIOUNIT_FLOAT32_BIGENDIAN !=
5160 (((((AudioStreamBasicDescription *)((void *)(p->params[1])))->mFormatFlags)
5161 & kAudioFormatFlagIsBigEndian) != 0))
5162 {
5163 result = kAudioUnitErr_InvalidPropertyValue;
5164 break;
5165 }
5166
5167 switch (p->params[3] /* inScope */ ) {
5168 case kAudioUnitScope_Input:
5169
5170 if (!(ASYS_AUDIOUNIT_EFFECT) ||
5171 (p->params[2] >= ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE) ||
5172 (p->params[2] < 0))
5173 {
5174 result = kAudioUnitErr_InvalidProperty;
5175 break;
5176 }
5177
5178 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5179 /* if the AU uses an input, accept if it doesn't exceed channel limit */
5180 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5181
5182 if (((AudioStreamBasicDescription *)
5183 ((void *)(p->params[1])))->mChannelsPerFrame &&
5184 (((AudioStreamBasicDescription *)
5185 ((void *)(p->params[1])))->mChannelsPerFrame
5186 <= ASYS_AUDIOUNIT_INPUT_MAXCHANNELS))
5187 {
5188 if (p->params[2] == 0)
5189 My->AudioBufferTemplate->mNumberBuffers =
5190 ((AudioStreamBasicDescription *)
5191 ((void *)(p->params[1])))->mChannelsPerFrame;
5192
5193 My->InputStreamFormat[p->params[2]].mChannelsPerFrame =
5194 ((AudioStreamBasicDescription *)
5195 ((void *)(p->params[1])))->mChannelsPerFrame;
5196 My->InputStreamFormat[p->params[2]].mSampleRate =
5197 ((AudioStreamBasicDescription *)
5198 ((void *)(p->params[1])))->mSampleRate;
5199 My->InputStreamFormat[p->params[2]].mFormatID =
5200 ((AudioStreamBasicDescription *)
5201 ((void *)(p->params[1])))->mFormatID;
5202 My->InputStreamFormat[p->params[2]].mFormatFlags =
5203 ((AudioStreamBasicDescription *)
5204 ((void *)(p->params[1])))->mFormatFlags;
5205 My->InputStreamFormat[p->params[2]].mBytesPerPacket =
5206 ((AudioStreamBasicDescription *)
5207 ((void *)(p->params[1])))->mBytesPerPacket;
5208 My->InputStreamFormat[p->params[2]].mBytesPerFrame =
5209 ((AudioStreamBasicDescription *)
5210 ((void *)(p->params[1])))->mBytesPerFrame;
5211 My->InputStreamFormat[p->params[2]].mFramesPerPacket =
5212 ((AudioStreamBasicDescription *)
5213 ((void *)(p->params[1])))->mFramesPerPacket;
5214 My->InputStreamFormat[p->params[2]].mBitsPerChannel =
5215 ((AudioStreamBasicDescription *)
5216 ((void *)(p->params[1])))->mBitsPerChannel;
5217 My->InputStreamFormat[p->params[2]].mReserved =
5218 ((AudioStreamBasicDescription *)
5219 ((void *)(p->params[1])))->mReserved;
5220 }
5221 else
5222 result = kAudioUnitErr_InvalidProperty;
5223 break;
5224 case kAudioUnitScope_Output:
5225
5226 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5227 /* if number of output channels meet our limits, accept */
5228 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5229
5230 if (((AudioStreamBasicDescription *)((void *)(p->params[1])))->mChannelsPerFrame
5231 &&
5232 (((AudioStreamBasicDescription *)((void *)(p->params[1])))->mChannelsPerFrame
5233 <= ASYS_AUDIOUNIT_OUTPUT_MAXCHANNELS))
5234 {
5235 My->OutputStreamFormat.mChannelsPerFrame =
5236 ((AudioStreamBasicDescription *)
5237 ((void *)(p->params[1])))->mChannelsPerFrame;
5238 My->OutputStreamFormat.mSampleRate =
5239 ((AudioStreamBasicDescription *)
5240 ((void *)(p->params[1])))->mSampleRate;
5241 My->OutputStreamFormat.mFormatID =
5242 ((AudioStreamBasicDescription *)
5243 ((void *)(p->params[1])))->mFormatID;
5244 My->OutputStreamFormat.mFormatFlags =
5245 ((AudioStreamBasicDescription *)
5246 ((void *)(p->params[1])))->mFormatFlags;
5247 My->OutputStreamFormat.mBytesPerPacket =
5248 ((AudioStreamBasicDescription *)
5249 ((void *)(p->params[1])))->mBytesPerPacket;
5250 My->OutputStreamFormat.mBytesPerFrame =
5251 ((AudioStreamBasicDescription *)
5252 ((void *)(p->params[1])))->mBytesPerFrame;
5253 My->OutputStreamFormat.mFramesPerPacket =
5254 ((AudioStreamBasicDescription *)
5255 ((void *)(p->params[1])))->mFramesPerPacket;
5256 My->OutputStreamFormat.mBitsPerChannel =
5257 ((AudioStreamBasicDescription *)
5258 ((void *)(p->params[1])))->mBitsPerChannel;
5259 My->OutputStreamFormat.mReserved =
5260 ((AudioStreamBasicDescription *)
5261 ((void *)(p->params[1])))->mReserved;
5262 }
5263 else
5264 result = kAudioUnitErr_InvalidPropertyValue;
5265 break;
5266 case kAudioUnitScope_Global:
5267
5268 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5269 /* if number of output channels meet our limits, accept */
5270 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5271
5272 if (((AudioStreamBasicDescription *)((void *)(p->params[1])))->mChannelsPerFrame
5273 &&
5274 (((AudioStreamBasicDescription *)((void *)(p->params[1])))->mChannelsPerFrame
5275 <= ASYS_AUDIOUNIT_OUTPUT_MAXCHANNELS))
5276 {
5277 My->OutputStreamFormat.mChannelsPerFrame =
5278 ((AudioStreamBasicDescription *)
5279 ((void *)(p->params[1])))->mChannelsPerFrame;
5280 My->OutputStreamFormat.mSampleRate =
5281 ((AudioStreamBasicDescription *)
5282 ((void *)(p->params[1])))->mSampleRate;
5283 My->OutputStreamFormat.mFormatID =
5284 ((AudioStreamBasicDescription *)
5285 ((void *)(p->params[1])))->mFormatID;
5286 My->OutputStreamFormat.mFormatFlags =
5287 ((AudioStreamBasicDescription *)
5288 ((void *)(p->params[1])))->mFormatFlags;
5289 My->OutputStreamFormat.mBytesPerPacket =
5290 ((AudioStreamBasicDescription *)
5291 ((void *)(p->params[1])))->mBytesPerPacket;
5292 My->OutputStreamFormat.mBytesPerFrame =
5293 ((AudioStreamBasicDescription *)
5294 ((void *)(p->params[1])))->mBytesPerFrame;
5295 My->OutputStreamFormat.mFramesPerPacket =
5296 ((AudioStreamBasicDescription *)
5297 ((void *)(p->params[1])))->mFramesPerPacket;
5298 My->OutputStreamFormat.mBitsPerChannel =
5299 ((AudioStreamBasicDescription *)
5300 ((void *)(p->params[1])))->mBitsPerChannel;
5301 My->OutputStreamFormat.mReserved =
5302 ((AudioStreamBasicDescription *)
5303 ((void *)(p->params[1])))->mReserved;
5304 }
5305 else
5306 {
5307 result = kAudioUnitErr_InvalidPropertyValue;
5308 break;
5309 }
5310
5311 if ((ASYS_AUDIOUNIT_EFFECT) &&
5312 (p->params[2] < ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE) ||
5313 (p->params[2] >= 0))
5314 {
5315
5316 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5317 /* if the AU uses an input, accept if it doesn't exceed channel limit */
5318 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5319
5320 if (((AudioStreamBasicDescription *)
5321 ((void *)(p->params[1])))->mChannelsPerFrame &&
5322 (((AudioStreamBasicDescription *)
5323 ((void *)(p->params[1])))->mChannelsPerFrame
5324 <= ASYS_AUDIOUNIT_INPUT_MAXCHANNELS))
5325 {
5326 if (p->params[2] == 0)
5327 My->AudioBufferTemplate->mNumberBuffers =
5328 ((AudioStreamBasicDescription *)
5329 ((void *)(p->params[1])))->mChannelsPerFrame;
5330
5331 My->InputStreamFormat[p->params[2]].mChannelsPerFrame =
5332 ((AudioStreamBasicDescription *)
5333 ((void *)(p->params[1])))->mChannelsPerFrame;
5334 My->InputStreamFormat[p->params[2]].mSampleRate =
5335 ((AudioStreamBasicDescription *)
5336 ((void *)(p->params[1])))->mSampleRate;
5337 My->InputStreamFormat[p->params[2]].mFormatID =
5338 ((AudioStreamBasicDescription *)
5339 ((void *)(p->params[1])))->mFormatID;
5340 My->InputStreamFormat[p->params[2]].mFormatFlags =
5341 ((AudioStreamBasicDescription *)
5342 ((void *)(p->params[1])))->mFormatFlags;
5343 My->InputStreamFormat[p->params[2]].mBytesPerPacket =
5344 ((AudioStreamBasicDescription *)
5345 ((void *)(p->params[1])))->mBytesPerPacket;
5346 My->InputStreamFormat[p->params[2]].mBytesPerFrame =
5347 ((AudioStreamBasicDescription *)
5348 ((void *)(p->params[1])))->mBytesPerFrame;
5349 My->InputStreamFormat[p->params[2]].mFramesPerPacket =
5350 ((AudioStreamBasicDescription *)
5351 ((void *)(p->params[1])))->mFramesPerPacket;
5352 My->InputStreamFormat[p->params[2]].mBitsPerChannel =
5353 ((AudioStreamBasicDescription *)
5354 ((void *)(p->params[1])))->mBitsPerChannel;
5355 My->InputStreamFormat[p->params[2]].mReserved =
5356 ((AudioStreamBasicDescription *)
5357 ((void *)(p->params[1])))->mReserved;
5358 }
5359 else
5360 result = kAudioUnitErr_InvalidProperty;
5361 }
5362 break;
5363 default:
5364 result = kAudioUnitErr_InvalidProperty;
5365 break;
5366 }
5367 break;
5368 case kAudioUnitProperty_SRCAlgorithm: /* 9 */
5369 My->SRCAlgorithm = *((OSType *)((void *)(p->params[1])));
5370 break;
5371 case kAudioUnitProperty_ElementCount: /* 11, also kAudioUnitProperty_BusCount */
5372 switch (p->params[3] /* inScope */ ) {
5373 case kAudioUnitScope_Input:
5374 if (*((UInt32 *)((void *)(p->params[1]))) <= ASYS_AUDIOUNIT_ELEMENT_INPUTMAX)
5375 My->InputElementCount = *((UInt32 *)((void *)(p->params[1])));
5376 else
5377 result = kAudioUnitErr_InvalidPropertyValue;
5378 break;
5379 case kAudioUnitScope_Output:
5380 if (*((UInt32 *)((void *)(p->params[1]))) <= ASYS_AUDIOUNIT_ELEMENT_OUTPUTMAX)
5381 My->OutputElementCount = *((UInt32 *)((void *)(p->params[1])));
5382 else
5383 result = kAudioUnitErr_InvalidPropertyValue;
5384 break;
5385 case kAudioUnitScope_Global:
5386 if (*((UInt32 *)((void *)(p->params[1]))) <= ASYS_AUDIOUNIT_ELEMENT_OUTPUTMAX)
5387 My->OutputElementCount = *((UInt32 *)((void *)(p->params[1])));
5388 else
5389 result = kAudioUnitErr_InvalidPropertyValue;
5390 if (ASYS_AUDIOUNIT_EFFECT)
5391 {
5392 if (*((UInt32 *)((void *)(p->params[1]))) <= ASYS_AUDIOUNIT_ELEMENT_INPUTMAX)
5393 My->InputElementCount = *((UInt32 *)((void *)(p->params[1])));
5394 else
5395 result = kAudioUnitErr_InvalidPropertyValue;
5396 }
5397 break;
5398 case kAudioUnitScope_Part:
5399 case kAudioUnitScope_Group:
5400 break;
5401 default:
5402 result = kAudioUnitErr_InvalidProperty;
5403 break;
5404 }
5405 break;
5406 case kAudioUnitProperty_Latency: /* 12 */
5407 My->Latency = *((Float64 *)((void *)(p->params[1])));
5408 asysn_audiounit_proplisteners_update(My, kAudioUnitProperty_Latency,
5409 kAudioUnitScope_Global, (AudioUnitElement) 0);
5410 break;
5411 case kAudioUnitProperty_SupportedNumChannels: /* 13 */
5412 result = kAudioUnitErr_InvalidPropertyValue;
5413 break;
5414 case kAudioUnitProperty_MaximumFramesPerSlice: /* 14 */
5415 if (*((UInt32 *)((void *)(p->params[1]))) > ASYS_AUDIOUNIT_FRAMES_PER_SLICE)
5416 result = kAudioUnitErr_InvalidPropertyValue;
5417 else
5418 {
5419 My->MaximumFramesPerSlice = *((UInt32 *)((void *)(p->params[1])));
5420 asysn_audiounit_proplisteners_update(My, kAudioUnitProperty_MaximumFramesPerSlice,
5421 kAudioUnitScope_Global, (AudioUnitElement) 0);
5422 }
5423 break;
5424 case kAudioUnitProperty_ParameterValueStrings: /* 16 */
5425 result = kAudioUnitErr_InvalidProperty;
5426 break; /* hosts not permitted to set ParameterValueStrings */
5427 case kAudioUnitProperty_TailTime: /* 20 */
5428 My->TailTime = *((Float64 *)((void *)(p->params[1])));
5429 asysn_audiounit_proplisteners_update(My, kAudioUnitProperty_TailTime,
5430 kAudioUnitScope_Global, (AudioUnitElement) 0);
5431 break;
5432 case kAudioUnitProperty_BypassEffect: /* 21 */
5433 My->BypassEffect = *((UInt32 *)((void *)(p->params[1])));
5434 break;
5435 case kAudioUnitProperty_LastRenderError: /* 22 */
5436 My->LastRenderError = *((OSStatus *)((void *)(p->params[1])));
5437 break;
5438 case kAudioUnitProperty_SetRenderCallback: /* 23 */
5439 if ((p->params[2] >= ASYS_AUDIOUNIT_ELEMENT_ARRAYSIZE) ||
5440 (p->params[2] < 0))
5441 {
5442 result = kAudioUnitErr_InvalidProperty;
5443 break;
5444 }
5445 OSSpinLockLock(&(My->lock_sampledelivery));
5446 memcpy(&(My->SetRenderCallback[p->params[2]]),
5447 (AURenderCallbackStruct *)(p->params[1]),
5448 sizeof(AURenderCallbackStruct));
5449 OSSpinLockUnlock(&(My->lock_sampledelivery));
5450 break;
5451 case kAudioUnitProperty_FactoryPresets: /* 24 */
5452 result = kAudioUnitErr_InvalidProperty;
5453 break; /* hosts not permitted to change Factory Presets */
5454 case kAudioUnitProperty_RenderQuality: /* 26 */
5455 My->RenderQuality = *((UInt32 *)((void *)(p->params[1])));
5456 asysn_audiounit_proplisteners_update(My, kAudioUnitProperty_RenderQuality,
5457 kAudioUnitScope_Global, (AudioUnitElement) 0);
5458 break;
5459 case kAudioUnitProperty_InPlaceProcessing: /* 29 */
5460 if (*((UInt32 *)((void *)(p->params[1]))) != ASYS_AUDIOUNIT_INPLACE_PROCESSING)
5461 result = kAudioUnitErr_InvalidPropertyValue;
5462 break;
5463 case kAudioUnitProperty_PresentPreset: /* 36 */
5464 OSSpinLockLock(&(My->lock_PresentPreset));
5465 CFRelease(My->PresentPreset.presetName);
5466 My->PresentPreset.presetNumber = ((AUPreset *)(p->params[1]))->presetNumber;
5467 My->PresentPreset.presetName = ((AUPreset *)(p->params[1]))->presetName;
5468 CFRetain(My->PresentPreset.presetName);
5469 OSSpinLockUnlock(&(My->lock_PresentPreset));
5470 asysn_audiounit_presentproperty_setfactory(My);
5471 asysn_audiounit_proplisteners_update(My, kAudioUnitProperty_PresentPreset,
5472 kAudioUnitScope_Global, (AudioUnitElement) 0);
5473 break;
5474 case kAudioUnitProperty_OfflineRender: /* 37 */
5475 My->OfflineRender = *((UInt32 *)((void *)(p->params[1])));
5476 break;
5477 case kAudioUnitProperty_PresentationLatency: /* 40 */
5478 My->PresentationLatency = *((Float64 *)((void *)(p->params[1])));
5479 break;
5480 case kMusicDeviceProperty_InstrumentCount: /* 1000 */
5481 if (ASYS_AUDIOUNIT_EFFECT)
5482 result = kAudioUnitErr_InvalidPropertyValue;
5483 else
5484 if (*((UInt32 *)((void *)(p->params[1]))) != ASYS_AUDIOUNIT_INSTRUMENT_COUNT)
5485 result = kAudioUnitErr_InvalidPropertyValue;
5486 break;
5487 case kMusicDeviceProperty_StreamFromDisk: /* 1011 */
5488 My->StreamFromDisk = *((UInt32 *)((void *)(p->params[1])));
5489 asysn_audiounit_proplisteners_update(My, kMusicDeviceProperty_StreamFromDisk,
5490 kAudioUnitScope_Global, (AudioUnitElement) 0);
5491 break;
5492 default: /* should never happen */
5493 result = kAudioUnitErr_InvalidProperty;
5494 break;
5495 }
5496
5497 return result;
5498 }
5499
5500 /**********************************************************/
5501 /* Selector: Render */
5502 /* */
5503 /* params[0]: AudioBufferList * ioData; */
5504 /* params[1]: UInt32 inNumberFrames; */
5505 /* params[2]: UInt32 inOutputBusNumber; */
5506 /* params[3]: const AudioTimeStamp * inTimeStamp; */
5507 /* params[4]: AudioUnitRenderActionFlags * ioActionFlags; */
5508 /* */
5509 /**********************************************************/
5510
asysn_audiounit_kAudioUnitRenderSelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)5511 ComponentResult asysn_audiounit_kAudioUnitRenderSelect(ComponentParameters * p,
5512 asysn_audiounit_InstanceState * My)
5513 {
5514 return (asysn_audiounit_MyRenderer((void *) My,
5515 (AudioUnitRenderActionFlags *)(p->params[4]),
5516 (const AudioTimeStamp *)(p->params[3]),
5517 (UInt32)(p->params[2]), (UInt32)(p->params[1]),
5518 (AudioBufferList *)(p->params[0])));
5519 }
5520
5521 /*******************/
5522 /* Selector: Reset */
5523 /* */
5524 /*******************/
5525
asysn_audiounit_kAudioUnitResetSelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)5526 ComponentResult asysn_audiounit_kAudioUnitResetSelect(ComponentParameters * p,
5527 asysn_audiounit_InstanceState * My)
5528 {
5529
5530 #if (ASYS_AUDIOUNIT_RESET_TYPE == ASYS_AUDIOUNIT_ACTIVE_RESET)
5531 asysn_audiounit_kAudioUnitUninitializeSelect(p, My);
5532 asysn_audiounit_kAudioUnitInitializeSelect(p, My);
5533 #endif
5534
5535 return noErr;
5536 }
5537
5538 /*****************************************************/
5539 /* Selector: Add Property Listener */
5540 /* */
5541 /* params[0]: void * inProcRefCon; */
5542 /* params[1]: AudioUnitPropertyListenerProc inProc; */
5543 /* params[2]: AudioUnitPropertyID inID; */
5544 /* */
5545 /* The caller passes in a function inProc to call */
5546 /* the AU changes the property, and an object */
5547 /* inProcRefCon to pass to the function. */
5548 /*****************************************************/
5549
asysn_audiounit_kAudioUnitAddPropertyListenerSelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)5550 ComponentResult asysn_audiounit_kAudioUnitAddPropertyListenerSelect(
5551 ComponentParameters * p,
5552 asysn_audiounit_InstanceState * My)
5553 {
5554 asysn_audiounit_proplisten * lp;
5555 AudioUnitPropertyListenerProc lproc;
5556 void * lrefcon;
5557 int idx, found, msize;
5558
5559 if ((idx = asysn_audiounit_proplisteners_index(p->params[2])) < 0)
5560 return noErr;
5561
5562 lrefcon = (void *)(p->params[0]);
5563 lproc = (AudioUnitPropertyListenerProc)(p->params[1]);
5564
5565 if (!lproc)
5566 return noErr;
5567
5568 found = 0;
5569
5570 OSSpinLockLock(&(My->lock_proplisteners));
5571
5572 for (lp = My->proplisteners[idx]; lp != NULL; lp = lp->next)
5573 if ((lp->lrefcon == lrefcon) && (lp->lproc == lproc))
5574 {
5575 found = 1;
5576 break;
5577 }
5578
5579 if (!found)
5580 {
5581 msize = sizeof(asysn_audiounit_proplisten);
5582 if (lp = malloc(msize))
5583 {
5584 asysn_audiounit_memstatus(lp, msize, MADV_WILLNEED);
5585 lp->lproc = lproc;
5586 lp->lrefcon = lrefcon;
5587 lp->next = My->proplisteners[idx];
5588 My->proplisteners[idx] = lp;
5589 }
5590 }
5591
5592 OSSpinLockUnlock(&(My->lock_proplisteners));
5593
5594 /* end of critical section */
5595
5596 return noErr;
5597 }
5598
5599 /*****************************************************/
5600 /* Selector: Remove Property Listener */
5601 /* */
5602 /* params[0]: AudioUnitPropertyListenerProc inProc; */
5603 /* params[1]: AudioUnitPropertyID inID; */
5604 /* */
5605 /* Instructs the AudioUnit to stop calling the */
5606 /* inProc for the specified property inID. */
5607 /*****************************************************/
5608
asysn_audiounit_kAudioUnitRemovePropertyListenerSelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)5609 ComponentResult asysn_audiounit_kAudioUnitRemovePropertyListenerSelect(
5610 ComponentParameters * p,
5611 asysn_audiounit_InstanceState * My)
5612 {
5613 asysn_audiounit_proplisten * lp, * remove, ** trailer;
5614 AudioUnitPropertyListenerProc lproc;
5615 int idx, msize;
5616
5617 if ((idx = asysn_audiounit_proplisteners_index(p->params[1])) < 0)
5618 return noErr;
5619
5620 lproc = (AudioUnitPropertyListenerProc)(p->params[0]);
5621
5622 OSSpinLockLock(&(My->lock_proplisteners));
5623
5624 lp = My->proplisteners[idx];
5625 trailer = &(My->proplisteners[idx]);
5626
5627 while (lp != NULL)
5628 if (lp->lproc == lproc)
5629 {
5630 remove = lp;
5631 lp = (*trailer) = lp->next;
5632 msize = sizeof(asysn_audiounit_proplisten);
5633 asysn_audiounit_memstatus(remove, msize, MADV_FREE);
5634 free(remove);
5635 }
5636 else
5637 {
5638 trailer = &(lp->next);
5639 lp = lp->next;
5640 }
5641
5642 OSSpinLockUnlock(&(My->lock_proplisteners));
5643
5644 return noErr;
5645 }
5646
5647 /*****************************************************/
5648 /* Selector: Remove Property Listener With User Data */
5649 /* */
5650 /* params[0]: void * inProcRefCon; */
5651 /* params[1]: AudioUnitPropertyListenerProc inProc; */
5652 /* params[2]: AudioUnitPropertyID inID; */
5653 /* */
5654 /* Instructs the AudioUnit to stop calling the */
5655 /* inProc for the specified property inID. */
5656 /*****************************************************/
5657
asysn_audiounit_kAudioUnitRemovePropertyListenerWithUserDataSelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)5658 ComponentResult asysn_audiounit_kAudioUnitRemovePropertyListenerWithUserDataSelect(
5659 ComponentParameters * p,
5660 asysn_audiounit_InstanceState * My)
5661 {
5662 asysn_audiounit_proplisten * lp, * remove, ** trailer;
5663 AudioUnitPropertyListenerProc lproc;
5664 void * lrefcon;
5665 int idx, msize;
5666
5667 if ((idx = asysn_audiounit_proplisteners_index(p->params[2])) < 0)
5668 return noErr;
5669
5670 lrefcon = (void *)(p->params[0]);
5671 lproc = (AudioUnitPropertyListenerProc)(p->params[1]);
5672
5673 OSSpinLockLock(&(My->lock_proplisteners));
5674
5675 lp = My->proplisteners[idx];
5676 trailer = &(My->proplisteners[idx]);
5677
5678 while (lp != NULL)
5679 if ((lp->lproc == lproc) && (lp->lrefcon == lrefcon))
5680 {
5681 remove = lp;
5682 lp = (*trailer) = lp->next;
5683 msize = sizeof(asysn_audiounit_proplisten);
5684 asysn_audiounit_memstatus(remove, msize, MADV_FREE);
5685 free(remove);
5686 }
5687 else
5688 {
5689 trailer = &(lp->next);
5690 lp = lp->next;
5691 }
5692
5693 OSSpinLockUnlock(&(My->lock_proplisteners));
5694
5695 return noErr;
5696 }
5697
5698 /*************************************/
5699 /* Selector: Add Render Notify */
5700 /* */
5701 /* params[0]: void * inProcRefCon; */
5702 /* params[1]: ProcPtr inProc; */
5703 /* */
5704 /*************************************/
5705
asysn_audiounit_kAudioUnitAddRenderNotifySelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)5706 ComponentResult asysn_audiounit_kAudioUnitAddRenderNotifySelect
5707 (ComponentParameters * p, asysn_audiounit_InstanceState * My)
5708 {
5709 asysn_audiounit_rendernotify * notify;
5710 int msize;
5711
5712 msize = sizeof(asysn_audiounit_rendernotify);
5713 if (!(notify = malloc(msize)))
5714 return noErr;
5715 asysn_audiounit_memstatus(notify, msize, MADV_WILLNEED);
5716
5717 notify->nproc = (AURenderCallback)(p->params[1]);
5718 notify->nrefcon = (void *)(p->params[0]);
5719
5720 OSSpinLockLock(&(My->lock_rendernotify));
5721
5722 notify->next = My->rendernotify;
5723 My->rendernotify = notify;
5724
5725 OSSpinLockUnlock(&(My->lock_rendernotify));
5726
5727 return noErr;
5728 }
5729
5730 /*************************************/
5731 /* Selector: Remove Render Notify */
5732 /* */
5733 /* params[0]: void * inProcRefCon; */
5734 /* params[1]: ProcPtr inProc; */
5735 /* */
5736 /*************************************/
5737
asysn_audiounit_kAudioUnitRemoveRenderNotifySelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)5738 ComponentResult asysn_audiounit_kAudioUnitRemoveRenderNotifySelect
5739 (ComponentParameters * p, asysn_audiounit_InstanceState * My)
5740 {
5741 asysn_audiounit_rendernotify * notify, * remove, ** trailer;
5742 int msize;
5743
5744 OSSpinLockLock(&(My->lock_rendernotify));
5745
5746 notify = My->rendernotify;
5747 trailer = &(My->rendernotify);
5748
5749 while (notify != NULL)
5750 if ((notify->nproc == (AURenderCallback)(p->params[1])) &&
5751 (notify->nrefcon == (void *)(p->params[0])))
5752 {
5753 remove = notify;
5754 notify = (*trailer) = notify->next;
5755
5756 msize = sizeof(asysn_audiounit_rendernotify);
5757 asysn_audiounit_memstatus(remove, msize, MADV_FREE);
5758 free(remove);
5759 }
5760 else
5761 {
5762 trailer = &(notify->next);
5763 notify = notify->next;
5764 }
5765
5766 OSSpinLockUnlock(&(My->lock_rendernotify));
5767
5768 return noErr;
5769 }
5770
5771
5772 /******************************************/
5773 /* Selector: GetParameterSelect */
5774 /* */
5775 /* params[0]: Float32 * outValue */
5776 /* params[1]: AudioUnitElement inElement */
5777 /* params[2]: AudioUnitScope inScope */
5778 /* params[3]: AudioUnitParameterID inID */
5779 /* */
5780 /******************************************/
5781
asysn_audiounit_kAudioUnitGetParameterSelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)5782 ComponentResult asysn_audiounit_kAudioUnitGetParameterSelect
5783 (ComponentParameters * p, asysn_audiounit_InstanceState * My)
5784 {
5785 if (((AudioUnitScope)(p->params[2])) != kAudioUnitScope_Global) /* inScope */
5786 return kAudioUnitErr_InvalidScope;
5787
5788 return asysn_audiounit_getSASLevent(((AudioUnitParameterID)(p->params[3])) /* inID */,
5789 ((Float32 *)(p->params[0])) /* outValue */, My);
5790 }
5791
5792
5793 /*********************************************/
5794 /* Selector: SetParameterSelect */
5795 /* */
5796 /* params[0]: UInt32 inBufferOffsetInFrames */
5797 /* params[1]: Float32 inValue */
5798 /* params[2]: AudioUnitElement inElement */
5799 /* params[3]: AudioUnitScope inScope; */
5800 /* params[4]: AudioUnitParameterID inID; */
5801 /* */
5802 /*********************************************/
5803
asysn_audiounit_kAudioUnitSetParameterSelect(ComponentParameters * p,asysn_audiounit_InstanceState * My)5804 ComponentResult asysn_audiounit_kAudioUnitSetParameterSelect
5805 (ComponentParameters * p, asysn_audiounit_InstanceState * My)
5806 {
5807 asysn_audiounit_SASLevent SASLevent;
5808 int result;
5809 Float32 inValue;
5810 int inID;
5811
5812 if (((AudioUnitScope)(p->params[3])) != kAudioUnitScope_Global) /* inScope */
5813 return kAudioUnitErr_InvalidScope;
5814
5815 inID = (AudioUnitParameterID)(p->params[4]);
5816
5817 if ((inID < 0) || (inID >= My->num_saolparams)) /* range-check ID */
5818 return kAudioUnitErr_InvalidParameter;
5819
5820 inValue = *((Float32 *)((unsigned char *)(&(p->params[1]))));
5821
5822 if (inValue > My->parameterinfo[inID].maxValue)
5823 inValue = My->parameterinfo[inID].maxValue;
5824
5825 if (inValue < My->parameterinfo[inID].minValue)
5826 inValue = My->parameterinfo[inID].minValue;
5827
5828 SASLevent.index = inID;
5829 SASLevent.value = My->saolparam[inID].value = inValue;
5830 SASLevent.kcycleidx = (int)((UInt32)(p->params[0]));
5831
5832 return asysn_audiounit_sendSASLevent(&SASLevent, My);
5833 }
5834
5835 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5836 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5837 /* The AudioUnit Entry Function */
5838 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5839 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
5840
5841 /************************************************************/
5842 /* The function Component Manager calls to access the AU */
5843 /************************************************************/
5844
asysn_audiounit_entry(ComponentParameters * p,Handle * obj)5845 extern ComponentResult asysn_audiounit_entry(ComponentParameters * p, Handle * obj)
5846 {
5847 asysn_audiounit_MIDIevent MIDIevent;
5848 ComponentResult result;
5849
5850 if (obj == NULL)
5851 switch (p->what) {
5852 case kComponentOpenSelect:
5853 case kComponentVersionSelect:
5854 case kComponentCanDoSelect:
5855 break;
5856 default:
5857 return noErr; /* avoid race condition */
5858 }
5859
5860 switch (p->what) {
5861 case kComponentOpenSelect:
5862 result = asysn_audiounit_kComponentOpenSelect
5863 (p, (asysn_audiounit_InstanceState *) obj);
5864 break;
5865 case kComponentCloseSelect:
5866 result = asysn_audiounit_kComponentCloseSelect
5867 (p, (asysn_audiounit_InstanceState *) obj);
5868 break;
5869 case kAudioUnitInitializeSelect:
5870 result = asysn_audiounit_kAudioUnitInitializeSelect
5871 (p, (asysn_audiounit_InstanceState *) obj);
5872 break;
5873 case kAudioUnitUninitializeSelect:
5874 result = asysn_audiounit_kAudioUnitUninitializeSelect
5875 (p, (asysn_audiounit_InstanceState *) obj);
5876 break;
5877 case kAudioUnitGetPropertyInfoSelect:
5878 result = asysn_audiounit_kAudioUnitGetPropertyInfoSelect
5879 (p, (asysn_audiounit_InstanceState *) obj);
5880 break;
5881 case kAudioUnitGetPropertySelect:
5882 result = asysn_audiounit_kAudioUnitGetPropertySelect
5883 (p, (asysn_audiounit_InstanceState *) obj);
5884 break;
5885 case kAudioUnitSetPropertySelect:
5886 result = asysn_audiounit_kAudioUnitSetPropertySelect
5887 (p, (asysn_audiounit_InstanceState *) obj);
5888 break;
5889 case kAudioUnitRenderSelect:
5890 result = asysn_audiounit_kAudioUnitRenderSelect
5891 (p, (asysn_audiounit_InstanceState *) obj);
5892 break;
5893 case kAudioUnitResetSelect:
5894 result = asysn_audiounit_kAudioUnitResetSelect
5895 (p, (asysn_audiounit_InstanceState *) obj);
5896 break;
5897 case kAudioUnitAddPropertyListenerSelect:
5898 result = asysn_audiounit_kAudioUnitAddPropertyListenerSelect
5899 (p, (asysn_audiounit_InstanceState *) obj);
5900 break;
5901 case kAudioUnitRemovePropertyListenerSelect:
5902 result = asysn_audiounit_kAudioUnitRemovePropertyListenerSelect
5903 (p, (asysn_audiounit_InstanceState *) obj);
5904 break;
5905 case kAudioUnitRemovePropertyListenerWithUserDataSelect:
5906 result = asysn_audiounit_kAudioUnitRemovePropertyListenerWithUserDataSelect
5907 (p, (asysn_audiounit_InstanceState *) obj);
5908 break;
5909 case kAudioUnitAddRenderNotifySelect:
5910 result = asysn_audiounit_kAudioUnitAddRenderNotifySelect
5911 (p, (asysn_audiounit_InstanceState *) obj);
5912 break;
5913 case kAudioUnitRemoveRenderNotifySelect:
5914 result = asysn_audiounit_kAudioUnitRemoveRenderNotifySelect
5915 (p, (asysn_audiounit_InstanceState *) obj);
5916 break;
5917 case kAudioUnitGetParameterSelect:
5918 result = asysn_audiounit_kAudioUnitGetParameterSelect
5919 (p, (asysn_audiounit_InstanceState *) obj);
5920 break;
5921 case kAudioUnitSetParameterSelect:
5922 result = asysn_audiounit_kAudioUnitSetParameterSelect
5923 (p, (asysn_audiounit_InstanceState *) obj);
5924 break;
5925 case kAudioUnitScheduleParametersSelect:
5926 result = noErr;
5927 break;
5928 case kMusicDeviceMIDIEventSelect:
5929 if (ASYS_AUDIOUNIT_MIDISUPPORT)
5930 {
5931 MIDIevent.cmd = (unsigned char)((UInt32)(p->params[3]));
5932 MIDIevent.d0 = (unsigned char)((UInt32)(p->params[2]));
5933 MIDIevent.d1 = (unsigned char)((UInt32)(p->params[1]));
5934 MIDIevent.flags = ASYS_AUDIOUNIT_MIDIFLAGS_WAITING;
5935 MIDIevent.kcycleidx = (int)((UInt32)(p->params[0]));
5936 result = asysn_audiounit_sendMIDIevent
5937 (&MIDIevent, (asysn_audiounit_InstanceState *) obj);
5938 }
5939 else
5940 result = badComponentSelector;
5941 break;
5942 case kMusicDeviceSysExSelect:
5943 case kMusicDevicePrepareInstrumentSelect:
5944 case kMusicDeviceReleaseInstrumentSelect:
5945 case kMusicDeviceStartNoteSelect:
5946 case kMusicDeviceStopNoteSelect:
5947 default:
5948 result = badComponentSelector;
5949 break;
5950 case kComponentVersionSelect:
5951 result = 0x00010000; /* major version 1, minor version 0 */
5952 break;
5953 case kComponentCanDoSelect:
5954 switch ((int)((SInt16)(p->params[0]))) {
5955 case kComponentOpenSelect:
5956 case kComponentCloseSelect:
5957 case kAudioUnitInitializeSelect:
5958 case kAudioUnitUninitializeSelect:
5959 case kAudioUnitGetPropertyInfoSelect:
5960 case kAudioUnitGetPropertySelect:
5961 case kAudioUnitSetPropertySelect:
5962 case kAudioUnitRenderSelect:
5963 case kAudioUnitResetSelect:
5964 case kAudioUnitAddPropertyListenerSelect:
5965 case kAudioUnitRemovePropertyListenerSelect:
5966 case kAudioUnitRemovePropertyListenerWithUserDataSelect:
5967 case kAudioUnitAddRenderNotifySelect:
5968 case kAudioUnitRemoveRenderNotifySelect:
5969 case kAudioUnitGetParameterSelect:
5970 case kAudioUnitSetParameterSelect:
5971 result = 1;
5972 break;
5973 case kMusicDeviceMIDIEventSelect:
5974 result = ASYS_AUDIOUNIT_MIDISUPPORT;
5975 default:
5976 result = 0;
5977 break;
5978 }
5979 break;
5980 }
5981
5982 switch (p->what) {
5983 case kAudioUnitRenderSelect:
5984 ASYS_AUDIOUNIT_WIRETAP_R(p, result);
5985 break;
5986 case kMusicDeviceMIDIEventSelect:
5987 ASYS_AUDIOUNIT_WIRETAP_M(p, result);
5988 break;
5989 default:
5990 ASYS_AUDIOUNIT_WIRETAP(p, result);
5991 break;
5992 }
5993
5994 return result;
5995 }
5996
5997 /****************************************************************/
5998 /* End of Part Three (The AudioUnit Component) */
5999 /****************************************************************/
6000
6001 /****************************************************************/
6002 /* End of Apple AudioUnit audio driver for sfront */
6003 /****************************************************************/
6004 /****************************************************************/
6005
6006