Annotation of XNU/iokit/Families/IOAudio/IOAudioController.cpp, revision 1.1.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:  * IOAudioController.cpp
                     26:  *
                     27:  * HISTORY
                     28:  *
                     29:  */
                     30: 
                     31: #include <IOKit/assert.h>
                     32: 
                     33: #include <IOKit/IOLib.h>
                     34: #include <IOKit/IOKitKeys.h>
                     35: #include <IOKit/IOSyncer.h>
                     36: #include <IOKit/IOWorkLoop.h>
                     37: #include <IOKit/IOCommandQueue.h>
                     38: #include <IOKit/IOTimerEventSource.h>
                     39: #include <IOKit/IOMemoryDescriptor.h>
                     40: #include <IOKit/audio/IOAudioController.h>
                     41: 
                     42: #include <libkern/c++/OSSet.h>
                     43: 
                     44: const IORegistryPlane * IOAudioController::gIOAudioPlane = NULL;
                     45: const OSSymbol * IOAudioController::gValSym = NULL;
                     46: const OSSymbol * IOAudioController::gTypeSym = NULL;
                     47: const OSSymbol * IOAudioController::gInputsSym = NULL;
                     48: const OSSymbol * IOAudioController::gControlsSym = NULL;
                     49: const OSSymbol * IOAudioController::gJackSym = NULL;
                     50: const OSSymbol * IOAudioController::gSpeakerSym = NULL;
                     51: const OSSymbol * IOAudioController::gHeadphonesSym = NULL;
                     52: const OSSymbol * IOAudioController::gLineOutSym = NULL;
                     53: const OSSymbol * IOAudioController::gMuteSym = NULL;
                     54: const OSSymbol * IOAudioController::gIdSym = NULL;
                     55: const OSSymbol * IOAudioController::gMasterSym = NULL;
                     56: 
                     57: #define TIMER_INTS_PER_BUF     4
                     58: #define MAX_POLL_INTERVAL_SEC  60
                     59: 
                     60: //************************************************************************
                     61: // Implementation of protocol clas.
                     62: //************************************************************************
                     63: OSDefineMetaClass(  IOAudio, IOService )
                     64: OSDefineAbstractStructors(  IOAudio, IOService )
                     65: 
                     66: //************************************************************************
                     67: // Begin implementation of IOAudioController class.
                     68: //************************************************************************
                     69: 
                     70: #undef super
                     71: #define super IOAudio
                     72: 
                     73: OSDefineMetaClass(  IOAudioController, IOAudio )
                     74: OSDefineAbstractStructors(  IOAudioController, IOAudio )
                     75: 
                     76: bool IOAudioController::init(OSDictionary *properties)
                     77: {
                     78:     if (!super::init(properties)) {
                     79:         return false;
                     80:     }
                     81: 
                     82:     fMasterVolumeComponents = OSSet::withCapacity(1);
                     83:     fNumStreamsInUse = 0;
                     84: 
                     85:     nanoseconds_to_absolutetime((UInt64)(MAX_POLL_INTERVAL_SEC) * (UInt64)NSEC_PER_SEC, &fMaxPollInterval);
                     86: 
                     87:     return true;
                     88: }
                     89: 
                     90: bool IOAudioController::start( IOService *provider )
                     91: {
                     92:     if (!super::start(provider))
                     93:         return false;
                     94: 
                     95:     fDevice = provider;
                     96: 
                     97:     return true;
                     98: }
                     99: 
                    100: void IOAudioController::execAndSignal(OSObject * obj, void *field0, void *field1, void *field2, void *field3)
                    101: {
                    102:     IOAudioController *me = (IOAudioController *)obj;
                    103:     IOSyncer *syncer = (IOSyncer *) field0;
                    104:     IOAudioCmd cmd = (IOAudioCmd) (int) field1;
                    105: 
                    106:     me->execCommand(cmd, field2, field3);
                    107: 
                    108:     if(syncer)
                    109:         syncer->signal();
                    110: }
                    111: 
                    112: void IOAudioController::execCommand(IOAudioCmd cmd, void *field2, void *field3)
                    113: {
                    114:     switch (cmd) {
                    115:         case kConnect:
                    116:         getMap((AudioStreamIndex)field2, (IOAudioStreamMap *)field3);
                    117:         break;
                    118: 
                    119:         case kDetach:
                    120:         releaseMap((AudioStreamIndex)field2);
                    121:         break;
                    122: 
                    123:         case kSetFlow:
                    124:         setFlow((AudioStreamIndex)field2, (bool)field3);
                    125:         break;
                    126: 
                    127:         case kProbeStreams:
                    128:             int numStreams, i;
                    129:             numStreams = probeStreams();
                    130:             fStreams = OSArray::withCapacity(numStreams);
                    131:             if(fStreams) {
                    132:                 for(i=0; i<numStreams; i++) {
                    133:                     IOAudioStream *stream;
                    134:                     stream = createAudioStream(i);
                    135:                     if(stream) {
                    136:                         fStreams->setObject(i, stream);
                    137:                         stream->attach(this);
                    138:                         stream->registerService();
                    139:                     }
                    140:                 }
                    141:                 CreateAudioTopology(fQueue);
                    142:             }
                    143:             // Start the timer event source, if necessary (eg polling Awacs inputs)
                    144:             AbsoluteTime pollInterval, wantTick;
                    145: 
                    146:             pollInterval = fMaxPollInterval;
                    147:             calculateTickInterval(&pollInterval);
                    148:             if(CMP_ABSOLUTETIME(&pollInterval, &fMaxPollInterval) < 0) {
                    149:                 clock_get_uptime(&wantTick);
                    150:                 ADD_ABSOLUTETIME(&wantTick, &pollInterval);
                    151:                 fNextTick = wantTick;
                    152:                 fTimer->wakeAtTime(fNextTick);
                    153:                 fTimerInUse = true;
                    154:                 fWorkLoop->addEventSource(fTimer);
                    155:             }
                    156: 
                    157:        break;
                    158: 
                    159:     case kSetVal:
                    160:         SetControl((UInt16)field2, (UInt16)field3);
                    161:         break;
                    162: 
                    163:     case kFlush:
                    164:         flushStream((AudioStreamIndex)field2, (IOAudioStreamPosition *)field3);
                    165:         break;
                    166: 
                    167:     case kAllocMixBuffer:
                    168:         if (*(void **)field3 == NULL) {
                    169:             *(void **)field3 = allocateMixBuffer((AudioStreamIndex)field2);
                    170:         }
                    171:         break;
                    172:         
                    173:     default:
                    174:         IOLog("Unexpected command %d in IOAudioController::execCommand!\n", cmd);
                    175: 
                    176:     }
                    177: }
                    178: 
                    179: void IOAudioController::clockTick(OSObject * obj, IOTimerEventSource *timer)
                    180: {
                    181:     ((IOAudioController *)obj)->DoClockTick(timer);
                    182: }
                    183: 
                    184: void IOAudioController::DoClockTick(IOTimerEventSource *timer)
                    185: {
                    186:     AudioStreamIndex stream;
                    187:     AudioStreamIndex end;
                    188: 
                    189:     if(fStreams)
                    190:         end = fStreams->getCount();
                    191:     else
                    192:         end = 0;
                    193: 
                    194:     for(stream = 0; stream < end; stream++) {
                    195:         IOAudioStreamStatus *status = getSharedStatus(stream);
                    196: 
                    197:         if(status && status->fRunning) {
                    198:             AbsoluteTime now;
                    199: 
                    200:             clock_get_uptime(&now);
                    201: 
                    202:             // Do buffer clearing before potentially removing the buffer!
                    203:             if(status->fErases) {
                    204:                 UInt32 currentBlock;
                    205: 
                    206:                 // Clear buffer behind DMA back to last erase point
                    207:                 char *buf = (char *)getSampleBuffer(stream);
                    208:                 char *mixBuf = (char *)getMixBuffer(stream);
                    209: 
                    210:                 currentBlock = status->fCurrentBlock;
                    211: 
                    212:                 if(currentBlock < status->fEraseHeadBlock) {
                    213:                     if (buf) {
                    214:                         bzero(buf, currentBlock * status->fBlockSize);
                    215:                         bzero(buf + (status->fEraseHeadBlock * status->fBlockSize),
                    216:                               status->fBufSize - (status->fEraseHeadBlock * status->fBlockSize));
                    217:                     }
                    218:                     if (mixBuf) {
                    219:                         bzero(mixBuf, currentBlock * status->fBlockSize / status->fSampleSize * MIX_BUFFER_SAMPLE_SIZE);
                    220:                         bzero(mixBuf + (status->fEraseHeadBlock * status->fBlockSize / status->fSampleSize * MIX_BUFFER_SAMPLE_SIZE),
                    221:                               (status->fBufSize / status->fSampleSize * MIX_BUFFER_SAMPLE_SIZE) - (status->fEraseHeadBlock * status->fBlockSize / status->fSampleSize * MIX_BUFFER_SAMPLE_SIZE));
                    222:                     }
                    223:                 }
                    224:                 else {
                    225:                     if (buf) {
                    226:                         bzero(buf + (status->fEraseHeadBlock * status->fBlockSize),
                    227:                               (currentBlock - status->fEraseHeadBlock) * status->fBlockSize);
                    228:                     }
                    229:                     if (mixBuf) {
                    230:                         bzero(mixBuf + (status->fEraseHeadBlock * status->fBlockSize / status->fSampleSize * MIX_BUFFER_SAMPLE_SIZE),
                    231:                               (currentBlock - status->fEraseHeadBlock) * status->fBlockSize  / status->fSampleSize * MIX_BUFFER_SAMPLE_SIZE);
                    232:                     }
                    233:                 }
                    234: 
                    235:                 status->fEraseHeadBlock = currentBlock;
                    236:             }
                    237:             if(status->fConnections == 0) {
                    238:                 UInt32 currentBlock, currentLoopCount;
                    239: 
                    240:                 currentLoopCount = status->fCurrentLoopCount;
                    241:                 currentBlock = status->fCurrentBlock;
                    242:                 
                    243:                 // See if its time to stop (we have completed flushing output buffers)
                    244:                 if ((currentLoopCount > status->fFlushEnd.fLoopCount)
                    245:                  || ((currentLoopCount == status->fFlushEnd.fLoopCount)
                    246:                   && (currentBlock > status->fFlushEnd.fBlock))) {
                    247:                     AbsoluteTime pollInterval;
                    248:                     status->fRunning = 0;
                    249:                     stopStream(stream);
                    250:                     fNumStreamsInUse--;
                    251:                     if (fNumStreamsInUse == 0) {
                    252:                         pollInterval = fMaxPollInterval;
                    253:                         calculateTickInterval(&pollInterval);
                    254:                         if(CMP_ABSOLUTETIME(&pollInterval, &fMaxPollInterval) < 0) {
                    255:                             fWorkLoop->removeEventSource(fTimer);
                    256:                             fTimerInUse = false;
                    257:                         }
                    258:                     }
                    259:                 }
                    260:             }
                    261:         }
                    262:     }
                    263: 
                    264:     if(fTimerInUse) {
                    265:         fTimer->setTimeout(fTickPeriod);
                    266:     }
                    267: }
                    268: 
                    269: //------------------------------------------------------------------------
                    270: /*
                    271:  * startWorkLoop()
                    272:  *
                    273:  * Drivers call this after initializing their hardware
                    274:  * We ask the device here how many initial audio channels it has, create appropriate nubs,
                    275:  * and then start the work loop running
                    276:  */
                    277: void IOAudioController::startWorkLoop()
                    278: {
                    279:     if(NULL == gIOAudioPlane) {
                    280:          gIOAudioPlane = IORegistryEntry::makePlane( kIOAudioPlane );
                    281:     }
                    282: 
                    283:     if(NULL == gValSym) {
                    284:         gValSym = OSSymbol::withCString("Val");
                    285:         gInputsSym = OSSymbol::withCString("Inputs");
                    286:         gControlsSym = OSSymbol::withCString("Controls");
                    287:         gJackSym = OSSymbol::withCString("Jack");
                    288:         gSpeakerSym = OSSymbol::withCString("Speaker");
                    289:         gHeadphonesSym = OSSymbol::withCString("Headphones");
                    290:         gLineOutSym = OSSymbol::withCString("LineOut");
                    291:         gTypeSym = OSSymbol::withCString("Type");
                    292:        gMuteSym = OSSymbol::withCString("Mute");
                    293:        gIdSym = OSSymbol::withCString("Id");
                    294:         gMasterSym = OSSymbol::withCString("Master");
                    295:     }
                    296: 
                    297:     fTimer = IOTimerEventSource::timerEventSource(this, &clockTick);
                    298:     fQueue = IOCommandQueue::commandQueue(this, &execAndSignal);
                    299: 
                    300:     fWorkLoop = createWorkLoop();
                    301:     fWorkLoop->addEventSource(fQueue);
                    302: 
                    303:     fQueue->enqueueCommand(true, 0, (void *)kProbeStreams, 0);
                    304: 
                    305:     registerService();
                    306: }
                    307: 
                    308: IOWorkLoop *IOAudioController::getWorkLoop() const
                    309: {
                    310:     return fWorkLoop;
                    311: }
                    312: 
                    313: IOWorkLoop * IOAudioController::createWorkLoop()
                    314: {
                    315:     IOWorkLoop *loop;
                    316: 
                    317:     loop = new IOWorkLoop();
                    318:     if(loop && !loop->init()) {
                    319:        loop->release();
                    320:        loop = NULL;
                    321:     }
                    322:     return loop;
                    323: }
                    324: 
                    325: IOAudioStream *IOAudioController::createAudioStream(AudioStreamIndex index)
                    326: {
                    327:     OSDictionary *props = getStreamProperties(index);
                    328:     IOAudioStreamImpl *stream;
                    329:     SInt32 isOut;
                    330:     IOReturn err;
                    331: 
                    332:     if(!props)
                    333:        return NULL;
                    334: 
                    335:     stream = new IOAudioStreamImpl;
                    336:     if(stream)
                    337:        stream->initWithPropsIndexQueue(props, index, fQueue);
                    338: 
                    339:     props->release();  // Finished with this now.
                    340: 
                    341:     /*
                    342:      * Output streams are the start of a sound chain, so put
                    343:      * them at the root of the IOAudio plane.
                    344:      */
                    345:     err = stream->isOutput(&isOut);
                    346:     if(!err && isOut)
                    347:         stream->attachToParent(getRegistryRoot(), gIOAudioPlane);
                    348: 
                    349:     return stream;
                    350: }
                    351: 
                    352: IOAudioComponentImpl *
                    353: IOAudioController::buildComponentAndAttach(IORegistryEntry *parent,
                    354:                        IORegistryEntry *child, const char *serialProps,
                    355:                                                        IOCommandQueue *queue)
                    356: {
                    357:     OSDictionary *dict;
                    358:     OSString *errorString;
                    359:     IOAudioComponentImpl * aComp;
                    360:     OSNumber *masterVal;
                    361: 
                    362:     aComp = new IOAudioComponentImpl;
                    363:     if(!aComp)
                    364:         return NULL;
                    365: 
                    366:     dict = OSDynamicCast(OSDictionary, OSUnserialize(serialProps, &errorString));
                    367:     if (!dict && errorString) {
                    368:        IOLog("%s\n", errorString->getCStringNoCopy());
                    369:        errorString->release();
                    370:     }
                    371:     if(!aComp->initWithStuff(this, dict, queue)) {
                    372:         aComp->release();
                    373:         return NULL;
                    374:     }
                    375: 
                    376:     if(!parent)
                    377:         parent = getRegistryRoot();
                    378: 
                    379:     aComp->attachToParent(parent, gIOAudioPlane);
                    380:     
                    381:     if(child)  
                    382:         child->attachToParent(aComp, gIOAudioPlane);
                    383: 
                    384:     masterVal = (OSNumber *)dict->getObject(gMasterSym);
                    385:     if ((masterVal != NULL) && (masterVal->unsigned32BitValue() != 0)) {
                    386:         fMasterVolumeComponents->setObject(aComp);
                    387:     }
                    388:         
                    389:     return aComp;
                    390: }
                    391: 
                    392: void IOAudioController::AttachComponents(IORegistryEntry *parent,
                    393:                        IORegistryEntry *child)
                    394: {
                    395:     child->attachToParent(parent, gIOAudioPlane);
                    396: }
                    397: 
                    398: 
                    399: void IOAudioController::free()
                    400: {
                    401:     if (fMasterVolumeComponents)
                    402:         fMasterVolumeComponents->release();
                    403:     if(fWorkLoop)
                    404:         fWorkLoop->release();
                    405:     if(fQueue)
                    406:         fQueue->release();
                    407:     if(fTimer)
                    408:         fTimer->release();
                    409:     if(fStreams)
                    410:        fStreams->release();
                    411:     super::free();
                    412: }
                    413: 
                    414: void IOAudioController::calculateTickInterval(AbsoluteTime *tickInterval)
                    415: {
                    416:     AudioStreamIndex stream;
                    417:     AudioStreamIndex end;
                    418: 
                    419:     if(fStreams)
                    420:         end = fStreams->getCount();
                    421:     else
                    422:         end = 0;
                    423: 
                    424:     for(stream = 0; stream < end; stream++) {
                    425:         IOAudioStreamStatus *status = getSharedStatus(stream);
                    426:         if(status) {
                    427:             AbsoluteTime pollInterval;
                    428: 
                    429:             nanoseconds_to_absolutetime(((UInt64)NSEC_PER_SEC * (UInt64)status->fBufSize / (UInt64)status->fDataRate / (UInt64)TIMER_INTS_PER_BUF), &pollInterval);
                    430: 
                    431:             if (CMP_ABSOLUTETIME(&pollInterval, tickInterval) < 0) {
                    432:                 *tickInterval = pollInterval;
                    433:             }
                    434:         }
                    435:     }
                    436: 
                    437:     // Save the minimum period
                    438:     fTickPeriod = *tickInterval;
                    439: }
                    440: 
                    441: /*
                    442:  * Map stream data for caller.
                    443:  */
                    444: void IOAudioController::getMap(AudioStreamIndex index, IOAudioStreamMap *map)
                    445: {
                    446:     IOAudioStreamStatus * status = getSharedStatus(index);
                    447: 
                    448:     if(!status) {
                    449:         fNumStreamsInUse++;
                    450:         status = startStream(index);
                    451:         if(status) {
                    452:             AbsoluteTime pollInterval, wantTick;
                    453: 
                    454:             //map->fMixBuffer = (void *)IOMallocAligned(round_page(status->fBufSize / status->fSampleSize * MIX_BUFFER_SAMPLE_SIZE), PAGE_SIZE);
                    455: 
                    456:             clock_get_uptime(&wantTick);
                    457:             if(status->fErases) {
                    458:                 status->fEraseHeadBlock = 0;
                    459:             }
                    460: 
                    461:             status->fFlushEnd.fBlock = 0;
                    462:             status->fFlushEnd.fLoopCount = 0;
                    463:             status->fMixBufferInUse = false;
                    464: 
                    465:             pollInterval = fMaxPollInterval;
                    466:             calculateTickInterval(&pollInterval);
                    467: 
                    468:             ADD_ABSOLUTETIME(&wantTick, &pollInterval);
                    469: 
                    470:             if(!fTimerInUse || (CMP_ABSOLUTETIME(&wantTick, &fNextTick) < 0)) {
                    471:                 fNextTick = wantTick;
                    472:                 fTimer->wakeAtTime(fNextTick);
                    473:             }
                    474:             if(!fTimerInUse) {
                    475:                 fTimerInUse = true;
                    476:                 fWorkLoop->addEventSource(fTimer);
                    477:             }
                    478:             setFlow(index, true);
                    479:         }
                    480:         else {
                    481:             map->fStatus = NULL;
                    482:             map->fSampleBuffer = NULL;
                    483:             //map->fMixBuffer = NULL;
                    484:             fNumStreamsInUse--;
                    485:             return;
                    486:         }
                    487:     }
                    488:     status->fConnections = 1;
                    489:     map->fStatus = status;
                    490:     map->fSampleBuffer = getSampleBuffer(index);
                    491: }
                    492: 
                    493: void IOAudioController::releaseMap(AudioStreamIndex index)
                    494: {
                    495:     IOAudioStreamStatus * status = getSharedStatus(index);
                    496: 
                    497:     if (status) {
                    498:         status->fConnections = 0;
                    499:     }
                    500: }
                    501: 
                    502: void IOAudioController::setFlow(AudioStreamIndex index, bool flowing)
                    503: {
                    504:     IOAudioStreamStatus * status = getSharedStatus(index);
                    505:     if(status) {
                    506:         if(flowing) {
                    507:             if(status->fRunning++ == 0) {
                    508:                 fNumStreamsInUse++;
                    509:                 resumeStream(index);
                    510:             }
                    511:         }
                    512:         else {
                    513:             if(--status->fRunning == 0) {
                    514:                 pauseStream(index);
                    515:                 fNumStreamsInUse--;
                    516:             }
                    517:         }
                    518:     }
                    519: }
                    520: 
                    521: void IOAudioController::flushStream(AudioStreamIndex index, IOAudioStreamPosition *endingPosition)
                    522: {
                    523:     IOAudioStreamStatus *status = getSharedStatus(index);
                    524: 
                    525:     if (status) {
                    526:         if ((endingPosition->fLoopCount > status->fFlushEnd.fLoopCount) || ((endingPosition->fLoopCount == status->fFlushEnd.fLoopCount) && (endingPosition->fBlock > status->fFlushEnd.fBlock))) {
                    527:             status->fFlushEnd = *endingPosition;
                    528:         }
                    529:     }
                    530: }
                    531: 
                    532: void *IOAudioController::allocateMixBuffer(AudioStreamIndex index)
                    533: {
                    534:     IOAudioStreamStatus * status = getSharedStatus(index);
                    535:     void *mixBuffer = NULL;
                    536: 
                    537:     if(status) {
                    538:         mixBuffer = (void *)IOMallocAligned(round_page(status->fBufSize / status->fSampleSize * MIX_BUFFER_SAMPLE_SIZE), PAGE_SIZE);
                    539:         bzero (mixBuffer, round_page(status->fBufSize / status->fSampleSize * MIX_BUFFER_SAMPLE_SIZE));
                    540:         status->fMixBufferInUse = true;
                    541:     }
                    542: 
                    543:     return mixBuffer;
                    544: }
                    545: void *IOAudioController::getMixBuffer(AudioStreamIndex index)
                    546: {
                    547:     void *mixBuffer = NULL;
                    548:     if (fStreams) {
                    549:         IOAudioStreamImpl *stream = (IOAudioStreamImpl *)fStreams->getObject(index);
                    550:         if (stream) {
                    551:             if (stream->getMixBuffer(&mixBuffer) != kIOReturnSuccess) {
                    552:                 mixBuffer = NULL;
                    553:             }
                    554:         }
                    555:     }
                    556: 
                    557:     return mixBuffer;
                    558: }
                    559: 
                    560: void IOAudioController::setMasterComponentsProperties(OSDictionary *properties)
                    561: {
                    562:     if (properties) {
                    563:         OSCollectionIterator *iter;
                    564: 
                    565:         iter = OSCollectionIterator::withCollection(fMasterVolumeComponents);
                    566:         if (iter) {
                    567:             IOAudioComponent *component;
                    568: 
                    569:             while ((component = OSDynamicCast(IOAudioComponent, iter->getNextObject())) != NULL) {
                    570:                 component->setProperties(properties);
                    571:             }
                    572:         }
                    573:     }
                    574: }
                    575: void IOAudioController::setMasterVolumeLeft(UInt16 newMasterVolumeLeft)
                    576: {
                    577:     OSDictionary *controlDict;
                    578:     OSString *errorString;
                    579:     char controlDictString[51]; // strlen(formatString) + 5 (max chars in 16-bit int) + 1 (terminator)
                    580: 
                    581:     sprintf (controlDictString, "{'Controls'={'VolumeLeft'={'Val'=%d:16;};};};", newMasterVolumeLeft);
                    582:     controlDict = OSDynamicCast(OSDictionary, OSUnserialize(controlDictString, &errorString));
                    583: 
                    584:     if (controlDict) {
                    585:         setMasterComponentsProperties(controlDict);
                    586:         controlDict->release();
                    587:     } else if (errorString) {
                    588:         IOLog("IOAudioController: %s\n", errorString->getCStringNoCopy());
                    589:         errorString->release();
                    590:     }
                    591: }
                    592: 
                    593: void IOAudioController::setMasterVolumeRight(UInt16 newMasterVolumeRight)
                    594: {
                    595:     OSDictionary *controlDict;
                    596:     OSString *errorString;
                    597:     char controlDictString[52]; // strlen(formatString) + 5 (max chars in 16-bit int) + 1 (terminator)
                    598: 
                    599:     // FIXME - We really should scale to min/max in this control...
                    600:     sprintf (controlDictString, "{'Controls'={'VolumeRight'={'Val'=%d:16;};};};", newMasterVolumeRight);
                    601:     controlDict = OSDynamicCast(OSDictionary, OSUnserialize(controlDictString, &errorString));
                    602: 
                    603:     if (controlDict) {
                    604:         setMasterComponentsProperties(controlDict);
                    605:         controlDict->release();
                    606:     } else if (errorString) {
                    607:         IOLog("IOAudioController: %s\n", errorString->getCStringNoCopy());
                    608:         errorString->release();
                    609:     }
                    610: }
                    611: 
                    612: void IOAudioController::setMasterMute(bool newMasterMute)
                    613: {
                    614:     OSDictionary *controlDict;
                    615:     OSString *errorString;
                    616:     char controlDictString[43]; // strlen(formatString) + 1 (single digit) + 1 (terminator)
                    617: 
                    618:     sprintf (controlDictString, "{'Controls'={'MuteAll'={'Val'=%d:8;};};};", newMasterMute ? 1 : 0);
                    619:     controlDict = OSDynamicCast(OSDictionary, OSUnserialize(controlDictString, &errorString));
                    620: 
                    621:     if (controlDict) {
                    622:         setMasterComponentsProperties(controlDict);
                    623:         controlDict->release();
                    624:     } else if (errorString) {
                    625:         IOLog("IOAudioController: %s\n", errorString->getCStringNoCopy());
                    626:         errorString->release();
                    627:     }
                    628: }

unix.superglobalmegacorp.com

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