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