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: @(#)GetElement.c,v 1.4 1994/03/22 22:50:00 greg Exp $
23  */
24 
25 #include "Alibint.h"
26 
27 AuElement      *
AuGetElements(AuServer * aud,AuFlowID flow,AuBool * pclocked,int * pnum_elements,AuStatus * ret_status)28 AuGetElements(
29               AuServer       *aud,
30               AuFlowID        flow,
31               AuBool         *pclocked,
32               int            *pnum_elements,
33               AuStatus       *ret_status
34               )
35 {
36     auResourceReq *req;
37     auGetElementsReply rep;
38     AuElement      *elements;
39     int             i;
40 
41     _AuLockServer();
42     _AuGetResReq(GetElements, flow, req, aud);
43 
44     (void) _AuReply(aud, (auReply *) & rep, 0, auFalse, ret_status);
45 
46     *pclocked = rep.clocked;
47     *pnum_elements = rep.num_elements;
48 
49     if (!(elements =
50 	  (AuElement *) Aucalloc(rep.num_elements, sizeof(AuElement))))
51     {
52 	_AuUnlockServer();
53 	_AuSyncHandle(aud);
54 	return NULL;
55     }
56 
57     for (i = 0; i < rep.num_elements; i++)
58     {
59 	AuElement      *el;
60 	auElement       e;
61 	AuElementActionList *actions;
62 	AuBool          bundle,
63 	                sum;
64 
65 	actions = NULL;
66 	bundle = sum = AuFalse;
67 	el = &elements[i];
68 
69 	_AuReadPad(aud, (char *) &e, SIZEOF(auElement));
70 
71 	el->type = e.type;
72 
73 	switch (el->type)
74 	{
75 	    case AuElementTypeImportClient:
76 #undef xfer
77 #define xfer(x)	el->importclient.x = e.importclient.x
78 		xfer(sample_rate);
79 		xfer(format);
80 		xfer(num_tracks);
81 		xfer(discard);
82 		xfer(max_samples);
83 		xfer(low_water_mark);
84 		xfer(actions.num_actions);
85 		actions = &el->importclient.actions;
86 		break;
87 	    case AuElementTypeImportDevice:
88 #undef xfer
89 #define xfer(x)	el->importdevice.x = e.importdevice.x
90 		xfer(sample_rate);
91 		xfer(num_samples);
92 		xfer(device);
93 		xfer(actions.num_actions);
94 		actions = &el->importdevice.actions;
95 		break;
96 	    case AuElementTypeImportBucket:
97 #undef xfer
98 #define xfer(x)	el->importbucket.x = e.importbucket.x
99 		xfer(sample_rate);
100 		xfer(num_samples);
101 		xfer(bucket);
102 		el->importbucket.parms[AuParmsImportBucketOffset] =
103 		    e.importbucket.offset;
104 		xfer(actions.num_actions);
105 		actions = &el->importbucket.actions;
106 		break;
107 	    case AuElementTypeImportWaveForm:
108 #undef xfer
109 #define xfer(x)	el->importwaveform.x = e.importwaveform.x
110 		xfer(sample_rate);
111 		xfer(wave_form);
112 		el->importwaveform.parms[AuParmsImportWaveFormFrequency] =
113 		    e.importwaveform.frequency;
114 		el->importwaveform.parms[AuParmsImportWaveFormNumSamples] =
115 		    e.importwaveform.num_samples;
116 		xfer(actions.num_actions);
117 		actions = &el->importwaveform.actions;
118 		break;
119 	    case AuElementTypeBundle:
120 #undef xfer
121 #define xfer(x)	el->bundle.x = e.bundle.x
122 		xfer(num_inputs);
123 		bundle = AuTrue;
124 		break;
125 	    case AuElementTypeMultiplyConstant:
126 #undef xfer
127 #define xfer(x)	el->multiplyconstant.x = e.multiplyconstant.x
128 		xfer(input);
129 		el->multiplyconstant.parms[AuParmsMultiplyConstantConstant] =
130 		    e.multiplyconstant.constant;
131 		break;
132 	    case AuElementTypeAddConstant:
133 #undef xfer
134 #define xfer(x)	el->addconstant.x = e.addconstant.x
135 		xfer(input);
136 		el->addconstant.parms[AuParmsAddConstantConstant] =
137 		    e.addconstant.constant;
138 		break;
139 	    case AuElementTypeSum:
140 #undef xfer
141 #define xfer(x)	el->sum.x = e.sum.x
142 		xfer(num_inputs);
143 		sum = AuTrue;
144 		break;
145 	    case AuElementTypeExportClient:
146 #undef xfer
147 #define xfer(x)	el->exportclient.x = e.exportclient.x
148 		xfer(sample_rate);
149 		xfer(input);
150 		xfer(format);
151 		xfer(num_tracks);
152 		xfer(discard);
153 		xfer(max_samples);
154 		xfer(high_water_mark);
155 		xfer(actions.num_actions);
156 		actions = &el->exportclient.actions;
157 		break;
158 	    case AuElementTypeExportDevice:
159 #undef xfer
160 #define xfer(x)	el->exportdevice.x = e.exportdevice.x
161 		xfer(sample_rate);
162 		xfer(num_samples);
163 		xfer(input);
164 		xfer(device);
165 		xfer(actions.num_actions);
166 		actions = &el->exportdevice.actions;
167 		break;
168 	    case AuElementTypeExportBucket:
169 #undef xfer
170 #define xfer(x)	el->exportbucket.x = e.exportbucket.x
171 		xfer(input);
172 		xfer(num_samples);
173 		xfer(bucket);
174 		el->exportbucket.parms[AuParmsExportBucketOffset] =
175 		    e.exportbucket.offset;
176 		xfer(actions.num_actions);
177 		actions = &el->exportbucket.actions;
178 		break;
179 	    case AuElementTypeExportMonitor:
180 #undef xfer
181 #define xfer(x)	el->exportmonitor.x = e.exportmonitor.x
182 		xfer(input);
183 		xfer(event_rate);
184 		xfer(format);
185 		xfer(num_tracks);
186 		break;
187 	}
188 
189 	if (actions)
190 	{
191 	    auElementAction a;
192 	    AuElementAction *act;
193 	    int             j;
194 
195 	    if (!(actions->actions = act =
196 		  (AuElementAction *) Aumalloc(actions->num_actions *
197 					       sizeof(AuElementAction))))
198 	    {
199 		AuFreeElements(aud, rep.num_elements, elements);
200 		_AuUnlockServer();
201 		_AuSyncHandle(aud);
202 		return NULL;
203 	    }
204 
205 	    for (j = 0; j < actions->num_actions; j++, act++)
206 	    {
207 		_AuReadPad(aud, (char *) &a, SIZEOF(auElementAction));
208 #undef xfer
209 #define xfer(x) act->x = a.x
210 		xfer(flow);
211 		xfer(element_num);
212 		xfer(trigger_state);
213 		xfer(trigger_prev_state);
214 		xfer(trigger_reason);
215 		xfer(action);
216 		xfer(new_state);
217 	    }
218 	}
219 	else if (bundle)
220 	{
221 	    auInputTrack    t;
222 	    AuInputTrack   *tr;
223 	    int             j;
224 
225 	    if (!(el->bundle.inputs = tr = (AuInputTrack *)
226 		  Aumalloc(el->bundle.num_inputs * sizeof(AuInputTrack))))
227 	    {
228 		AuFreeElements(aud, rep.num_elements, elements);
229 		_AuUnlockServer();
230 		_AuSyncHandle(aud);
231 		return NULL;
232 	    }
233 
234 	    for (j = 0; j < (int) el->bundle.num_inputs; j++, tr++)
235 	    {
236 		_AuReadPad(aud, (char *) &t, SIZEOF(auInputTrack));
237 #undef xfer
238 #define xfer(x) tr->x = t.x
239 		xfer(element_num);
240 		xfer(track);
241 	    }
242 	}
243 	else if (sum)
244 	{
245 	    int             n = el->sum.num_inputs * sizeof(unsigned short);
246 
247 	    if (!(el->sum.inputs = (unsigned short *) Aumalloc(n)))
248 	    {
249 		AuFreeElements(aud, rep.num_elements, elements);
250 		_AuUnlockServer();
251 		_AuSyncHandle(aud);
252 		return NULL;
253 	    }
254 
255 	    _AuReadPad(aud, (char *) el->sum.inputs, n);
256 	}
257     }
258 
259     _AuUnlockServer();
260     _AuSyncHandle(aud);
261 
262     return elements;
263 }
264 
265 void
AuFreeElements(AuServer * aud,int num_elements,AuElement * elements)266 AuFreeElements(
267                AuServer       *aud,
268                int             num_elements,
269                AuElement      *elements
270                )
271 {
272     int             i;
273 
274     for (i = 0; i < num_elements; i++)
275     {
276 	AuElement      *el;
277 	AuElementActionList *actions;
278 	AuBool          bundle,
279 	                sum;
280 
281 	actions = NULL;
282 	bundle = sum = AuFalse;
283 	el = &elements[i];
284 
285 	switch (el->type)
286 	{
287 	    case AuElementTypeImportClient:
288 		actions = &el->importclient.actions;
289 		break;
290 	    case AuElementTypeImportDevice:
291 		actions = &el->importdevice.actions;
292 		break;
293 	    case AuElementTypeImportBucket:
294 		actions = &el->importbucket.actions;
295 		break;
296 	    case AuElementTypeImportWaveForm:
297 		actions = &el->importwaveform.actions;
298 		break;
299 	    case AuElementTypeBundle:
300 		bundle = AuTrue;
301 		break;
302 	    case AuElementTypeMultiplyConstant:
303 		break;
304 	    case AuElementTypeAddConstant:
305 		break;
306 	    case AuElementTypeSum:
307 		sum = AuTrue;
308 		break;
309 	    case AuElementTypeExportClient:
310 		actions = &el->exportclient.actions;
311 		break;
312 	    case AuElementTypeExportDevice:
313 		actions = &el->exportdevice.actions;
314 		break;
315 	    case AuElementTypeExportBucket:
316 		actions = &el->exportbucket.actions;
317 		break;
318 	    case AuElementTypeExportMonitor:
319 		break;
320 	}
321 
322 	if (actions)
323 	    Aufree(actions->actions);
324 	else if (bundle)
325 	    Aufree(el->bundle.inputs);
326 	else if (sum)
327 	    Aufree(el->sum.inputs);
328     }
329 
330     Aufree(elements);
331 }
332