|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24: /*
25: * snd_server.m
26: *
27: * Copyright (c) 1991, NeXT Computer, Inc. All rights reserved.
28: *
29: * Field old SoundDSP driver user messages for audio driver.
30: *
31: * HISTORY
32: * 08/10/92/mtm Original coding.
33: */
34:
35: #import "audioLog.h"
36: #import "snd_reply.h"
37: #import "snd_server.h"
38: #import "audio_server.h"
39: #import <driverkit/IOAudioPrivate.h>
40: #import "AudioChannel.h"
41: #import "AudioStream.h"
42: #import "audio_kern_server.h"
43: #import <driverkit/NXSoundParameterTags.h>
44: #import <bsd/dev/snd_msgs.h>
45: #import <bsd/dev/audioTypes.h>
46: #import <mach/mach_types.h>
47: #import <kernserv/queue.h>
48: #import <bsd/sys/time.h>
49: #import <driverkit/kernelDriver.h> // for IOVmTaskSelf()
50:
51: #define SND_DIR_PLAY 0
52: #define SND_DIR_RECORD 1
53:
54: /*
55: * DO NOT PUT ANY STATIC DATA IN THIS FILE.
56: * These routines may be used by multiple AudioDevice instances
57: * if more sound boards are added.
58: */
59:
60: static int snd_nx_encoding(int encoding)
61: {
62: switch (encoding) {
63: case SND_STREAM_FORMAT_ENCODING_LINEAR_16:
64: return NX_SoundStreamDataEncoding_Linear16;
65: case SND_STREAM_FORMAT_ENCODING_LINEAR_8:
66: return NX_SoundStreamDataEncoding_Linear8;
67: case SND_STREAM_FORMAT_ENCODING_MULAW_8:
68: default:
69: return NX_SoundStreamDataEncoding_Mulaw8;
70: }
71: }
72:
73: static void snd_set_stream_format(int dir, void *stream,
74: int srate, int encoding, int chans,
75: int low_water, int high_water)
76: {
77: int parray[] = { NX_SoundStreamLowWaterMark,
78: NX_SoundStreamHighWaterMark,
79: NX_SoundStreamSamplingRate,
80: NX_SoundStreamDataEncoding,
81: NX_SoundStreamChannelCount };
82: int pcount = sizeof(parray)/sizeof(int);
83: int pvalues[pcount];
84: kern_return_t kerr;
85:
86: pvalues[0] = low_water;
87: pvalues[1] = high_water;
88: pvalues[2] = srate;
89: pvalues[3] = snd_nx_encoding(encoding);
90: pvalues[4] = chans;
91: kerr = _NXAudioSetStreamParameters(stream, parray, pcount, pvalues);
92: if (kerr != KERN_SUCCESS)
93: xpr_audio_user("AU: snd_set_stream_format: setStreamParams returns "
94: "%d\n", kerr, 2,3,4,5);
95: }
96:
97: /*
98: * Handle stream port messages.
99: */
100: static int snd_stream_msg(msg_header_t *in_msg, msg_header_t *out_msg)
101: {
102: kern_return_t kerr;
103: int size;
104: snd_msg_type_t *msg_type;
105: vm_address_t snd_data = 0;
106: vm_size_t snd_size = 0;
107: int snd_control = 0;
108: int options = 0;
109: int error = 0;
110: int direction = -1;
111: int high_water = 0;
112: int low_water = 0;
113: u_int dma_size, dma_count;
114: struct timeval time_now;
115: snd_stream_msg_t *stream_msg = (snd_stream_msg_t *)in_msg;
116: int data_tag = stream_msg->data_tag;
117: port_t reply_port = PORT_NULL;
118: u_int bytes_processed, time_stamp;
119: int sample_rate = 0, data_encoding = 0, chan_count = 0;
120: boolean_t set_format = FALSE;
121: AudioStream *audioStream = [AudioChannel
122: streamForUserPort:in_msg->msg_local_port];
123:
124: xpr_audio_user("AU: snd_stream_msg: stream 0x%x\n", audioStream,
125: 2,3,4,5);
126:
127: if (in_msg->msg_id == SND_MSG_STREAM_NSAMPLES) {
128: xpr_audio_user("AU: snd_stream_msg: nsamples\n", 1,2,3,4,5);
129: kerr = _NXAudioStreamInfo(audioStream, &bytes_processed,
130: &time_stamp);
131: if (kerr != KERN_SUCCESS)
132: xpr_audio_user("AU: snd_stream_msg: streamInfo returns %d\n",
133: kerr, 2,3,4,5);
134: audio_snd_reply_ret_samples(out_msg, in_msg->msg_remote_port,
135: bytes_processed, time_stamp);
136: return 0;
137: }
138:
139: /*
140: * NOTE: snddriver_client.c sends options and play/record data
141: * in the same message.
142: */
143: size = in_msg->msg_size - sizeof(*stream_msg);
144: msg_type = (snd_msg_type_t *)(stream_msg + 1);
145: while (size > 0) {
146: switch (msg_type->type) {
147: case SND_MT_PLAY_DATA: {
148: #ifdef DDM_DEBUG
149: snd_stream_play_data_t *stream_play_data =
150: (snd_stream_play_data_t *)msg_type;
151: #endif DDM_DEBUG
152:
153: *(int *)&msg_type += sizeof(snd_stream_play_data_t);
154: size -= sizeof(snd_stream_play_data_t);
155:
156: if (!error && direction == SND_DIR_RECORD)
157: error = SND_BAD_PARM;
158: #ifdef DDM_DEBUG
159: options = stream_play_data->options;
160: snd_data = (vm_address_t)stream_play_data->data;
161: snd_size = (vm_size_t)
162: stream_play_data->dataType.msg_type_long_number;
163: #endif DDM_DEBUG
164: xpr_audio_user("AU: snd_stream_msg: play data=0x%x, size=%d\n",
165: snd_data, snd_size, 3,4,5);
166: direction = SND_DIR_PLAY;
167: break;
168: }
169: case SND_MT_RECORD_DATA: {
170: int r;
171: //char *filename;
172: int filename_len;
173: snd_stream_record_data_t *record_data =
174: (snd_stream_record_data_t *)msg_type;
175:
176: filename_len = record_data->filenameType.msg_type_number;
177: r = sizeof(*record_data) + filename_len;
178: *(int *)&msg_type += r;
179: size -= r;
180: xpr_audio_user("AU: snd_stream_msg: record data\n", 1,2,3,4,5);
181: break;
182: }
183: case SND_MT_CONTROL: {
184: snd_stream_control_t *stream_control =
185: (snd_stream_control_t *)msg_type;
186:
187: xpr_audio_user("AU: snd_stream_msg: control\n", 1,2,3,4,5);
188: *(int *)&msg_type += sizeof(snd_stream_control_t);
189: size -= sizeof(snd_stream_control_t);
190:
191: xpr_audio_user("AU: snd_stream_msg: control 0x%x\n",
192: stream_control->snd_control, 2,3,4,5);
193: snd_control |= stream_control->snd_control;
194: break;
195: }
196: case SND_MT_FORMAT: {
197: snd_stream_format_t *stream_format =
198: (snd_stream_format_t *)msg_type;
199: *(int *)&msg_type += sizeof(snd_stream_format_t);
200: size -= sizeof(snd_stream_format_t);
201:
202: sample_rate = stream_format->rate;
203: data_encoding = stream_format->encoding;
204: chan_count = stream_format->chan_count;
205: set_format = TRUE;
206: xpr_audio_user("AU: snd_stream_msg: format sr=%d de=%d cc=%d\n",
207: stream_format->rate,
208: stream_format->encoding,
209: stream_format->chan_count, 4,5);
210: break;
211: }
212: case SND_MT_OPTIONS: {
213: snd_stream_options_t *stream_options =
214: (snd_stream_options_t *)msg_type;
215: xpr_audio_user("AU: snd_stream_msg: options hw=%d lw=%d "
216: "size=%d\n",
217: stream_options->high_water,
218: stream_options->low_water,
219: stream_options->dma_size, 4,5);
220: *(int *)&msg_type += sizeof(snd_stream_options_t);
221: size -= sizeof(snd_stream_options_t);
222: /*
223: * Save water marks for later use by play/record stream call.
224: */
225: high_water = stream_options->high_water;
226: low_water = stream_options->low_water;
227:
228: kerr = _NXAudioGetBufferOptions([audioStream channel],
229: &dma_size, &dma_count);
230: if (kerr != KERN_SUCCESS)
231: xpr_audio_user("AU: snd_stream_msg: getBufferOpts returns "
232: "%d\n", kerr, 2,3,4,5);
233: kerr = _NXAudioSetBufferOptions([audioStream channel], 0,
234: stream_options->dma_size,
235: dma_count);
236: if (kerr != KERN_SUCCESS)
237: xpr_audio_user("AU: snd_stream_msg: setBufferOpts returns "
238: "%d\n", kerr, 2,3,4,5);
239: break;
240: }
241: case SND_MT_NDMA: {
242: snd_stream_ndma_t *stream_ndma = (snd_stream_ndma_t *)msg_type;
243: xpr_audio_user("AU: snd_stream_msg: ndma %d\n",
244: stream_ndma->ndma, 2,3,4,5);
245: *(int *)&msg_type += sizeof(snd_stream_ndma_t);
246: size -= sizeof(snd_stream_ndma_t);
247: kerr = _NXAudioGetBufferOptions([audioStream channel],
248: &dma_size, &dma_count);
249: if (kerr != KERN_SUCCESS)
250: xpr_audio_user("AU: snd_stream_msg: getBufferOpts returns "
251: "%d\n",kerr, 2,3,4,5);
252: kerr = _NXAudioSetBufferOptions([audioStream channel], 0,
253: dma_size,
254: stream_ndma->ndma);
255: if (kerr != KERN_SUCCESS)
256: xpr_audio_user("AU: snd_stream_msg: setBufferOpts returns "
257: "%d\n", kerr, 2,3,4,5);
258: break;
259: }
260: default:
261: error = SND_BAD_MSG;
262: size = 0;
263: break;
264: }
265: }
266:
267: /*
268: * If we found any errors, cleanup and return an error.
269: */
270: if (error) {
271: size = in_msg->msg_size - sizeof(*stream_msg);
272: msg_type = (snd_msg_type_t *)(stream_msg + 1);
273: while (size > 0) {
274: switch (msg_type->type) {
275: case SND_MT_PLAY_DATA: {
276: snd_stream_play_data_t *stream_play_data =
277: (snd_stream_play_data_t *)msg_type;
278:
279: *(int *)&msg_type +=
280: sizeof(snd_stream_play_data_t);
281: size -= sizeof(snd_stream_play_data_t);
282:
283: vm_deallocate(IOVmTaskSelf(),
284: (vm_address_t)stream_play_data->data,
285: stream_play_data->
286: dataType.msg_type_long_number);
287: break;
288: }
289: case SND_MT_RECORD_DATA:
290: *(int *)&msg_type +=
291: sizeof(snd_stream_record_data_t);
292: size -= sizeof(snd_stream_record_data_t);
293: break;
294: case SND_MT_CONTROL:
295: *(int *)&msg_type +=
296: sizeof(snd_stream_control_t);
297: size -= sizeof(snd_stream_control_t);
298: break;
299: case SND_MT_FORMAT:
300: *(int *)&msg_type +=
301: sizeof(snd_stream_format_t);
302: size -= sizeof(snd_stream_format_t);
303: break;
304: case SND_MT_OPTIONS:
305: *(int *)&msg_type +=
306: sizeof(snd_stream_options_t);
307: size -= sizeof(snd_stream_options_t);
308: break;
309: case SND_MT_NDMA:
310: *(int *)&msg_type +=
311: sizeof(snd_stream_ndma_t);
312: size -= sizeof(snd_stream_ndma_t);
313: break;
314: default:
315: /*
316: * This shouldn't happen.
317: */
318: break;
319: }
320: }
321: return error;
322: }
323:
324: /*
325: * Process control requests.
326: */
327: timerclear(&time_now);
328:
329: if (snd_control&SND_DC_ABORT) {
330: kerr = _NXAudioStreamControl(audioStream, _NXAUDIO_STREAM_ABORT,
331: time_now);
332: if (kerr != KERN_SUCCESS)
333: xpr_audio_user("AU: snd_stream_msg: streamControl returns %d\n",
334: kerr,2,3,4,5);
335: }
336: if (snd_control&SND_DC_AWAIT) {
337: kerr = _NXAudioStreamControl(audioStream, _NXAUDIO_STREAM_RETURN_DATA,
338: time_now);
339: if (kerr != KERN_SUCCESS)
340: xpr_audio_user("AU: snd_stream_msg: streamControl returns %d\n",
341: kerr,2,3,4,5);
342: }
343: if (snd_control&SND_DC_PAUSE) {
344: kerr = _NXAudioStreamControl(audioStream, _NXAUDIO_STREAM_PAUSE,
345: time_now);
346: if (kerr != KERN_SUCCESS)
347: xpr_audio_user("AU: snd_stream_msg: streamControl returns %d\n",
348: kerr, 2,3,4,5);
349: }
350: /*
351: * Resume control handled below after (possible) data enqueue.
352: */
353:
354: /*
355: * This time for sure.
356: */
357: size = in_msg->msg_size - sizeof(*stream_msg);
358: msg_type = (snd_msg_type_t *)(stream_msg + 1);
359: while (size > 0) {
360: snd_size = 0;
361: switch (msg_type->type) {
362: case SND_MT_PLAY_DATA: {
363: snd_stream_play_data_t *stream_play_data =
364: (snd_stream_play_data_t *)msg_type;
365:
366: *(int *)&msg_type += sizeof(snd_stream_play_data_t);
367: size -= sizeof(snd_stream_play_data_t);
368:
369: options = stream_play_data->options;
370: snd_data = (vm_address_t)stream_play_data->data;
371: snd_size = (vm_size_t)
372: stream_play_data->dataType.msg_type_long_number;
373: reply_port = stream_play_data->reg_port;
374: break;
375: }
376: case SND_MT_RECORD_DATA: {
377: snd_stream_record_data_t *record_data =
378: (snd_stream_record_data_t *)msg_type;
379:
380: *(int *)&msg_type += sizeof(*record_data);
381: size -= sizeof(*record_data);
382:
383: options = record_data->options;
384: snd_size = (vm_size_t)record_data->nbytes;
385: /*
386: * Note: record data is allocated in audio_server.
387: */
388: reply_port = record_data->reg_port;
389: break;
390: }
391: case SND_MT_CONTROL:
392: *(int *)&msg_type += sizeof(snd_stream_control_t);
393: size -= sizeof(snd_stream_control_t);
394: break;
395: case SND_MT_FORMAT:
396: *(int *)&msg_type += sizeof(snd_stream_format_t);
397: size -= sizeof(snd_stream_format_t);
398: break;
399: case SND_MT_OPTIONS:
400: *(int *)&msg_type += sizeof(snd_stream_options_t);
401: size -= sizeof(snd_stream_options_t);
402: break;
403: case SND_MT_NDMA:
404: *(int *)&msg_type += sizeof(snd_stream_ndma_t);
405: size -= sizeof(snd_stream_ndma_t);
406: break;
407: default:
408: /*
409: * This shouldn't happen.
410: */
411: break;
412: }
413:
414: /*
415: * Enqueue the region.
416: */
417: if (snd_size) {
418: u_int messages = 0;
419:
420: if ((options&SND_DM_STARTED_MSG) != 0)
421: messages |= _NXAUDIO_MSG_STARTED;
422: /*
423: * Old recording code cannot handle completed msg.
424: */
425: if (direction == SND_DIR_PLAY &&
426: (options&SND_DM_COMPLETED_MSG) != 0)
427: messages |= _NXAUDIO_MSG_COMPLETED;
428: if ((options&SND_DM_PAUSED_MSG) != 0)
429: messages |= _NXAUDIO_MSG_PAUSED;
430: if ((options&SND_DM_RESUMED_MSG) != 0)
431: messages |= _NXAUDIO_MSG_RESUMED;
432: if ((options&SND_DM_ABORTED_MSG) != 0)
433: messages |= _NXAUDIO_MSG_ABORTED;
434: if ((options&SND_DM_OVERFLOW_MSG) != 0)
435: messages |= _NXAUDIO_MSG_UNDERRUN;
436:
437: if (direction == SND_DIR_PLAY) {
438: if (set_format) {
439: snd_set_stream_format(direction, audioStream,
440: sample_rate,
441: data_encoding,
442: chan_count,
443: low_water, high_water);
444: kerr = _NXAudioPlayStreamData((OutputStream *)audioStream,
445: snd_data,
446: snd_size, data_tag,
447: reply_port, messages);
448: if (kerr != KERN_SUCCESS) {
449: xpr_audio_user("AU: snd_stream_msg: playStreamD "
450: "returns %d\n", kerr, 2,3,4,5);
451: }
452: } else {
453: if ([audioStream type] == _NXAUDIO_STREAM_TYPE_SND_22)
454: sample_rate = _NXAUDIO_RATE_22050;
455: else
456: sample_rate = _NXAUDIO_RATE_44100;
457: kerr = _NXAudioPlayStream((OutputStream *)audioStream,
458: snd_data,
459: snd_size,
460: data_tag, 2, sample_rate,
461: 32768, 32768, /* gains */
462: low_water, high_water,
463: reply_port, messages);
464: if (kerr != KERN_SUCCESS) {
465: /* audio_server deallocs data if error */
466: xpr_audio_user("AU: snd_stream_msg: playStream returns"
467: " %d\n",kerr, 2,3,4,5);
468: }
469: }
470: /*
471: * Data has been enqueued. Send a message to the client
472: * telling that it is okay to enqueue more data.
473: */
474: } else {
475: if (set_format) {
476: snd_set_stream_format(direction, audioStream,
477: sample_rate,
478: data_encoding,
479: chan_count,
480: low_water, high_water);
481: kerr = _NXAudioRecordStreamData((InputStream *)audioStream,
482: snd_size, data_tag,
483: reply_port, messages);
484: if (kerr != KERN_SUCCESS) {
485: xpr_audio_user("AU: snd_stream_msg: recStreamD returns"
486: " %d\n",kerr, 2,3,4,5);
487: }
488: } else {
489: kerr = _NXAudioRecordStream((InputStream *)audioStream,
490: snd_size,
491: data_tag,
492: low_water, high_water,
493: reply_port, messages);
494: if (kerr != KERN_SUCCESS)
495: xpr_audio_user("AU: snd_stream_msg: recordStream "
496: "returns %d\n", kerr, 2,3,4,5);
497: }
498: }
499: }
500: }
501:
502: if (snd_control&SND_DC_RESUME) {
503: kerr = _NXAudioStreamControl(audioStream, _NXAUDIO_STREAM_RESUME,
504: time_now);
505: if (kerr != KERN_SUCCESS)
506: xpr_audio_user("AU: snd_stream_msg: streamControl returns %d\n",
507: kerr, 2,3,4,5);
508: }
509:
510: return (error ? error : SND_NO_ERROR);
511: }
512:
513: static void snd_get_stream_formats(void *dev, int *rates,
514: int *low_rate, int *high_rate,
515: int *encodings, int *chans)
516: {
517: int parms[_NXAUDIO_PARAM_MAX];
518: int count, continuous, i;
519: kern_return_t kerr;
520:
521: kerr = _NXAudioGetSamplingRates(dev, &continuous, low_rate,
522: high_rate, parms, &count);
523: if (kerr != KERN_SUCCESS)
524: xpr_audio_user("AU: snd_get_stream_formats: getSamplingRates returns "
525: "%d\n", kerr, 2,3,4,5);
526:
527: *rates = 0;
528: if (continuous)
529: *rates |= SND_STREAM_FORMAT_RATE_CONTINUOUS;
530: for (i = 0; i < count; i++) {
531: if (parms[i] >= 8000 && parms[i] <= 8013)
532: *rates |= SND_STREAM_FORMAT_RATE_8000;
533: else switch (parms[i]) {
534: case 11025:
535: *rates |= SND_STREAM_FORMAT_RATE_11025;
536: break;
537: case 16000:
538: *rates |= SND_STREAM_FORMAT_RATE_16000;
539: break;
540: case 22050:
541: *rates |= SND_STREAM_FORMAT_RATE_22050;
542: break;
543: case 32000:
544: *rates |= SND_STREAM_FORMAT_RATE_32000;
545: break;
546: case 44100:
547: *rates |= SND_STREAM_FORMAT_RATE_44100;
548: break;
549: case 48000:
550: *rates |= SND_STREAM_FORMAT_RATE_48000;
551: break;
552: default:
553: break;
554: }
555: }
556:
557: kerr = _NXAudioGetDataEncodings(dev, parms, &count);
558: if (kerr != KERN_SUCCESS)
559: xpr_audio_user("AU: snd_get_stream_formats: getDataEncodings returns "
560: "%d\n", kerr,2,3,4,5);
561:
562: *encodings = 0;
563: for (i = 0; i < count; i++)
564: switch (parms[i]) {
565: case NX_SoundStreamDataEncoding_Mulaw8:
566: *encodings |= SND_STREAM_FORMAT_ENCODING_MULAW_8;
567: break;
568: case NX_SoundStreamDataEncoding_Linear8:
569: *encodings |= SND_STREAM_FORMAT_ENCODING_LINEAR_8;
570: break;
571: case NX_SoundStreamDataEncoding_Linear16:
572: *encodings |= SND_STREAM_FORMAT_ENCODING_LINEAR_16;
573: break;
574: default:
575: break;
576: }
577: kerr = _NXAudioGetChannelCountLimit(dev, chans);
578: if (kerr != KERN_SUCCESS)
579: xpr_audio_user("AU: snd_get_stream_formats: getChanCount returns %d\n",
580: kerr, 2,3,4,5);
581: }
582:
583: /*
584: * Handle device port messages.
585: */
586: static int snd_device_msg(msg_header_t *in_msg, msg_header_t *out_msg)
587: {
588: int ret = SND_NO_ERROR;
589: snd_get_stream_t *get_stream;
590: snd_set_parms_t *set_parms;
591: snd_get_volume_t *get_volume;
592: snd_set_volume_t *set_volume;
593: snd_set_owner_t *set_owner;
594: snd_get_stream_formats_t *get_formats;
595: snd_reset_owner_t *reset_owner;
596: snd_new_device_t *new_device;
597: u_int new_parms = 0, parms = 0;
598: u_int vol;
599: int lv, rv;
600: int rates, low, high, encodings, chans;
601: kern_return_t kerr;
602: id audioChan;
603: port_t new_stream, new_port;
604: int stream_type;
605: struct timeval time_now;
606: AudioStream *audioStream;
607:
608: timerclear(&time_now);
609:
610: /*
611: * The return values mean:
612: * SND_NO_ERROR - no error but need a reply msg sent
613: * 0 - no error, and no reply needed (we sent a reply)
614: * other - error, send a reply message
615: */
616:
617: switch (in_msg->msg_id) {
618: case SND_MSG_GET_STREAM:
619: if (in_msg->msg_size != sizeof(snd_get_stream_t))
620: return SND_BAD_PARM;
621: get_stream = (snd_get_stream_t *)in_msg;
622: xpr_audio_user("AU: snd_dev_msg: get_stream 0x%x\n",
623: get_stream->stream,2,3,4,5);
624:
625: if (get_stream->stream == SND_GD_SIN) {
626: audioChan =
627: [IOAudio _inputChannelForSndPort:in_msg->msg_local_port];
628: xpr_audio_user("AU: snd_dev_msg: input chan 0x%x\n", audioChan,
629: 2,3,4,5);
630: if (!(new_stream =
631: [audioChan streamUserForOwnerPort:get_stream->owner])) {
632: kerr = _NXAudioAddStream(audioChan, &new_stream,
633: get_stream->owner, 0, /* id */
634: _NXAUDIO_STREAM_TYPE_SND);
635: if (kerr != KERN_SUCCESS)
636: xpr_audio_user("AU: snd_dev_msg: addStream returns %d\n",
637: kerr, 2,3,4,5);
638: }
639: } else {
640: if (get_stream->stream == SND_GD_SOUT_22)
641: stream_type = _NXAUDIO_STREAM_TYPE_SND_22;
642: else
643: stream_type = _NXAUDIO_STREAM_TYPE_SND_44;
644: audioChan =
645: [IOAudio _outputChannelForSndPort:in_msg->msg_local_port];
646: xpr_audio_user("AU: snd_dev_msg: output chan 0x%x\n", audioChan,
647: 2,3,4,5);
648: if (!(new_stream =
649: [audioChan streamUserForOwnerPort:get_stream->owner])) {
650: kerr = _NXAudioAddStream(audioChan, &new_stream,
651: get_stream->owner, 0, /* id */
652: stream_type);
653: if (kerr != KERN_SUCCESS)
654: xpr_audio_user("AU: snd_dev_msg: addStream returns %d\n",
655: kerr,2,3,4,5);
656: }
657: }
658: audio_snd_reply_ret_stream(out_msg, in_msg->msg_remote_port, new_stream);
659: ret = 0;
660: break;
661: case SND_MSG_SET_PARMS:
662: xpr_audio_user("AU: snd_dev_msg: set_parms\n", 1,2,3,4,5);
663: if (in_msg->msg_size != sizeof(snd_set_parms_t))
664: return SND_BAD_PARM;
665: set_parms = (snd_set_parms_t *)in_msg;
666:
667: audioChan = [IOAudio _outputChannelForSndPort:in_msg->msg_local_port];
668: kerr = _NXAudioGetSndoutOptions(audioChan, &new_parms);
669: if (kerr != KERN_SUCCESS)
670: xpr_audio_user("AU: snd_dev_msg: getSndoutOptions returns %d\n",
671: kerr, 2,3,4,5);
672: if (set_parms->parms&SND_PARM_ZEROFILL)
673: new_parms |= _NXAUDIO_SNDOUT_ZEROFILL;
674: else
675: new_parms &= ~_NXAUDIO_SNDOUT_ZEROFILL;
676: if (set_parms->parms&SND_PARM_SPEAKER)
677: new_parms |= _NXAUDIO_SNDOUT_SPEAKER_ON;
678: else
679: new_parms &= ~_NXAUDIO_SNDOUT_SPEAKER_ON;
680: if (set_parms->parms&SND_PARM_LOWPASS)
681: new_parms |= _NXAUDIO_SNDOUT_DEEMPHASIS;
682: else
683: new_parms &= ~_NXAUDIO_SNDOUT_DEEMPHASIS;
684:
685: kerr = _NXAudioSetSndoutOptions(audioChan, 0, new_parms);
686: if (kerr != KERN_SUCCESS)
687: xpr_audio_user("AU: snd_dev_msg: setSndoutOptions returns %d\n",
688: kerr, 2,3,4,5);
689: break;
690: case SND_MSG_GET_PARMS:
691: xpr_audio_user("AU: snd_dev_msg: get_parms\n", 1,2,3,4,5);
692: if (in_msg->msg_size != sizeof(snd_get_parms_t))
693: return SND_BAD_PARM;
694:
695: audioChan = [IOAudio _outputChannelForSndPort:in_msg->msg_local_port];
696: kerr = _NXAudioGetSndoutOptions(audioChan, &new_parms);
697: if (kerr != KERN_SUCCESS)
698: xpr_audio_user("AU: snd_dev_msg: getSndoutOptions returns %d\n",
699: kerr,2,3,4,5);
700: if (new_parms&_NXAUDIO_SNDOUT_ZEROFILL)
701: parms |= SND_PARM_ZEROFILL;
702: if (new_parms&_NXAUDIO_SNDOUT_SPEAKER_ON)
703: parms |= SND_PARM_SPEAKER;
704: if (new_parms&_NXAUDIO_SNDOUT_DEEMPHASIS)
705: parms |= SND_PARM_LOWPASS;
706:
707: audio_snd_reply_ret_parms(out_msg, in_msg->msg_remote_port, parms);
708: ret = 0;
709: break;
710: case SND_MSG_SET_VOLUME:
711: xpr_audio_user("AU: snd_dev_msg: set_vol\n", 1,2,3,4,5);
712: if (in_msg->msg_size != sizeof(snd_set_volume_t))
713: return SND_BAD_PARM;
714: set_volume = (snd_set_volume_t *)in_msg;
715:
716: vol = set_volume->volume;
717: lv = ((vol&SND_VOLUME_LCHAN_MASK) >>SND_VOLUME_LCHAN_SHIFT);
718: rv = ((vol&SND_VOLUME_RCHAN_MASK) >>SND_VOLUME_RCHAN_SHIFT);
719: xpr_audio_user("AU: snd_dev_msg: set_vol: %d %d\n", lv, rv, 3,4,5);
720: /*
721: * Convert from range [1,43] to [-84,0].
722: */
723: lv = ((lv-1)*2)-84;
724: rv = ((rv-1)*2)-84;
725: audioChan = [IOAudio _outputChannelForSndPort:in_msg->msg_local_port];
726: kerr = _NXAudioSetSpeaker(audioChan, 0, lv, rv);
727: if (kerr != KERN_SUCCESS)
728: xpr_audio_user("AU: snd_dev_msg: setSpeaker returns %d\n", kerr,
729: 2,3,4,5);
730: break;
731: case SND_MSG_GET_VOLUME:
732: xpr_audio_user("AU: snd_dev_msg: get_vol\n", 1,2,3,4,5);
733: if (in_msg->msg_size != sizeof(snd_get_volume_t))
734: return SND_BAD_PARM;
735: get_volume = (snd_get_volume_t *)in_msg;
736:
737: audioChan = [IOAudio _outputChannelForSndPort:in_msg->msg_local_port];
738: kerr = _NXAudioGetSpeaker(audioChan, &lv, &rv);
739: if (kerr != KERN_SUCCESS)
740: xpr_audio_user("AU: snd_dev_msg: getSpeaker returns %d\n", kerr,
741: 2,3,4,5);
742: /*
743: * Convert from range [-84,0] to [1,43].
744: */
745: lv = 43 + (lv/2);
746: rv = 43 + (rv/2);
747: vol = (lv<<SND_VOLUME_LCHAN_SHIFT) | (rv<<SND_VOLUME_RCHAN_SHIFT);
748:
749: xpr_audio_user("AU: snd_dev_msg: get_vol: %d %d\n", lv, rv, 3,4,5);
750: audio_snd_reply_ret_volume(out_msg, in_msg->msg_remote_port, vol);
751: ret = 0;
752: break;
753: /* New for 3.1 */
754: case SND_MSG_GET_SNDOUT_FORMATS:
755: xpr_audio_user("AU: snd_dev_msg: get_sndout_formats\n", 1,2,3,4,5);
756: if (in_msg->msg_size != sizeof(snd_get_stream_formats_t))
757: return SND_BAD_PARM;
758: get_formats = (snd_get_stream_formats_t *)in_msg;
759:
760: audioChan = [IOAudio _outputChannelForSndPort:in_msg->msg_local_port];
761: snd_get_stream_formats(audioChan, &rates, &low, &high,
762: &encodings, &chans);
763: audio_snd_reply_ret_formats(out_msg, in_msg->msg_remote_port,
764: rates, low, high,
765: encodings, chans);
766: ret = 0;
767: break;
768: case SND_MSG_GET_SNDIN_FORMATS:
769: xpr_audio_user("AU: snd_dev_msg: get_sndin_formats\n", 1,2,3,4,5);
770: if (in_msg->msg_size != sizeof(snd_get_stream_formats_t))
771: return SND_BAD_PARM;
772: get_formats = (snd_get_stream_formats_t *)in_msg;
773:
774: audioChan = [IOAudio _inputChannelForSndPort:in_msg->msg_local_port];
775: snd_get_stream_formats(audioChan, &rates, &low, &high,
776: &encodings, &chans);
777: audio_snd_reply_ret_formats(out_msg, in_msg->msg_remote_port,
778: rates, low, high,
779: encodings, chans);
780: ret = 0;
781: break;
782: case SND_MSG_SET_RAMP:
783: xpr_audio_user("AU: snd_dev_msg: set_ramp\n", 1,2,3,4,5);
784: if (in_msg->msg_size != sizeof(snd_set_parms_t))
785: return SND_BAD_PARM;
786: set_parms = (snd_set_parms_t *)in_msg;
787:
788: audioChan = [IOAudio _outputChannelForSndPort:in_msg->msg_local_port];
789: kerr = _NXAudioGetSndoutOptions(audioChan, &new_parms);
790: if (kerr != KERN_SUCCESS)
791: xpr_audio_user("AU: snd_dev_msg: getSndoutOptions returns %d\n",
792: kerr, 2,3,4,5);
793: if (set_parms->parms&SND_PARM_RAMPUP)
794: new_parms |= _NXAUDIO_SNDOUT_RAMPUP;
795: else
796: new_parms &= ~_NXAUDIO_SNDOUT_RAMPUP;
797: if (set_parms->parms&SND_PARM_RAMPDOWN)
798: new_parms |= _NXAUDIO_SNDOUT_RAMPDOWN;
799: else
800: new_parms &= ~_NXAUDIO_SNDOUT_RAMPDOWN;
801:
802: kerr = _NXAudioSetSndoutOptions(audioChan, 0, new_parms);
803: if (kerr != KERN_SUCCESS)
804: xpr_audio_user("AU: snd_dev_msg: setSndoutOptions returns %d\n",
805: kerr,2,3,4,5);
806: break;
807: case SND_MSG_SET_DSPOWNER:
808: xpr_audio_user("AU: snd_dev_msg: set_dspowner\n", 1,2,3,4,5);
809: /*
810: * DSP is never available.
811: */
812: return SND_SEARCH;
813: break;
814: case SND_MSG_SET_SNDINOWNER:
815: if (in_msg->msg_size != sizeof(snd_set_owner_t))
816: return SND_BAD_PARM;
817: set_owner = (snd_set_owner_t *)in_msg;
818: xpr_audio_user("AU: snd_dev_msg: set_sndinowner 0x%x\n",
819: set_owner->owner,2,3,4,5);
820: /*
821: * Abort (reset) stream if asserting same owner port.
822: */
823: if ((audioStream =
824: [AudioChannel streamForOwnerPort:set_owner->owner])) {
825: kerr = _NXAudioStreamControl(audioStream,
826: _NXAUDIO_STREAM_ABORT, time_now);
827: if (kerr != KERN_SUCCESS)
828: xpr_audio_user("AU: snd_dev_msg: streamControl returns %d\n",
829: kerr,2,3,4,5);
830: }
831: break;
832: case SND_MSG_SET_SNDOUTOWNER:
833: if (in_msg->msg_size != sizeof(snd_set_owner_t))
834: return SND_BAD_PARM;
835: set_owner = (snd_set_owner_t *)in_msg;
836: xpr_audio_user("AU: snd_dev_msg: set_sndoutowner 0x%x\n",
837: set_owner->owner, 2,3,4,5);
838: /*
839: * Abort (reset) stream if asserting same owner port.
840: */
841: if ((audioStream =
842: [AudioChannel streamForOwnerPort:set_owner->owner])) {
843: kerr = _NXAudioStreamControl(audioStream,
844: _NXAUDIO_STREAM_ABORT, time_now);
845: if (kerr != KERN_SUCCESS)
846: xpr_audio_user("AU: snd_dev_msg: streamControl returns %d\n",
847: kerr, 2,3,4,5);
848: }
849: break;
850: case SND_MSG_NEW_DEVICE_PORT:
851: /*
852: * This is only marginally useful now, since the NXSound device
853: * ports do NOT get reset by this message.
854: */
855: if (in_msg->msg_size != sizeof(snd_new_device_t))
856: return SND_BAD_PARM;
857: new_device = (snd_new_device_t *)in_msg;
858: xpr_audio_user("AU: snd_dev_msg: new_device_port\n", 1,2,3,4,5);
859: /*
860: * Note: input and output chans share the same user msg device port.
861: */
862: audioChan = [IOAudio _outputChannelForSndPort: in_msg->msg_local_port];
863: new_port = audio_reset_snd_dev_port([audioChan audioDevice],
864: new_device->priv);
865: if (new_port == PORT_NULL)
866: return SND_BAD_HOST_PRIV;
867:
868: [audioChan removeSndStreams];
869: audioChan = [IOAudio _inputChannelForSndPort: in_msg->msg_local_port];
870: [audioChan removeSndStreams];
871:
872: audio_snd_reply_ret_device(out_msg, in_msg->msg_remote_port, new_port);
873: ret = 0;
874: break;
875: case SND_MSG_RESET_SNDINOWNER:
876: if (in_msg->msg_size != sizeof(snd_reset_owner_t))
877: return SND_BAD_PARM;
878: reset_owner = (snd_reset_owner_t *)in_msg;
879: xpr_audio_user("AU: snd_dev_msg: reset_sndinowner 0x%x\n",
880: reset_owner->old_owner, 2,3,4,5);
881: audioStream = [AudioChannel streamForOwnerPort:reset_owner->old_owner];
882: if (!audioStream)
883: return SND_NOT_OWNER;
884: kerr = _NXAudioRemoveStream(audioStream);
885: if (kerr != KERN_SUCCESS)
886: xpr_audio_user("AU: snd_dev_msg: removeStream returns %d\n", kerr,
887: 2,3,4,5);
888: break;
889: case SND_MSG_RESET_SNDOUTOWNER:
890: if (in_msg->msg_size != sizeof(snd_reset_owner_t))
891: return SND_BAD_PARM;
892: reset_owner = (snd_reset_owner_t *)in_msg;
893: xpr_audio_user("AU: snd_dev_msg: reset_sndoutowner 0x%x\n",
894: reset_owner->old_owner, 2,3,4,5);
895: audioStream = [AudioChannel streamForOwnerPort:reset_owner->old_owner];
896: if (!audioStream)
897: return SND_NOT_OWNER;
898: kerr = _NXAudioRemoveStream(audioStream);
899: if (kerr != KERN_SUCCESS)
900: xpr_audio_user("AU: snd_dev_msg: removeStream returns %d\n", kerr,
901: 2,3,4,5);
902: break;
903: case SND_MSG_DSP_PROTO:
904: case SND_MSG_GET_DSP_CMD_PORT:
905: case SND_MSG_RESET_DSPOWNER:
906: xpr_audio_user("AU: snd_dev_msg: dsp msg\n", 1,2,3,4,5);
907: /*
908: * DSP is never available.
909: */
910: return SND_SEARCH;
911: break;
912: default:
913: /* impossible */
914: break;
915: }
916: return ret;
917: }
918:
919: /*
920: * Handle in_msg and setup out_msg for reply.
921: */
922: boolean_t snd_server(msg_header_t *in_msg, msg_header_t *out_msg)
923: {
924: boolean_t ret = TRUE;
925: int reply_val = 0;
926:
927: /*
928: * Standard reply header.
929: */
930: out_msg->msg_simple = TRUE;
931: out_msg->msg_size = sizeof(msg_header_t);
932: out_msg->msg_type = MSG_TYPE_NORMAL;
933: out_msg->msg_local_port = PORT_NULL;
934: out_msg->msg_remote_port = PORT_NULL;
935: out_msg->msg_id = 0;
936:
937: if (in_msg->msg_id >= SND_MSG_STREAM_BASE &&
938: in_msg->msg_id <= SND_MSG_STREAM_NSAMPLES)
939: reply_val = snd_stream_msg(in_msg, out_msg);
940: else if (in_msg->msg_id >= SND_MSG_DEVICE_BASE &&
941: in_msg->msg_id <= SND_MSG_GET_SNDIN_FORMATS)
942: reply_val = snd_device_msg(in_msg, out_msg);
943: else if (in_msg->msg_id >= SND_MSG_DSP_BASE &&
944: in_msg->msg_id <= SND_MSG_DSP_REQ_ERR) {
945: /*
946: * Should not happen since you can't set a dsp owner port.
947: */
948: log_error(("Audio: received dsp cmd port msg!\n"));
949: audio_snd_reply_illegal_msg(out_msg, PORT_NULL, in_msg->msg_remote_port,
950: in_msg->msg_id, SND_BAD_MSG);
951: ret = FALSE;
952: } else {
953: audio_snd_reply_illegal_msg(out_msg, PORT_NULL, in_msg->msg_remote_port,
954: in_msg->msg_id, SND_BAD_MSG);
955: ret = FALSE;
956: }
957: /*
958: * Send a reply if msg handler routine didn't.
959: */
960: if (reply_val)
961: audio_snd_reply_illegal_msg(out_msg, PORT_NULL, in_msg->msg_remote_port,
962: in_msg->msg_id, reply_val);
963: return ret;
964: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.