ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/audio.cpp
Revision: 1.8
Committed: 2001-07-05T20:30:49Z (22 years, 10 months ago) by cebix
Branch: MAIN
Changes since 1.7: +35 -18 lines
Log Message:
- supported audio formats are now kept in STL vectors
- added run-time audio parameter switching for OSS/ESD audio output
- setting ESPEAKER env variable causes B2 to try ESD before OSS

File Contents

# Content
1 /*
2 * audio.cpp - Audio support
3 *
4 * Basilisk II (C) 1997-2001 Christian Bauer
5 * Portions (C) 1997-1999 Marc Hellwig
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 /*
23 * SEE ALSO
24 * Inside Macintosh: Sound, chapter 5 "Sound Components"
25 */
26
27 #include "sysdeps.h"
28 #include "cpu_emulation.h"
29 #include "macos_util.h"
30 #include "emul_op.h"
31 #include "main.h"
32 #include "audio.h"
33 #include "audio_defs.h"
34
35 #define DEBUG 0
36 #include "debug.h"
37
38
39 // Supported sample rates, sizes and channels
40 vector<uint32> audio_sample_rates;
41 vector<uint16> audio_sample_sizes;
42 vector<uint16> audio_channel_counts;
43
44 // Global variables
45 struct audio_status AudioStatus; // Current audio status (sample rate etc.)
46 bool audio_open = false; // Flag: audio is initialized and ready
47 int audio_frames_per_block; // Number of audio frames per block
48 uint32 audio_component_flags; // Component feature flags
49 uint32 audio_data = 0; // Mac address of global data area
50 static int open_count = 0; // Open/close nesting count
51
52 bool AudioAvailable = false; // Flag: audio output available (from the software point of view)
53
54
55 /*
56 * Reset audio emulation
57 */
58
59 void AudioReset(void)
60 {
61 audio_data = 0;
62 }
63
64
65 /*
66 * Get audio info
67 */
68
69 static int32 AudioGetInfo(uint32 infoPtr, uint32 selector, uint32 sourceID)
70 {
71 D(bug(" AudioGetInfo %c%c%c%c, infoPtr %08lx, source ID %08lx\n", selector >> 24, (selector >> 16) & 0xff, (selector >> 8) & 0xff, selector & 0xff, infoPtr, sourceID));
72 M68kRegisters r;
73 int i;
74
75 switch (selector) {
76 case siSampleSize:
77 WriteMacInt16(infoPtr, AudioStatus.sample_size);
78 break;
79
80 case siSampleSizeAvailable: {
81 r.d[0] = audio_sample_sizes.size() * 2;
82 Execute68kTrap(0xa122, &r); // NewHandle()
83 uint32 h = r.a[0];
84 if (h == 0)
85 return memFullErr;
86 WriteMacInt16(infoPtr + sil_count, audio_sample_sizes.size());
87 WriteMacInt32(infoPtr + sil_infoHandle, h);
88 uint32 sp = ReadMacInt32(h);
89 for (i=0; i<audio_sample_sizes.size(); i++)
90 WriteMacInt16(sp + i*2, audio_sample_sizes[i]);
91 break;
92 }
93
94 case siNumberChannels:
95 WriteMacInt16(infoPtr, AudioStatus.channels);
96 break;
97
98 case siChannelAvailable: {
99 r.d[0] = audio_channel_counts.size() * 2;
100 Execute68kTrap(0xa122, &r); // NewHandle()
101 uint32 h = r.a[0];
102 if (h == 0)
103 return memFullErr;
104 WriteMacInt16(infoPtr + sil_count, audio_channel_counts.size());
105 WriteMacInt32(infoPtr + sil_infoHandle, h);
106 uint32 sp = ReadMacInt32(h);
107 for (i=0; i<audio_channel_counts.size(); i++)
108 WriteMacInt16(sp + i*2, audio_channel_counts[i]);
109 break;
110 }
111
112 case siSampleRate:
113 WriteMacInt32(infoPtr, AudioStatus.sample_rate);
114 break;
115
116 case siSampleRateAvailable: {
117 r.d[0] = audio_sample_rates.size() * 4;
118 Execute68kTrap(0xa122, &r); // NewHandle()
119 uint32 h = r.a[0];
120 if (h == 0)
121 return memFullErr;
122 WriteMacInt16(infoPtr + sil_count, audio_sample_rates.size());
123 WriteMacInt32(infoPtr + sil_infoHandle, h);
124 uint32 lp = ReadMacInt32(h);
125 for (i=0; i<audio_sample_rates.size(); i++)
126 WriteMacInt32(lp + i*4, audio_sample_rates[i]);
127 break;
128 }
129
130 case siSpeakerMute:
131 WriteMacInt16(infoPtr, audio_get_speaker_mute());
132 break;
133
134 case siSpeakerVolume:
135 WriteMacInt32(infoPtr, audio_get_speaker_volume());
136 break;
137
138 case siHeadphoneMute:
139 WriteMacInt16(infoPtr, 0);
140 break;
141
142 case siHeadphoneVolume:
143 WriteMacInt32(infoPtr, 0x01000100);
144 break;
145
146 case siHeadphoneVolumeSteps:
147 WriteMacInt16(infoPtr, 13);
148 break;
149
150 case siHardwareMute:
151 WriteMacInt16(infoPtr, audio_get_main_mute());
152 break;
153
154 case siHardwareVolume:
155 WriteMacInt32(infoPtr, audio_get_main_volume());
156 break;
157
158 case siHardwareVolumeSteps:
159 WriteMacInt16(infoPtr, 13);
160 break;
161
162 case siHardwareBusy:
163 WriteMacInt16(infoPtr, AudioStatus.num_sources != 0);
164 break;
165
166 default: // Delegate to Apple Mixer
167 if (AudioStatus.mixer == 0)
168 return badComponentSelector;
169 M68kRegisters r;
170 r.a[0] = infoPtr;
171 r.d[0] = selector;
172 r.a[1] = sourceID;
173 r.a[2] = AudioStatus.mixer;
174 Execute68k(audio_data + adatGetInfo, &r);
175 D(bug(" delegated to Apple Mixer, returns %08lx\n", r.d[0]));
176 return r.d[0];
177 }
178 return noErr;
179 }
180
181
182 /*
183 * Set audio info
184 */
185
186 static int32 AudioSetInfo(uint32 infoPtr, uint32 selector, uint32 sourceID)
187 {
188 D(bug(" AudioSetInfo %c%c%c%c, infoPtr %08lx, source ID %08lx\n", selector >> 24, (selector >> 16) & 0xff, (selector >> 8) & 0xff, selector & 0xff, infoPtr, sourceID));
189 M68kRegisters r;
190 int i;
191
192 switch (selector) {
193 case siSampleSize:
194 D(bug(" set sample size %08lx\n", infoPtr));
195 if (AudioStatus.num_sources)
196 return siDeviceBusyErr;
197 if (infoPtr == AudioStatus.sample_size)
198 return noErr;
199 for (i=0; i<audio_sample_sizes.size(); i++)
200 if (audio_sample_sizes[i] == infoPtr) {
201 if (audio_set_sample_size(i))
202 return noErr;
203 else
204 return siInvalidSampleSize;
205 }
206 return siInvalidSampleSize;
207
208 case siSampleRate:
209 D(bug(" set sample rate %08lx\n", infoPtr));
210 if (AudioStatus.num_sources)
211 return siDeviceBusyErr;
212 if (infoPtr == AudioStatus.sample_rate)
213 return noErr;
214 for (i=0; i<audio_sample_rates.size(); i++)
215 if (audio_sample_rates[i] == infoPtr) {
216 if (audio_set_sample_rate(i))
217 return noErr;
218 else
219 return siInvalidSampleRate;
220 }
221 return siInvalidSampleRate;
222
223 case siNumberChannels:
224 D(bug(" set number of channels %08lx\n", infoPtr));
225 if (AudioStatus.num_sources)
226 return siDeviceBusyErr;
227 if (infoPtr == AudioStatus.channels)
228 return noErr;
229 for (i=0; i<audio_channel_counts.size(); i++)
230 if (audio_channel_counts[i] == infoPtr) {
231 if (audio_set_channels(i))
232 return noErr;
233 else
234 return badChannel;
235 }
236 return badChannel;
237
238 case siSpeakerMute:
239 audio_set_speaker_mute((uint16)infoPtr);
240 break;
241
242 case siSpeakerVolume:
243 D(bug(" set speaker volume %08lx\n", infoPtr));
244 audio_set_speaker_volume(infoPtr);
245 break;
246
247 case siHeadphoneMute:
248 case siHeadphoneVolume:
249 break;
250
251 case siHardwareMute:
252 audio_set_main_mute((uint16)infoPtr);
253 break;
254
255 case siHardwareVolume:
256 D(bug(" set hardware volume %08lx\n", infoPtr));
257 audio_set_main_volume(infoPtr);
258 break;
259
260 default: // Delegate to Apple Mixer
261 if (AudioStatus.mixer == 0)
262 return badComponentSelector;
263 r.a[0] = infoPtr;
264 r.d[0] = selector;
265 r.a[1] = sourceID;
266 r.a[2] = AudioStatus.mixer;
267 Execute68k(audio_data + adatSetInfo, &r);
268 D(bug(" delegated to Apple Mixer, returns %08lx\n", r.d[0]));
269 return r.d[0];
270 }
271 return noErr;
272 }
273
274
275 /*
276 * Sound output component dispatch
277 */
278
279 int32 AudioDispatch(uint32 params, uint32 globals)
280 {
281 D(bug("AudioDispatch params %08lx (size %d), what %d\n", params, ReadMacInt8(params + cp_paramSize), (int16)ReadMacInt16(params + cp_what)));
282 M68kRegisters r;
283 uint32 p = params + cp_params;
284
285 switch ((int16)ReadMacInt16(params + cp_what)) {
286 // Basic component functions
287 case kComponentOpenSelect:
288 if (audio_data == 0) {
289
290 // Allocate global data area
291 r.d[0] = SIZEOF_adat;
292 Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
293 if (r.a[0] == 0)
294 return memFullErr;
295 audio_data = r.a[0];
296 D(bug(" global data at %08lx\n", audio_data));
297
298 // Put in 68k routines
299 int p = audio_data + adatDelegateCall;
300 WriteMacInt16(p, 0x598f); p += 2; // subq.l #4,sp
301 WriteMacInt16(p, 0x2f09); p += 2; // move.l a1,-(sp)
302 WriteMacInt16(p, 0x2f08); p += 2; // move.l a0,-(sp)
303 WriteMacInt16(p, 0x7024); p += 2; // moveq #$24,d0
304 WriteMacInt16(p, 0xa82a); p += 2; // ComponentDispatch
305 WriteMacInt16(p, 0x201f); p += 2; // move.l (sp)+,d0
306 WriteMacInt16(p, M68K_RTS); p += 2; // rts
307 if (p - audio_data != adatOpenMixer)
308 goto adat_error;
309 WriteMacInt16(p, 0x558f); p += 2; // subq.l #2,sp
310 WriteMacInt16(p, 0x2f09); p += 2; // move.l a1,-(sp)
311 WriteMacInt16(p, 0x2f00); p += 2; // move.l d0,-(sp)
312 WriteMacInt16(p, 0x2f08); p += 2; // move.l a0,-(sp)
313 WriteMacInt16(p, 0x203c); p += 2; // move.l #$06140018,d0
314 WriteMacInt32(p, 0x06140018); p+= 4;
315 WriteMacInt16(p, 0xa800); p += 2; // SoundDispatch
316 WriteMacInt16(p, 0x301f); p += 2; // move.w (sp)+,d0
317 WriteMacInt16(p, 0x48c0); p += 2; // ext.l d0
318 WriteMacInt16(p, M68K_RTS); p += 2; // rts
319 if (p - audio_data != adatCloseMixer)
320 goto adat_error;
321 WriteMacInt16(p, 0x558f); p += 2; // subq.l #2,sp
322 WriteMacInt16(p, 0x2f08); p += 2; // move.l a0,-(sp)
323 WriteMacInt16(p, 0x203c); p += 2; // move.l #$02180018,d0
324 WriteMacInt32(p, 0x02180018); p+= 4;
325 WriteMacInt16(p, 0xa800); p += 2; // SoundDispatch
326 WriteMacInt16(p, 0x301f); p += 2; // move.w (sp)+,d0
327 WriteMacInt16(p, 0x48c0); p += 2; // ext.l d0
328 WriteMacInt16(p, M68K_RTS); p += 2; // rts
329 if (p - audio_data != adatGetInfo)
330 goto adat_error;
331 WriteMacInt16(p, 0x598f); p += 2; // subq.l #4,sp
332 WriteMacInt16(p, 0x2f0a); p += 2; // move.l a2,-(sp)
333 WriteMacInt16(p, 0x2f09); p += 2; // move.l a1,-(sp)
334 WriteMacInt16(p, 0x2f00); p += 2; // move.l d0,-(sp)
335 WriteMacInt16(p, 0x2f08); p += 2; // move.l a0,-(sp)
336 WriteMacInt16(p, 0x2f3c); p += 2; // move.l #$000c0103,-(sp)
337 WriteMacInt32(p, 0x000c0103); p+= 4;
338 WriteMacInt16(p, 0x7000); p += 2; // moveq #0,d0
339 WriteMacInt16(p, 0xa82a); p += 2; // ComponentDispatch
340 WriteMacInt16(p, 0x201f); p += 2; // move.l (sp)+,d0
341 WriteMacInt16(p, M68K_RTS); p += 2; // rts
342 if (p - audio_data != adatSetInfo)
343 goto adat_error;
344 WriteMacInt16(p, 0x598f); p += 2; // subq.l #4,sp
345 WriteMacInt16(p, 0x2f0a); p += 2; // move.l a2,-(sp)
346 WriteMacInt16(p, 0x2f09); p += 2; // move.l a1,-(sp)
347 WriteMacInt16(p, 0x2f00); p += 2; // move.l d0,-(sp)
348 WriteMacInt16(p, 0x2f08); p += 2; // move.l a0,-(sp)
349 WriteMacInt16(p, 0x2f3c); p += 2; // move.l #$000c0104,-(sp)
350 WriteMacInt32(p, 0x000c0104); p+= 4;
351 WriteMacInt16(p, 0x7000); p += 2; // moveq #0,d0
352 WriteMacInt16(p, 0xa82a); p += 2; // ComponentDispatch
353 WriteMacInt16(p, 0x201f); p += 2; // move.l (sp)+,d0
354 WriteMacInt16(p, M68K_RTS); p += 2; // rts
355 if (p - audio_data != adatPlaySourceBuffer)
356 goto adat_error;
357 WriteMacInt16(p, 0x598f); p += 2; // subq.l #4,sp
358 WriteMacInt16(p, 0x2f0a); p += 2; // move.l a2,-(sp)
359 WriteMacInt16(p, 0x2f09); p += 2; // move.l a1,-(sp)
360 WriteMacInt16(p, 0x2f08); p += 2; // move.l a0,-(sp)
361 WriteMacInt16(p, 0x2f00); p += 2; // move.l d0,-(sp)
362 WriteMacInt16(p, 0x2f3c); p += 2; // move.l #$000c0108,-(sp)
363 WriteMacInt32(p, 0x000c0108); p+= 4;
364 WriteMacInt16(p, 0x7000); p += 2; // moveq #0,d0
365 WriteMacInt16(p, 0xa82a); p += 2; // ComponentDispatch
366 WriteMacInt16(p, 0x201f); p += 2; // move.l (sp)+,d0
367 WriteMacInt16(p, M68K_RTS); p += 2; // rts
368 if (p - audio_data != adatGetSourceData)
369 goto adat_error;
370 WriteMacInt16(p, 0x598f); p += 2; // subq.l #4,sp
371 WriteMacInt16(p, 0x2f09); p += 2; // move.l a1,-(sp)
372 WriteMacInt16(p, 0x2f08); p += 2; // move.l a0,-(sp)
373 WriteMacInt16(p, 0x2f3c); p += 2; // move.l #$00040004,-(sp)
374 WriteMacInt32(p, 0x00040004); p+= 4;
375 WriteMacInt16(p, 0x7000); p += 2; // moveq #0,d0
376 WriteMacInt16(p, 0xa82a); p += 2; // ComponentDispatch
377 WriteMacInt16(p, 0x201f); p += 2; // move.l (sp)+,d0
378 WriteMacInt16(p, M68K_RTS); p += 2; // rts
379 if (p - audio_data != adatData)
380 goto adat_error;
381 }
382 AudioAvailable = true;
383 if (open_count == 0)
384 audio_enter_stream();
385 open_count++;
386 return noErr;
387
388 adat_error: printf("FATAL: audio component data block initialization error\n");
389 QuitEmulator();
390 return openErr;
391
392 case kComponentCanDoSelect:
393 case kComponentRegisterSelect:
394 return noErr;
395
396 case kComponentVersionSelect:
397 return 0x00010003;
398
399 case kComponentCloseSelect:
400 open_count--;
401 if (open_count == 0) {
402 if (AudioStatus.mixer) {
403 // Close Apple Mixer
404 r.a[0] = AudioStatus.mixer;
405 Execute68k(audio_data + adatCloseMixer, &r);
406 AudioStatus.mixer = 0;
407 return r.d[0];
408 }
409 AudioStatus.num_sources = 0;
410 audio_exit_stream();
411 }
412 return noErr;
413
414 // Sound component functions
415 case kSoundComponentInitOutputDeviceSelect:
416 D(bug(" InitOutputDevice\n"));
417 if (!audio_open)
418 return noHardwareErr;
419 if (AudioStatus.mixer)
420 return noErr;
421
422 // Init sound component data
423 WriteMacInt32(audio_data + adatData + scd_flags, 0);
424 WriteMacInt32(audio_data + adatData + scd_format, AudioStatus.sample_size == 16 ? FOURCC('t','w','o','s') : FOURCC('r','a','w',' '));
425 WriteMacInt16(audio_data + adatData + scd_numChannels, AudioStatus.channels);
426 WriteMacInt16(audio_data + adatData + scd_sampleSize, AudioStatus.sample_size);
427 WriteMacInt32(audio_data + adatData + scd_sampleRate, AudioStatus.sample_rate);
428 WriteMacInt32(audio_data + adatData + scd_sampleCount, audio_frames_per_block);
429 WriteMacInt32(audio_data + adatData + scd_buffer, 0);
430 WriteMacInt32(audio_data + adatData + scd_reserved, 0);
431 WriteMacInt32(audio_data + adatStreamInfo, 0);
432
433 // Open Apple Mixer
434 r.a[0] = audio_data + adatMixer;
435 r.d[0] = 0;
436 r.a[1] = audio_data + adatData;
437 Execute68k(audio_data + adatOpenMixer, &r);
438 AudioStatus.mixer = ReadMacInt32(audio_data + adatMixer);
439 D(bug(" OpenMixer() returns %08lx, mixer %08lx\n", r.d[0], AudioStatus.mixer));
440 return r.d[0];
441
442 case kSoundComponentAddSourceSelect:
443 D(bug(" AddSource\n"));
444 AudioStatus.num_sources++;
445 goto delegate;
446
447 case kSoundComponentRemoveSourceSelect:
448 D(bug(" RemoveSource\n"));
449 AudioStatus.num_sources--;
450 goto delegate;
451
452 case kSoundComponentStopSourceSelect:
453 D(bug(" StopSource\n"));
454 goto delegate;
455
456 case kSoundComponentPauseSourceSelect:
457 D(bug(" PauseSource\n"));
458 delegate: // Delegate call to Apple Mixer
459 D(bug(" delegating call to Apple Mixer\n"));
460 r.a[0] = AudioStatus.mixer;
461 r.a[1] = params;
462 Execute68k(audio_data + adatDelegateCall, &r);
463 D(bug(" returns %08lx\n", r.d[0]));
464 return r.d[0];
465
466 case kSoundComponentStartSourceSelect:
467 D(bug(" StartSource\n"));
468 return noErr;
469
470 case kSoundComponentGetInfoSelect:
471 return AudioGetInfo(ReadMacInt32(p), ReadMacInt32(p + 4), ReadMacInt32(p + 8));
472
473 case kSoundComponentSetInfoSelect:
474 return AudioSetInfo(ReadMacInt32(p), ReadMacInt32(p + 4), ReadMacInt32(p + 8));
475
476 case kSoundComponentPlaySourceBufferSelect:
477 D(bug(" PlaySourceBuffer\n"));
478 r.d[0] = ReadMacInt32(p);
479 r.a[0] = ReadMacInt32(p + 4);
480 r.a[1] = ReadMacInt32(p + 8);
481 r.a[2] = AudioStatus.mixer;
482 Execute68k(audio_data + adatPlaySourceBuffer, &r);
483 D(bug(" returns %08lx\n", r.d[0]));
484 return r.d[0];
485
486 default:
487 return badComponentSelector;
488 }
489 }
490
491
492 /*
493 * Sound input driver Open() routine
494 */
495
496 int16 SoundInOpen(uint32 pb, uint32 dce)
497 {
498 D(bug("SoundInOpen\n"));
499 return noErr;
500 }
501
502
503 /*
504 * Sound input driver Prime() routine
505 */
506
507 int16 SoundInPrime(uint32 pb, uint32 dce)
508 {
509 D(bug("SoundInPrime\n"));
510 //!!
511 return paramErr;
512 }
513
514
515 /*
516 * Sound input driver Control() routine
517 */
518
519 int16 SoundInControl(uint32 pb, uint32 dce)
520 {
521 uint16 code = ReadMacInt16(pb + csCode);
522 D(bug("SoundInControl %d\n", code));
523
524 if (code == 1) {
525 D(bug(" SoundInKillIO\n"));
526 //!!
527 return noErr;
528 }
529
530 if (code != 2)
531 return -231; // siUnknownInfoType
532
533 uint32 *param = (uint32 *)Mac2HostAddr(pb + csParam);
534 uint32 selector = param[0];
535 D(bug(" selector %c%c%c%c\n", selector >> 24, selector >> 16, selector >> 8, selector));
536
537 switch (selector) {
538 default:
539 return -231; // siUnknownInfoType
540 }
541 }
542
543
544 /*
545 * Sound input driver Status() routine
546 */
547
548 int16 SoundInStatus(uint32 pb, uint32 dce)
549 {
550 uint16 code = ReadMacInt16(pb + csCode);
551 D(bug("SoundInStatus %d\n", code));
552 if (code != 2)
553 return -231; // siUnknownInfoType
554
555 uint32 *param = (uint32 *)Mac2HostAddr(pb + csParam);
556 uint32 selector = param[0];
557 D(bug(" selector %c%c%c%c\n", selector >> 24, selector >> 16, selector >> 8, selector));
558 switch (selector) {
559 #if 0
560 case siDeviceName: {
561 const char *str = GetString(STR_SOUND_IN_NAME);
562 param[0] = 0;
563 memcpy((void *)param[1], str, strlen(str));
564 return noErr;
565 }
566
567 case siDeviceIcon: {
568 M68kRegisters r;
569 static const uint16 proc[] = {
570 0x558f, // subq.l #2,sp
571 0xa994, // CurResFile
572 0x4267, // clr.w -(sp)
573 0xa998, // UseResFile
574 0x598f, // subq.l #4,sp
575 0x4879, 0x4943, 0x4e23, // move.l #'ICN#',-(sp)
576 0x3f3c, 0xbf76, // move.w #-16522,-(sp)
577 0xa9a0, // GetResource
578 0x245f, // move.l (sp)+,a2
579 0xa998, // UseResFile
580 0x200a, // move.l a2,d0
581 0x6604, // bne 1
582 0x7000, // moveq #0,d0
583 M68K_RTS,
584 0x2f0a, //1 move.l a2,-(sp)
585 0xa992, // DetachResource
586 0x204a, // move.l a2,a0
587 0xa04a, // HNoPurge
588 0x7001, // moveq #1,d0
589 M68K_RTS
590 };
591 Execute68k((uint32)proc, &r);
592 if (r.d[0]) {
593 param[0] = 4; // Length of returned data
594 param[1] = r.a[2]; // Handle to icon suite
595 return noErr;
596 } else
597 return -192; // resNotFound
598 }
599 #endif
600 default:
601 return -231; // siUnknownInfoType
602 }
603 }
604
605
606 /*
607 * Sound input driver Close() routine
608 */
609
610 int16 SoundInClose(uint32 pb, uint32 dce)
611 {
612 D(bug("SoundInClose\n"));
613 return noErr;
614 }