Annotation of driverkit/libDriver/Kernel/snd_server.m, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.