1 /*
2  * Copyright 1993 Network Computing Devices, Inc.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name Network Computing Devices, Inc. not be
9  * used in advertising or publicity pertaining to distribution of this
10  * software without specific, written prior permission.
11  *
12  * THIS SOFTWARE IS PROVIDED `AS-IS'.  NETWORK COMPUTING DEVICES, INC.,
13  * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
14  * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
15  * PARTICULAR PURPOSE, OR NONINFRINGEMENT.  IN NO EVENT SHALL NETWORK
16  * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
17  * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
18  * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
19  * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  *
22  * $NCDId: @(#)au.h,v 1.22 1995/11/29 00:50:13 greg Exp $
23  * $Id: au.h 166 2006-07-26 23:56:34Z jon $
24  */
25 
26 #ifndef _AU_H_
27 #define _AU_H_
28 
29 /* This will define the appropriate *_SERVER */
30 #include "auservertype.h"
31 
32 /* JET - last one wins... */
33 
34 #if defined(HPUX_SERVER)        /* hpux */
35 # include "../dda/hpux/auhpux.h"
36 #elif defined(SUN_SERVER)       /* sun */
37 # include "../dda/sun/ausun.h"
38 #elif defined(SGI_SERVER)       /* SGI */
39 # include "../dda/sgi/ausgi.h"
40 #elif defined(VOXWARE_SERVER)   /* voxware */
41 # include "../dda/voxware/auvoxware.h"
42 #endif
43 
44 typedef void *AuPointer;
45 
46 #define auMaxTracks                     32
47 
48 #define AuElementNotifyKindSpecial      0xff
49 
50 #if (defined(SYSV) && !defined(ISC)) || defined(SVR4)
51 #ifndef bcopy
52 #define bcopy(a,b,c)                    memmove((b),(a),(c))
53 #endif
54 
55 #ifndef bzero
56 #define bzero(a,b)                      memset((a),0,(b))
57 #endif
58 #endif /* SYSV && !ISC || SVR4 */
59 
60 #define aumin(x, y)                     ((x) < (y) ? (x) : (y))
61 #define aumax(x, y)                     ((x) > (y) ? (x) : (y))
62 #define aucopy(_src, _dst, _size)       bcopy(_src, _dst, _size)
63 #define auset(_dst, _val, _size)        memset(_dst, _val, _size)
64 #define auclr(_dst, _size)              bzero(_dst, _size)
65 #define aualloc                         auProtectedAlloc
66 #define aufree                          auProtectedFree
67 #define aurealloc                       auProtectedRealloc
68 
69 AuPointer auProtectedAlloc(), auProtectedRealloc(), aucalloc();
70 void auProtectedFree();
71 
72 #define NUMARRAY(x)                     (sizeof(x) / sizeof((x)[0]))
73 #define PAD4(x)                         (((x) + 3) & ~3)
74 
75 #define NotAPhysicalDevice              0
76 #define PhysicalOutputMono              (1L << 0)
77 #define PhysicalOutputLeft              (1L << 1)
78 #define PhysicalOutputRight             (1L << 2)
79 #define PhysicalOutputStereo            (1L << 3)
80 #define AllPhysicalOutputs             ((1L << 4) - 1)
81 
82 #define PhysicalInputMono               (1L << 4)
83 #define PhysicalInputStereo             (1L << 5)
84 #define AllPhysicalInputs             (((1L << 6) - 1) ^ AllPhysicalOutputs)
85 
86 #define PhysicalFeedbackMono           (1L << 6)
87 #define PhysicalFeedbackStereo         (1L << 7)
88 #define AllPhysicalFeedbacks         (((1L << 8) - 1) ^ AllPhysicalOutputs \
89                                                       ^ AllPhysicalInputs)
90 
91 
92 #define AuValidState(s)                                                        \
93     ((s) == AuStateStop || (s) == AuStatePause || (s) == AuStateStart)
94 
95 #define AuValidTriggerState(s)                                                 \
96     ((s) == AuStateAny || AuValidState(s))
97 
98 #define AuValidTriggerReason(r)                                                \
99     (((r) == AuReasonAny) ||                                                   \
100      ((r) == AuReasonUser) ||                                                  \
101      ((r) == AuReasonUnderrun) ||                                              \
102      ((r) == AuReasonOverrun) ||                                               \
103      ((r) == AuReasonEOF) ||                                                   \
104      ((r) == AuReasonWatermark) ||                                             \
105      ((r) == AuReasonHardware))
106 
107 #define AddToLinkedList(head, item)                                            \
108 {                                                                              \
109     (item)->prev = NULL;                                                       \
110     (item)->next = (head);                                                     \
111     if (head)                                                                  \
112         (head)->prev = (item);                                                 \
113     head = (item);                                                             \
114 }
115 
116 #define RemoveFromLinkedList(head, item)                                       \
117 {                                                                              \
118     if ((item)->next)                                                          \
119         (item)->next->prev = (item)->prev;                                     \
120                                                                                \
121     if ((item)->prev)                                                          \
122         (item)->prev->next = (item)->next;                                     \
123     else                                                                       \
124         (head) = (item)->next;                                                 \
125 }
126 
127 
128 #define AU_ERROR(e, v)                                                         \
129 {                                                                              \
130     client->errorValue = (v);                                                  \
131     return (e);                                                                \
132 }
133 
134 #define sizeofFormat(f)         auBytesPerSample[f]
135 
136 typedef struct {
137     AuUint8 type;               /* AuStringLatin1, ... */
138     AuUint32 len;               /* length in bytes */
139     AuInt8 *string;             /* the data */
140 } StringRec, *StringPtr;
141 
142 typedef struct _ComponentRec {
143     /* external common stuff */
144     AuID id;                    /* who am I? */
145     AuUint32 numSamples,        /* for ports and buckets */
146         changableMask,          /* what can be changed */
147         valueMask;              /* what is present */
148     AuUint8 kind,               /* what type of component is
149                                  * it */
150         use,                    /* importable, exportable,
151                                  * etc. */
152         access,                 /* who can access */
153         format,                 /* data format */
154         numTracks;              /* 1 for mono, 2 for stereo,
155                                  * etc. */
156     StringRec description;      /* a text description */
157 
158     /* external physical stuff */
159     AuUint32 minSampleRate, maxSampleRate, location;    /* mask of bits */
160     AuFixedPoint gain;          /* input gain (16.16%) */
161     AuUint8 lineMode,           /* mic/line */
162         numChildren;            /* number of subcomponents,
163                                  * if any */
164     AuID *children;             /* subcomponents, if any */
165     AuInt8 *childSwap;          /* swap space for children */
166 
167     /* external port stuff */
168     AuUint32 lowWaterMark, highWaterMark;
169 
170 #ifdef notyet
171     /* external virtual stuff */
172     AuUint32 station;           /* for radios */
173 #endif                          /* notyet */
174 
175     /* internal common stuff */
176     AuUint32 refCnt,            /* reference count */
177         readTag, sampleRate, physicalDeviceMask, minibufSize,   /* mini-buffer size */
178         bytesPerSample, minibufSamples, dataSize;       /* size of data in bytes */
179     AuUint8 *minibuf,           /* chunk storage */
180        *data,                   /* start of data */
181        *dataEnd;                /* end of data */
182 
183     /* internal port stuff */
184     AuUint8 *write,             /* write pointer */
185        *read;                   /* read pointer */
186     AuUint32 incoming,          /* how much data are we
187                                  * expecting */
188         outgoing,               /* how much data have we sent */
189         currentSize;            /* how much data is in the
190                                  * port */
191     AuBool discard,             /* true if we're to clear a
192                                  * port when starting it */
193         eof,                    /* true if we've received an
194                                  * EOF on this port */
195         processed;              /* used during processing */
196 
197     /* internal bucket stuff */
198     AuBool destroyed,           /* true if the bucket has
199                                  * been destroyed */
200         list;                   /* used in ListBuckets */
201 
202     /* internal wave form stuff */
203     AuUint32 frequency, waveSamples;
204 
205     struct _ComponentRec *prev, /* linked list pointers */
206        *next;
207 } ComponentRec, *ComponentPtr;
208 
209 
210 typedef struct _FlowRec FlowRec, *FlowPtr;
211 
212 typedef struct {
213     FlowPtr flow;
214     AuUint8 triggerState,
215             triggerPrevState, triggerReason, action, elementNum, newState;
216 } ActionRec, *ActionPtr;
217 
218 typedef struct {
219     AuPointer client;           /* client that owns this
220                                  * element */
221     AuUint32 state,
222             prevState,
223             elementNum,
224             numBytes,
225             refCnt,
226             varLen,
227             numActions,
228             currentSample, nextSample, minibufSamples, minibufBytes;
229     FlowPtr flow;
230     AuBool compiled,            /* true if we've compiled
231                                  * this element */
232         setup,                  /* true if we've setup this
233                                  * element */
234         countSamples, stateChange,      /* true if there's been a
235                                          * state change */
236         isComponent,            /* true if this is a
237                                  * component element */
238         parmsChanged;           /* true if the element
239                                  * parameters changed */
240     AuUint8 *minibuf;           /* pointer to chunk storage */
241     auElement *raw;             /* the raw element */
242     ActionPtr actions;          /* the actions */
243     ComponentPtr component;
244 
245     /* instance data for buffers */
246     AuUint8 *read,              /* read pointer */
247        *write;                  /* write pointer */
248     AuUint32 sampleRate, readTag;
249 
250     /* stuff used in processing the flow */
251     void (*toNativeFormat) (), (*fromNativeFormat) ();
252     AuInt32 minibufChunk;       /* number of bytes to read to
253                                  * fill up minibuffer after
254                                  * format conversion */
255 } FlowElementRec, *FlowElementPtr;
256 
257 typedef struct {
258     ComponentPtr component;     /* the input component */
259     FlowElementPtr flowEl;      /* the flow element */
260     AuFixedPoint multiplyConstant,      /* (16.16) */
261         addConstant;            /* (16.16) */
262     AuUint8 numTracks, inTrack[auMaxTracks], outTrack[auMaxTracks];
263         AuUint32(*rateConvert) (), *preadTag;
264         AuBool(*readInput) ();
265     void *devPrivate;           /* device specific data */
266     void (*freeDevPrivate) ();  /* free function for device
267                                  * specific data */
268 } CompiledFlowInputRec, *CompiledFlowInputPtr;
269 
270 typedef struct {
271     ComponentPtr component;     /* the output component */
272     FlowElementPtr flowEl;      /* the flow element */
273     AuUint32 numInputs,         /* how many inputs */
274         firstInput;             /* head of the input chain */
275     CompiledFlowInputPtr inputs;        /* the inputs */
276         AuUint32(*rateConvert) ();
277         AuBool(*writeOutput) ();
278     void *devPrivate;           /* device specific data */
279     void (*freeDevPrivate) ();  /* free function for device
280                                  * specific data */
281 } CompiledFlowOutputRec, *CompiledFlowOutputPtr;
282 
283 typedef struct {
284     AuUint32 numOutputs,        /* how many outputs */
285         physicalDeviceMask;     /* mask of physical devices
286                                  * used */
287     AuBool freeComponents;
288     CompiledFlowOutputPtr outputs;      /* the outputs */
289     void (*accumulateOutput) ();
290     void *devPrivate;           /* device specific data */
291     void (*freeDevPrivate) ();  /* free function for device
292                                  * specific data */
293 } CompiledFlowRec, *CompiledFlowPtr;
294 
295 struct _FlowRec {
296     AuFlowID flowId;            /* flow id */
297     AuUint32 numElements,       /* how many elements */
298         count,                  /* used in trivial flows */
299         state,                  /* current state */
300         varLen,                 /* total size of variable
301                                  * data */
302         pendingState;           /* new state */
303     AuBool clocked,             /* true if flow is clocked */
304         trivial,                /* true if flow is just an
305                                  * import or export and a
306                                  * bucket */
307         needsRecompile;         /* true if flow needs to be
308                                  * recompiled */
309     CompiledFlowRec compiled;   /* compiled flow */
310     FlowElementPtr elements;    /* flow elements */
311     auElement *raw;             /* the raw elements off the
312                                  * wire */
313     struct _FlowRec *prev,      /* linked list pointers */
314        *next;
315 };
316 
317 AuFixedPoint AuFixedPointMultiply();
318 
319 /* configuration stuff */
320 
321 #define AU_ALLOC_DEVICE(d, numTracks, numChildren)                            \
322 {                                                                             \
323     int extra = (numChildren) * sizeof(AuID) * 2;                             \
324                                                                               \
325     if (!((d) = (ComponentPtr) aualloc(PAD4(sizeof(ComponentRec)) + (extra))))\
326         return AuBadAlloc;                                                    \
327                                                                               \
328     /* pebl: specific initalize minibufSamples to zero (needed!) */           \
329     bzero((d),PAD4(sizeof(ComponentRec)) + (extra));                          \
330 }
331 
332 #define AU_ADD_DEVICE(d)                                                      \
333 {                                                                             \
334     d->bytesPerSample = d->numTracks * sizeofFormat(d->format);               \
335     d->refCnt = 0;                                                            \
336                                                                               \
337     AddToLinkedList(auDevices, d);                                            \
338                                                                               \
339     if (!AddResource(d->id, auComponentType, d))                              \
340         return AuBadAlloc;                                                    \
341                                                                               \
342     auNumServerDevices++;                                                     \
343     *auServerDeviceListSize += sizeof(auDeviceAttributes) +                   \
344         PAD4(d->description.len) + PAD4(d->numChildren * sizeof(AuDeviceID)); \
345 }
346 
347 #define AU_ALLOC_BUCKET(b)                                                    \
348 {                                                                             \
349     if (!((b) = (ComponentPtr) aualloc(sizeof(ComponentRec))))                \
350         return AuBadAlloc;                                                    \
351 }
352 
353 #define AU_ADD_BUCKET(b)                                                      \
354 {                                                                             \
355     b->refCnt = 0;                                                            \
356                                                                               \
357     AddToLinkedList(auBuckets, b);                                            \
358                                                                               \
359     if (!AddResource(b->id, auComponentType, b))                              \
360         return AuBadAlloc;                                                    \
361                                                                               \
362     auNumServerBuckets++;                                                     \
363     *auServerBucketListSize += sizeof(auBucketAttributes) +                   \
364         PAD4(b->description.len);                                             \
365 }
366 
367 enum _auCallbackTypes {
368     /* required */
369     AuCreateServerComponentsCB,
370     AuSetPhysicalOutputGainCB,
371     AuGetPhysicalOutputGainCB,
372     AuSetPhysicalInputGainAndLineModeCB,
373     AuEnableProcessFlowCB,
374     AuDisableProcessFlowCB,
375     AuReadPhysicalInputsCB,
376     AuSetWritePhysicalOutputFunctionCB,
377 
378     /* optional */
379     AuSetSampleRateCB,
380     AuEventPostedCB,
381     AuSetPhysicalOutputModeCB,
382     AuGetPhysicalOutputModeCB,
383     AuSetPhysicalFeedbackGainCB,
384     AuGetPhysicalFeedbackGainCB,
385     AuGetPhysicalInputGainCB,
386     AuGetPhysicalInputModeCB,
387 
388     AuMaxCB
389 };
390 
391 typedef AuUint32(*_pFunc) ();
392 
393 #ifndef _AUUTIL_C_
394 extern AuUint32 auBytesPerSample[];
395 extern
396 #endif                          /* !_AUUTIL_C_ */
397 _pFunc AuCallbacks[AuMaxCB];
398 
399 #define AuRegisterCallback(_n, _f)      AuCallbacks[_n] = (_pFunc) (_f)
400 #define CallbackExists(_n)              AuCallbacks[_n]
401 
402 #define AuCallbackIf(_n, _args)                                               \
403 {                                                                             \
404     if (CallbackExists(_n))                                                   \
405         (*AuCallbacks[_n]) _args;                                             \
406 }
407 
408 #define AuCallback(_n, _args)                                                 \
409         (*AuCallbacks[_n]) _args
410 
411 #ifndef WAKEUP_SERVER
412 #define WAKEUP_SERVER()         kill(getpid(), SIGUSR1)
413 #endif /* !WAKEUP_SERVER */
414 
415 #ifndef _AUPROCESS_C_
416 extern void AuULAW8ToNative(), AuNativeToULAW8(),
417 AuUnsigned8ToNative(), AuNativeToUnsigned8(),
418 AuSigned8ToNative(), AuNativeToSigned8(),
419 changeSign(), byteSwap(), AuNeg16LSBTo16MSB(), AuNeg16MSBto16LSB();
420 #endif /* !_AUPROCESS_C_ */
421 
422 #if (auNativeFormat == AuFormatLinearSigned16MSB)
423 #define AuSigned16MSBToNative           (void (*) ()) 0
424 #define AuNativeToSigned16MSB           (void (*) ()) 0
425 #define AuUnsigned16MSBToNative         changeSign
426 #define AuNativeToUnsigned16MSB         changeSign
427 #define AuSigned16LSBToNative           byteSwap
428 #define AuNativeToSigned16LSB           byteSwap
429 #define AuUnsigned16LSBToNative         AuNeg16LSBTo16MSB
430 #define AuNativeToUnsigned16LSB         AuNeg16MSBto16LSB
431 #endif
432 
433 #if (auNativeFormat == AuFormatLinearSigned16LSB)
434 #define AuSigned16MSBToNative           byteSwap
435 #define AuNativeToSigned16MSB           byteSwap
436 #define AuUnsigned16MSBToNative         AuNeg16MSBto16LSB
437 #define AuNativeToUnsigned16MSB         AuNeg16LSBTo16MSB
438 #define AuSigned16LSBToNative           (void (*) ()) 0
439 #define AuNativeToSigned16LSB           (void (*) ()) 0
440 #define AuUnsigned16LSBToNative         changeSign
441 #define AuNativeToUnsigned16LSB         changeSign
442 #endif
443 
444 #endif /* _AU_H_ */
445