Annotation of XNU/iokit/Families/IOAudio/IOAudioBus.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
        !            24:  *
        !            25:  * Hardware independent (relatively) code for the AudioBus
        !            26:  *
        !            27:  * HISTORY
        !            28:  *
        !            29:  *
        !            30:  */
        !            31: 
        !            32: #include <IOKit/audio/IOAudioBus.h>
        !            33: #include <IOKit/IOLib.h>
        !            34: #include <IOKit/IOWorkLoop.h>
        !            35: #include <IOKit/IOFilterInterruptEventSource.h>
        !            36: 
        !            37: #undef super
        !            38: #define super IOAudioController
        !            39: 
        !            40: //************************************************************************
        !            41: // Implementation of protocol clas.
        !            42: //************************************************************************
        !            43: OSDefineMetaClass(  IOAudioBus, IOAudioController )
        !            44: OSDefineAbstractStructors(  IOAudioBus, IOAudioController )
        !            45: 
        !            46: #ifdef __ppc__
        !            47: 
        !            48: //************************************************************************
        !            49: // Begin implementation of IOAudioBus class.
        !            50: //************************************************************************
        !            51: 
        !            52: #define kNumberOfBuffers  4
        !            53: #define kNumberOfSamples  8192
        !            54: #define kNumberOfChannels 2    // left and right
        !            55: #define kSampleSize      2     // 16 bit channels
        !            56: #define kBlockSize       256
        !            57: 
        !            58: const int IOAudioBus::kAudioDMAdeviceInt       = 0;
        !            59: const int IOAudioBus::kAudioDMAtxInt           = 1;
        !            60: const int IOAudioBus::kAudioDMArxInt           = 2;
        !            61: 
        !            62: const int IOAudioBus::kAudioDMAOutputStream    = 0;
        !            63: const int IOAudioBus::kAudioDMAInputStream     = 1;
        !            64: 
        !            65: // Constructs an empty audio bus:
        !            66: bool
        !            67: IOAudioBus::init(OSDictionary * properties)
        !            68: {
        !            69:     if (!super::init(properties))
        !            70:             return false;
        !            71: 
        !            72:     ioAudioStreamsDMA = NULL;
        !            73:     numDMAStreams = NULL;
        !            74: 
        !            75:     // Initialize my ivars.
        !            76:     fBufMax = kNumberOfBuffers * kNumberOfSamples * kNumberOfChannels * kSampleSize;
        !            77:     fBlockSize = kBlockSize;
        !            78: 
        !            79:     return true;
        !            80: }
        !            81: 
        !            82: // This should free everything
        !            83: void
        !            84: IOAudioBus::free()
        !            85: {
        !            86:     FreeStreams();
        !            87:     super::free();
        !            88: }
        !            89: 
        !            90: void IOAudioBus::startWorkLoop()
        !            91: {
        !            92:     super::startWorkLoop();
        !            93:     registerInterrupts();
        !            94: }
        !            95: 
        !            96: void IOAudioBus::registerInterrupts()
        !            97: {
        !            98:     fTxInterruptSource = IOFilterInterruptEventSource::filterInterruptEventSource(this,
        !            99:                                                                                   IOAudioBus::AudioBusInterruptHandler,
        !           100:                                                                                   IOAudioBus::AudioBusInterruptFilter,
        !           101:                                                                                   fDevice,
        !           102:                                                                                   kAudioDMAtxInt);
        !           103:     fWorkLoop->addEventSource(fTxInterruptSource);
        !           104: 
        !           105:     fRxInterruptSource = IOFilterInterruptEventSource::filterInterruptEventSource(this,
        !           106:                                                                                   IOAudioBus::AudioBusInterruptHandler,
        !           107:                                                                                   IOAudioBus::AudioBusInterruptFilter,
        !           108:                                                                                   fDevice,
        !           109:                                                                                   kAudioDMArxInt);
        !           110:     fWorkLoop->addEventSource(fRxInterruptSource);
        !           111: 
        !           112:     fTxInterruptSource->enable();
        !           113:     fRxInterruptSource->enable();
        !           114: }
        !           115: 
        !           116: bool IOAudioBus::AudioBusInterruptFilter(OSObject *owner,
        !           117:                                IOFilterInterruptEventSource *source)
        !           118: {
        !           119:     register IOAudioBus *bus = (IOAudioBus *)owner;
        !           120:     bool result = true;
        !           121: 
        !           122:     if (bus) {
        !           123:         result = bus->filterInterrupt(source->getIntIndex());
        !           124:     }
        !           125: 
        !           126:     return result;
        !           127: }
        !           128: 
        !           129: bool IOAudioBus::filterInterrupt(int index)
        !           130: {
        !           131:     IOAudioStreamStatus *status = getSharedStatus(getStreamForInterrupt(index));
        !           132: 
        !           133:     if (status) {
        !           134:         clock_get_uptime(&status->fLastLoopTime);
        !           135:         ++status->fCurrentLoopCount;
        !           136:     }
        !           137: 
        !           138:     return false;
        !           139: }
        !           140: 
        !           141: void IOAudioBus::AudioBusInterruptHandler(OSObject *owner,
        !           142:                                 IOInterruptEventSource * /*source*/,
        !           143:                                 int /*count*/)
        !           144: {
        !           145:     return;
        !           146: }
        !           147: 
        !           148: AudioStreamIndex IOAudioBus::getStreamForInterrupt(int index)
        !           149: {
        !           150:     AudioStreamIndex result = kNoStream;
        !           151: 
        !           152:     switch (index) {
        !           153:         case kAudioDMAtxInt:
        !           154:             result = kAudioDMAOutputStream;
        !           155:             break;
        !           156:         case kAudioDMArxInt:
        !           157:             result = kAudioDMAInputStream;
        !           158:             break;
        !           159:     }
        !           160:     return result;
        !           161: }
        !           162: 
        !           163: // Creates n empty streams (also a method to free them)
        !           164: bool
        !           165: IOAudioBus::AllocateStreams(int n)
        !           166: {
        !           167:     numDMAStreams = n;
        !           168: 
        !           169:     if (numDMAStreams > 0) {
        !           170:         // Allocates as many StreamDMAInfo as needed:
        !           171:         ioAudioStreamsDMA = (StreamDMAInfo*)IOMalloc(sizeof(StreamDMAInfo) * numDMAStreams);
        !           172:         if (ioAudioStreamsDMA == NULL) {
        !           173:             numDMAStreams = 0;
        !           174:             return false;
        !           175:         }
        !           176:         for (n =0 ; n < numDMAStreams; n++) {
        !           177:             ioAudioStreamsDMA[n].streamProperty = NULL;
        !           178:             ioAudioStreamsDMA[n].fIOBaseDMA = NULL;
        !           179:             ioAudioStreamsDMA[n].fSharedStatus = NULL;
        !           180:         }
        !           181:   
        !           182:         return (true);
        !           183:     }
        !           184: 
        !           185:     return (false);
        !           186: }
        !           187: 
        !           188: bool
        !           189: IOAudioBus::FreeStreams()
        !           190: {
        !           191:     int n;
        !           192: 
        !           193:     if (ioAudioStreamsDMA != NULL) {
        !           194:         // First stops all the streams:
        !           195:         for (n =0 ; n < numDMAStreams; n++)
        !           196:             if (ioAudioStreamsDMA[n].fIOBaseDMA != NULL) {
        !           197:                 stopStream(n);
        !           198: 
        !           199:                 // If we ever created a stream property fpr the stream, delete it:
        !           200:                 IOFree(ioAudioStreamsDMA[n].streamProperty, 128);
        !           201:                 ioAudioStreamsDMA[n].streamProperty = NULL;
        !           202:             }
        !           203: 
        !           204:         IOFree(ioAudioStreamsDMA, sizeof(StreamDMAInfo) * numDMAStreams);
        !           205:         ioAudioStreamsDMA = NULL;
        !           206: 
        !           207:         return true;
        !           208:     }
        !           209: 
        !           210:     return false;
        !           211: }
        !           212: 
        !           213: // For each stream defines its properties:
        !           214: bool
        !           215: IOAudioBus::DefineStream(AudioStreamIndex i, int direction, UInt32 rate, IODBDMAChannelRegisters *base)
        !           216: {
        !           217:     if ((ioAudioStreamsDMA != NULL) && (i < numDMAStreams) && (base != NULL)) {
        !           218:         ioAudioStreamsDMA[i].fIOBaseDMA = base;
        !           219: 
        !           220:         // The stream direction is "hardwired" so that ecah channel
        !           221:         // can go in one direction. 
        !           222:         if (direction == kInput) {
        !           223:             ioAudioStreamsDMA[i].fDmaCmd = kdbdmaInputMore;
        !           224:             ioAudioStreamsDMA[i].fNeedsErase = false;
        !           225:             ioAudioStreamsDMA[i].fIsInput = true;
        !           226:         }
        !           227:         else {
        !           228:             ioAudioStreamsDMA[i].fDmaCmd = kdbdmaOutputMore;
        !           229:             ioAudioStreamsDMA[i].fNeedsErase = true;
        !           230:             ioAudioStreamsDMA[i].fIsInput = false;
        !           231:         }
        !           232:         ioAudioStreamsDMA[i].fSampleRate = rate;
        !           233: 
        !           234: #ifdef DEBUGMODE
        !           235:         IOLog("IOAudioBus::DefineStream(%d, %s, %ld, 0x%08lx)\n",i, (direction == kInput ? "kInput" : "kOutput"),rate, (UInt32)base);
        !           236: #endif
        !           237:     }
        !           238:     
        !           239:     return false;
        !           240: }
        !           241: 
        !           242: // Returns the first stream in the given direction after the given
        !           243: // index. (this is useful if we have to handle more than one stream
        !           244: // for input and output). (afterIndex is inclusive)
        !           245: 
        !           246: AudioStreamIndex
        !           247: IOAudioBus::firstStreamAfter(int inDirection, AudioStreamIndex afterIndex)
        !           248: {
        !           249:     if ((ioAudioStreamsDMA != NULL) && (afterIndex < numDMAStreams)) {
        !           250:         for (;afterIndex < numDMAStreams; afterIndex++) {
        !           251:             if ((inDirection == kInput) && (ioAudioStreamsDMA[afterIndex].fIsInput))
        !           252:                 return (afterIndex);
        !           253:             else if ((inDirection == kOutput) && (!ioAudioStreamsDMA[afterIndex].fIsInput))
        !           254:                 return (afterIndex);
        !           255:         }
        !           256:     }
        !           257: 
        !           258:     // We did not find a stream with the wanted properties
        !           259:     return (kInvalidStreamIndex);
        !           260: }
        !           261: 
        !           262: OSDictionary*
        !           263: IOAudioBus::getStreamProperties(AudioStreamIndex i)
        !           264: {
        !           265:     OSDictionary *dict = NULL;
        !           266:     OSString *errorString = NULL;
        !           267: 
        !           268:     if ((ioAudioStreamsDMA != NULL) && (i < numDMAStreams))
        !           269:         if (ioAudioStreamsDMA[i].fIOBaseDMA != NULL) {
        !           270: 
        !           271:             ioAudioStreamsDMA[i].streamProperty = (char*)IOMalloc(128);
        !           272:             if (ioAudioStreamsDMA[i].streamProperty != NULL) {
        !           273:                 // Depending from the direction of the stream this builds the property
        !           274:                 // string:
        !           275:                 if (ioAudioStreamsDMA[i].fIsInput) {
        !           276:                     sprintf(ioAudioStreamsDMA[i].streamProperty, "{'In'=%d:8;'Out'=%d:8;'Channels'=%d:8;'Rate'=%ld:32;}",
        !           277:                             (UInt8)1, (UInt8)0, (UInt8)2,
        !           278:                             ioAudioStreamsDMA[i].fSampleRate);
        !           279:                 }
        !           280:                 else{
        !           281:                     sprintf(ioAudioStreamsDMA[i].streamProperty, "{'In'=%d:8;'Out'=%d:8;'Channels'=%d:8;'Rate'=%ld:32;}",
        !           282:                             (UInt8)0, (UInt8)1, (UInt8)2,
        !           283:                             ioAudioStreamsDMA[i].fSampleRate);
        !           284:                 }
        !           285: 
        !           286:                 dict = OSDynamicCast(OSDictionary, OSUnserialize(ioAudioStreamsDMA[i].streamProperty, &errorString));
        !           287:             }
        !           288:         }
        !           289:             else
        !           290:                 IOLog("IOAudioBus::getStreamProperties: bad index %d\n", i);
        !           291: 
        !           292:     if (dict == NULL) {
        !           293:         if (errorString != NULL) {
        !           294:             IOLog("IOAudioBus::getStreamProperties %s (\"%s\")\n", errorString->getCStringNoCopy(), ioAudioStreamsDMA[i].streamProperty);
        !           295:             errorString->release();
        !           296:         }
        !           297:     }
        !           298: 
        !           299:     return dict;
        !           300: }
        !           301: 
        !           302: /*
        !           303:  * Map stream data for caller.
        !           304:  */
        !           305: 
        !           306: IOAudioStream *
        !           307: IOAudioBus::createAudioStream(AudioStreamIndex index)
        !           308: {
        !           309:     assert(index < numDMAStreams);
        !           310:     IOAudioStream * stream = super::createAudioStream(index);
        !           311:     return stream;
        !           312: }
        !           313: 
        !           314: int IOAudioBus::probeStreams()
        !           315: {
        !           316:     return numDMAStreams;
        !           317: }
        !           318: 
        !           319: IOAudioStreamStatus * IOAudioBus::startStream(AudioStreamIndex index)
        !           320: {
        !           321:     assert(index < numDMAStreams);
        !           322: 
        !           323:     int numBlocks, bufSize, i, cmdSize;
        !           324:     u_int32_t cmdPhys, bufPhys, seqPhys, offset;
        !           325:     IOAudioStreamStatus *status;
        !           326:     char *bufs;
        !           327:     bool doInterrupt = false;
        !           328: 
        !           329:     // Calculate size and allocate dbdma command area, sample buffer and shared status.
        !           330:     numBlocks = fBufMax/fBlockSize;
        !           331:     bufSize = fBlockSize * numBlocks;
        !           332:     cmdSize = (numBlocks * 2 + 1) * sizeof(IODBDMADescriptor);
        !           333:     IODBDMADescriptor *cmds = (IODBDMADescriptor *)IOMallocAligned(cmdSize, 4);
        !           334:     bufs = (char *)IOMallocAligned(round_page(bufSize), PAGE_SIZE);
        !           335: 
        !           336:     // This makes sure we get an entire page for the status buffer
        !           337:     // to prevent the problem of other memory being allocated
        !           338:     // in the same page that we're sharing read-only with user space.
        !           339:     // Since we don't need an entire page for each status struct,
        !           340:     // we could keep track of how much of the page that we've used and
        !           341:     // assign chunks of it for each stream...
        !           342: 
        !           343:     status = (IOAudioStreamStatus *)IOMallocAligned(round_page(sizeof(IOAudioStreamStatus)), PAGE_SIZE);
        !           344: 
        !           345:     // Everything after this check should always succeed.
        !           346:     if(!cmds || !bufs || !status)
        !           347:         return NULL;
        !           348: 
        !           349:     bzero(bufs, bufSize);
        !           350: 
        !           351:     // get physical addresses of everything for the DBDMA controller.
        !           352:     seqPhys = pmap_extract(kernel_pmap, (vm_address_t) &(status->fCurrentBlock));
        !           353:     cmdPhys = pmap_extract(kernel_pmap, (vm_address_t) cmds);
        !           354:     bufPhys = pmap_extract(kernel_pmap, (vm_address_t) bufs);
        !           355:     offset = 0;
        !           356:     
        !           357:     // The address of the stop command:
        !           358:     u_int32_t cmdStopPys = pmap_extract(kernel_pmap, (vm_address_t) (&cmds[numBlocks * 2]));
        !           359: 
        !           360:     for(i=0; i<numBlocks; i++) {
        !           361:         u_int32_t cmdDest;
        !           362: 
        !           363:         if(offset >= PAGE_SIZE) {
        !           364:             bufPhys = pmap_extract(kernel_pmap, (vm_address_t) (bufs + i*fBlockSize));
        !           365:             offset = 0;
        !           366:         }
        !           367: 
        !           368:         // Need a DBDMA branch if the next command is on a different page or
        !           369:         // if we have to loop back to the first DBDMA command.
        !           370:         if(i == numBlocks-1) {
        !           371:             cmdDest = cmdPhys;
        !           372:             doInterrupt = true;
        !           373:         } else if( ((2*(i+1)*sizeof(IODBDMADescriptor)) % PAGE_SIZE) == 0)
        !           374:             cmdDest = pmap_extract(kernel_pmap, (vm_address_t) (cmds+2*(i+1)));
        !           375:         else
        !           376:             cmdDest = 0;
        !           377: 
        !           378:         IOMakeDBDMADescriptorDep( &cmds[2*i],
        !           379:                                         kdbdmaStoreQuad,
        !           380:                                         kdbdmaKeyStream0,
        !           381:                                         kdbdmaIntNever,
        !           382:                                         kdbdmaBranchNever,
        !           383:                                         kdbdmaWaitNever,
        !           384:                                         sizeof(u_int32_t),
        !           385:                                         seqPhys,
        !           386:                                         OSReadLittleInt32(&i, 0)  );
        !           387:         if(cmdDest) {
        !           388:             IOMakeDBDMADescriptorDep( &cmds[2*i+1],
        !           389:                                       ioAudioStreamsDMA[index].fDmaCmd,
        !           390:                                       kdbdmaKeyStream0,
        !           391:                                       doInterrupt ? kdbdmaIntAlways : kdbdmaIntNever,
        !           392:                                       kdbdmaBranchAlways,
        !           393:                                       kdbdmaWaitNever,
        !           394:                                       fBlockSize,
        !           395:                                       bufPhys+offset,
        !           396:                                       cmdDest);
        !           397:         }
        !           398:         else {
        !           399:            IOMakeDBDMADescriptorDep(  &cmds[2*i+1],
        !           400:                                     ioAudioStreamsDMA[index].fDmaCmd,
        !           401:                                     kdbdmaKeyStream0,
        !           402:                                     kdbdmaIntNever,
        !           403:                                     kdbdmaBranchIfTrue,
        !           404:                                     kdbdmaWaitNever,
        !           405:                                     fBlockSize,
        !           406:                                     bufPhys+offset,
        !           407:                                     cmdStopPys);
        !           408: 
        !           409:         }
        !           410:         offset += fBlockSize;
        !           411:     }
        !           412:     
        !           413:     // Add a STOP:
        !           414:     IOMakeDBDMADescriptor(  &cmds[2*i],
        !           415:                         kdbdmaStop,
        !           416:                         kdbdmaKeyStream0,
        !           417:                         kdbdmaIntNever,
        !           418:                         kdbdmaBranchNever,
        !           419:                         kdbdmaWaitNever,
        !           420:                         0,
        !           421:                         NULL);
        !           422:     
        !           423:     ioAudioStreamsDMA[index].fSharedStatus = status;
        !           424:     ioAudioStreamsDMA[index].fCmds = cmds;
        !           425:     ioAudioStreamsDMA[index].fCmdSize = cmdSize;
        !           426:     ioAudioStreamsDMA[index].fSampleBuffer = (int16_t *)bufs;
        !           427:     status->fVersion = 1;
        !           428:     status->fErases = ioAudioStreamsDMA[index].fNeedsErase;
        !           429:     status->fRunning = 0;
        !           430:     status->fConnections = 0;
        !           431: 
        !           432:     status->fBufSize = bufSize;
        !           433:     status->fBlockSize = fBlockSize;
        !           434:     status->fNumBlocks = numBlocks;
        !           435:     status->fSampleSize = 2;
        !           436:     status->fChannels = 2;
        !           437:     status->fDataRate = ioAudioStreamsDMA[index].fSampleRate * status->fSampleSize * status->fChannels;
        !           438:     status->fCurrentBlock = 0;
        !           439:     status->fEraseHeadBlock = 0;
        !           440:     status->fCurrentLoopCount = 0;
        !           441:     status->fMixBufferInUse = false;
        !           442: 
        !           443: #ifdef DEBUGMODE
        !           444:     IOLog("DMA commands at 0x%x, %d blocks, seq at 0x%x\n", cmds, numBlocks, seqVirt);
        !           445:     IOLog("Block size %d, total size %d\n", fBlockSize, bufSize);
        !           446: #endif
        !           447: 
        !           448:     flush_dcache((vm_offset_t) cmds, cmdSize, false );
        !           449: 
        !           450:     clock_get_uptime(&status->fLastLoopTime);
        !           451: 
        !           452:     IOSetDBDMAChannelControl( ioAudioStreamsDMA[index].fIOBaseDMA, IOClearDBDMAChannelControlBits(kdbdmaS0));
        !           453:     IOSetDBDMABranchSelect( ioAudioStreamsDMA[index].fIOBaseDMA, IOSetDBDMAChannelControlBits(kdbdmaS0));
        !           454:     IODBDMAStart( ioAudioStreamsDMA[index].fIOBaseDMA, cmdPhys );
        !           455: 
        !           456:     return status;
        !           457: }
        !           458: 
        !           459: void IOAudioBus::stopStream(AudioStreamIndex index)
        !           460: {
        !           461:     IOFilterInterruptEventSource *interruptEventSource;
        !           462:     UInt8 attemptsToStop = 100;
        !           463: 
        !           464:     assert(!ioAudioStreamsDMA[index].fSharedStatus->fRunning);
        !           465: 
        !           466:     if (index == kAudioDMAOutputStream) {
        !           467:         interruptEventSource = fTxInterruptSource;
        !           468:     } else {   // index == kAudioDMAInputStream
        !           469:         interruptEventSource = fRxInterruptSource;
        !           470:     }
        !           471:     interruptEventSource->disable();
        !           472: 
        !           473:     IOSetDBDMAChannelControl( ioAudioStreamsDMA[index].fIOBaseDMA, IOSetDBDMAChannelControlBits(kdbdmaS0));
        !           474:     while ((IOGetDBDMAChannelStatus(ioAudioStreamsDMA[index].fIOBaseDMA) & kdbdmaActive ) && (attemptsToStop--)) {
        !           475:         eieio();
        !           476:         IOSleep(10);
        !           477:     }
        !           478: 
        !           479:     IODBDMAStop( ioAudioStreamsDMA[index].fIOBaseDMA );
        !           480:     IODBDMAReset( ioAudioStreamsDMA[index].fIOBaseDMA );
        !           481: 
        !           482:     IOFreeAligned(ioAudioStreamsDMA[index].fCmds, ioAudioStreamsDMA[index].fCmdSize);
        !           483:     IOFreeAligned(ioAudioStreamsDMA[index].fSampleBuffer, round_page(ioAudioStreamsDMA[index].fSharedStatus->fBufSize));
        !           484:     IOFreeAligned(ioAudioStreamsDMA[index].fSharedStatus, round_page(sizeof(IOAudioStreamStatus)));
        !           485: 
        !           486:     ioAudioStreamsDMA[index].fCmds = NULL;
        !           487:     ioAudioStreamsDMA[index].fSampleBuffer = NULL;
        !           488:     ioAudioStreamsDMA[index].fSharedStatus = NULL;
        !           489: 
        !           490:     interruptEventSource->enable();
        !           491: }
        !           492: 
        !           493: void IOAudioBus::pauseStream(AudioStreamIndex index)
        !           494: {
        !           495:     assert(index < numDMAStreams);
        !           496:     IODBDMAPause( ioAudioStreamsDMA[index].fIOBaseDMA );
        !           497: }
        !           498: 
        !           499: void IOAudioBus::resumeStream(AudioStreamIndex index)
        !           500: {
        !           501:     assert(index < numDMAStreams);
        !           502: 
        !           503:     IODBDMAContinue( ioAudioStreamsDMA[index].fIOBaseDMA );
        !           504: }
        !           505: 
        !           506: IOAudioStreamStatus * IOAudioBus::getSharedStatus(AudioStreamIndex index)
        !           507: {
        !           508:     assert(index < numDMAStreams);
        !           509:     return ioAudioStreamsDMA[index].fSharedStatus;
        !           510: }
        !           511: 
        !           512: void * IOAudioBus::getSampleBuffer(AudioStreamIndex index)
        !           513: {
        !           514:     assert(index < numDMAStreams);
        !           515:     return ioAudioStreamsDMA[index].fSampleBuffer;
        !           516: }
        !           517: 
        !           518: #endif // __ppc__

unix.superglobalmegacorp.com

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