void AREngine::CreateControls(UInt32 inNumberChannels) { for(UInt32 theChannelID = 0; theChannelID <= inNumberChannels; ++theChannelID) { IOAudioControl* theControl; IOAudioSelectorControl* theSelectorControl; char theChannelName[32]; if(theChannelID > 0) { snprintf(theChannelName, 32, "Channel %lu", theChannelID); } else { strncpy(theChannelName, kIOAudioControlChannelNameAll, 32); } // clock source selector if(theChannelID == 0) { theSelectorControl = IOAudioSelectorControl::create(0, theChannelID, theChannelName, 0, kIOAudioSelectorControlSubTypeClockSource, kIOAudioControlUsageInput); if(theSelectorControl != NULL) { theSelectorControl->addAvailableSelection(0, "Internal"); theSelectorControl->addAvailableSelection(1, "External 1"); theSelectorControl->addAvailableSelection(2, "External 2"); theSelectorControl->addAvailableSelection(3, "External 3"); theSelectorControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theSelectorControl); theSelectorControl->release(); theSelectorControl = NULL; } } // output volume theControl = IOAudioLevelControl::createVolumeControl(65535, 0, 65535, (-22 << 16) + (32768), 0, theChannelID, theChannelName, 0, kIOAudioControlUsageOutput); if(theControl != NULL) { theControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theControl); theControl->release(); theControl = NULL; } // output mute theControl = IOAudioToggleControl::createMuteControl(false, theChannelID, theChannelName, 0, kIOAudioControlUsageOutput); if(theControl != NULL) { theControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theControl); theControl->release(); theControl = NULL; } // output solo if(theChannelID != 0) { theControl = IOAudioToggleControl::create(false, theChannelID, theChannelName, 0, kIOAudioToggleControlSubTypeSolo, kIOAudioControlUsageOutput); if(theControl != NULL) { theControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theControl); theControl->release(); theControl = NULL; } } // output data source if(theChannelID != 0) { theSelectorControl = IOAudioSelectorControl::create(0, theChannelID, theChannelName, 0, kIOAudioSelectorControlSubTypeOutput, kIOAudioControlUsageOutput); if(theSelectorControl != NULL) { theSelectorControl->addAvailableSelection(0, "Source 1"); theSelectorControl->addAvailableSelection(1, "Source 2"); theSelectorControl->addAvailableSelection(2, "Source 3"); theSelectorControl->addAvailableSelection(3, "Source 4"); theSelectorControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theSelectorControl); theSelectorControl->release(); theSelectorControl = NULL; } } // output line level if(theChannelID != 0) { theSelectorControl = IOAudioSelectorControl::create(kIOAudioSelectorControlSubTypeChannelLevelMinus10dBV, theChannelID, theChannelName, 0, kIOAudioSelectorControlSubTypeChannelNominalLineLevel, kIOAudioControlUsageOutput); if(theSelectorControl != NULL) { theSelectorControl->addAvailableSelection(kIOAudioSelectorControlSubTypeChannelLevelPlus4dBu, "+4dBu"); theSelectorControl->addAvailableSelection(kIOAudioSelectorControlSubTypeChannelLevelMinus10dBV, "-10dBV"); theSelectorControl->addAvailableSelection(kIOAudioSelectorControlSubTypeChannelLevelMinus20dBV, "-20dBV"); theSelectorControl->addAvailableSelection(kIOAudioSelectorControlSubTypeChannelLevelMicLevel, "Mic"); theSelectorControl->addAvailableSelection(kIOAudioSelectorControlSubTypeChannelLevelInstrumentLevel, "Instrument"); theSelectorControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theSelectorControl); theSelectorControl->release(); theSelectorControl = NULL; } } // input volume theControl = IOAudioLevelControl::createVolumeControl(65535, 0, 65535, (-22 << 16) + (32768), 0, theChannelID, theChannelName, 0, kIOAudioControlUsageInput); if(theControl != NULL) { theControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theControl); theControl->release(); theControl = NULL; } // input mute theControl = IOAudioToggleControl::createMuteControl(false, theChannelID, theChannelName, 0, kIOAudioControlUsageInput); if(theControl != NULL) { theControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theControl); theControl->release(); theControl = NULL; } // input solo if(theChannelID != 0) { theControl = IOAudioToggleControl::create(false, theChannelID, theChannelName, 0, kIOAudioToggleControlSubTypeSolo, kIOAudioControlUsageInput); if(theControl != NULL) { theControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theControl); theControl->release(); theControl = NULL; } } // input data source if(theChannelID != 0) { theSelectorControl = IOAudioSelectorControl::create(0, theChannelID, theChannelName, 0, kIOAudioSelectorControlSubTypeInput, kIOAudioControlUsageInput); if(theSelectorControl != NULL) { theSelectorControl->addAvailableSelection(0, "Source 1"); theSelectorControl->addAvailableSelection(1, "Source 2"); theSelectorControl->addAvailableSelection(2, "Source 3"); theSelectorControl->addAvailableSelection(3, "Source 4"); theSelectorControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theSelectorControl); theSelectorControl->release(); theSelectorControl = NULL; } } // input line level if(theChannelID != 0) { theSelectorControl = IOAudioSelectorControl::create(kIOAudioSelectorControlSubTypeChannelLevelMinus10dBV, theChannelID, theChannelName, 0, kIOAudioSelectorControlSubTypeChannelNominalLineLevel, kIOAudioControlUsageInput); if(theSelectorControl != NULL) { theSelectorControl->addAvailableSelection(kIOAudioSelectorControlSubTypeChannelLevelPlus4dBu, "+4dBu"); theSelectorControl->addAvailableSelection(kIOAudioSelectorControlSubTypeChannelLevelMinus10dBV, "-10dBV"); theSelectorControl->addAvailableSelection(kIOAudioSelectorControlSubTypeChannelLevelMinus20dBV, "-20dBV"); theSelectorControl->addAvailableSelection(kIOAudioSelectorControlSubTypeChannelLevelMicLevel, "Mic"); theSelectorControl->addAvailableSelection(kIOAudioSelectorControlSubTypeChannelLevelInstrumentLevel, "Instrument"); theSelectorControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theSelectorControl); theSelectorControl->release(); theSelectorControl = NULL; } } // play through volume theControl = IOAudioLevelControl::createVolumeControl(65535, 0, 65535, (-22 << 16) + (32768), 0, theChannelID, theChannelName, 0, kIOAudioControlUsagePassThru); if(theControl != NULL) { theControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theControl); theControl->release(); theControl = NULL; } // play through on/off theControl = IOAudioToggleControl::createMuteControl(true, theChannelID, theChannelName, 0, kIOAudioControlUsagePassThru); if(theControl != NULL) { theControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theControl); theControl->release(); theControl = NULL; } // play through solo if(theChannelID != 0) { theControl = IOAudioToggleControl::create(false, theChannelID, theChannelName, 0, kIOAudioToggleControlSubTypeSolo, kIOAudioControlUsagePassThru); if(theControl != NULL) { theControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theControl); theControl->release(); theControl = NULL; } } // play through data destination if(theChannelID != 0) { theSelectorControl = IOAudioSelectorControl::create(0, theChannelID, theChannelName, 0, kIOAudioSelectorControlSubTypeDestination, kIOAudioControlUsagePassThru); if(theSelectorControl != NULL) { theSelectorControl->addAvailableSelection(0, "Destination 1"); theSelectorControl->addAvailableSelection(1, "Destination 2"); theSelectorControl->addAvailableSelection(2, "Destination 3"); theSelectorControl->addAvailableSelection(3, "Destination 4"); theSelectorControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theSelectorControl); theSelectorControl->release(); theSelectorControl = NULL; } } // play through stereo pan if((inNumberChannels > 2) && (theChannelID != 0)) { theControl = ARStereoPanControl::create(0, -128, 0, 128, 1, 2, theChannelID, theChannelName, 0, ARStereoPanControl::kIOAudioControlSubTypeStereoPan, kIOAudioControlUsagePassThru); if(theControl != NULL) { theControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theControl); theControl->release(); theControl = NULL; } } // LFE volume if(theChannelID == 0) { theControl = IOAudioLevelControl::create(65535, 0, 65535, (-22 << 16) + (32768), 0, theChannelID, theChannelName, 0, kIOAudioLevelControlSubTypeLFEVolume, kIOAudioControlUsageOutput); if(theControl != NULL) { theControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theControl); theControl->release(); theControl = NULL; } } // LFE mute if(theChannelID == 0) { theControl = IOAudioToggleControl::create(false, theChannelID, theChannelName, 0, kIOAudioToggleControlSubTypeLFEMute, kIOAudioControlUsageOutput); if(theControl != NULL) { theControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)IntegerControlChangeHandler, this); addDefaultAudioControl(theControl); theControl->release(); theControl = NULL; } } } }
bool PNetAudioDevice::createAudioEngine () { bool res = false; IOAudioControl *ctl = 0; PNetAudioEngine *engine = new PNetAudioEngine; if (!engine || !engine->init()) goto end; // left output ctl = IOAudioLevelControl::createVolumeControl(65535, // default 0, // min 65535, // max -22 << 16 + 1 << 15, // min -22.5 dB 0, // max 0.0 dB kIOAudioControlChannelIDDefaultLeft, kIOAudioControlChannelNameLeft, 0, // output id kIOAudioControlUsageOutput); if (!ctl) goto end; ctl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)controlValueChangeHandler, this); engine->addDefaultAudioControl(ctl); ctl->release(); // right output ctl = IOAudioLevelControl::createVolumeControl(65535, 0, 65535, -22 << 16 + 1 << 15, 0, kIOAudioControlChannelIDDefaultRight, kIOAudioControlChannelNameRight, 0, kIOAudioControlUsageOutput); if (!ctl) goto end; ctl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)controlValueChangeHandler, this); engine->addDefaultAudioControl(ctl); ctl->release(); // mute output ctl = IOAudioToggleControl::createMuteControl(false, // default not mute kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlUsageOutput); if (!ctl) goto end; ctl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)controlValueChangeHandler, this); engine->addDefaultAudioControl(ctl); ctl->release(); // left input ctl = IOAudioLevelControl::createVolumeControl(65535, 0, 65535, -22 << 16 + 1 << 15, 0, kIOAudioControlChannelIDDefaultLeft, kIOAudioControlChannelNameLeft, 0, kIOAudioControlUsageInput); if (!ctl) goto end; ctl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)controlValueChangeHandler, this); engine->addDefaultAudioControl(ctl); ctl->release(); // right input ctl = IOAudioLevelControl::createVolumeControl(65535, 0, 65535, -22 << 16 + 1 << 15, 0, kIOAudioControlChannelIDDefaultRight, kIOAudioControlChannelNameRight, 0, kIOAudioControlUsageInput); if (!ctl) goto end; ctl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)controlValueChangeHandler, this); engine->addDefaultAudioControl(ctl); ctl->release(); // mute input ctl = IOAudioToggleControl::createMuteControl(false, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlUsageInput); if (!ctl) goto end; ctl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)controlValueChangeHandler, this); engine->addDefaultAudioControl(ctl); ctl->release(); activateAudioEngine(engine); res = true; end: if (engine) engine->release(); if (ctl) ctl->release(); return res; }
bool PhantomAudioEngine::createAudioStreams(IOAudioSampleRate *initialSampleRate) { bool result = false; OSNumber *number; UInt32 numStreams, streamNum; OSArray *formatArray, *sampleRateArray; UInt32 startingChannelID = 1; IOAudioControl *control; OSString *desc; OSBoolean *boolean; bool separateStreamBuffers = FALSE, separateInputBuffers = FALSE; desc = OSDynamicCast(OSString, getProperty(DESCRIPTION_KEY)); if (desc) { setDescription(desc->getCStringNoCopy()); } number = OSDynamicCast(OSNumber, getProperty(NUM_STREAMS_KEY)); if (number) { numStreams = number->unsigned32BitValue(); } else { numStreams = NUM_STREAMS; } formatArray = OSDynamicCast(OSArray, getProperty(FORMATS_KEY)); if (formatArray == NULL) { goto Done; } sampleRateArray = OSDynamicCast(OSArray, getProperty(SAMPLE_RATES_KEY)); if (sampleRateArray == NULL) { goto Done; } boolean = OSDynamicCast(OSBoolean, getProperty(SEPARATE_STREAM_BUFFERS_KEY)); if (boolean != NULL) { separateStreamBuffers = boolean->getValue(); } boolean = OSDynamicCast(OSBoolean, getProperty(SEPARATE_INPUT_BUFFERS_KEY)); if (boolean != NULL) { separateInputBuffers = boolean->getValue(); } if (separateStreamBuffers) { IOLog("PhantomAudioEngine::createAudioStreams() - Creating a separate buffer for each stream.\n"); } else { IOLog("PhantomAudioEngine::createAudioStreams() - Sharing one buffer among all streams.\n"); } if (separateInputBuffers) { IOLog("PhantomAudioEngine::createAudioStreams() - Creating separate buffers for input and output.\n"); } else { IOLog("PhantomAudioEngine::createAudioStreams() - Sharing input and output buffers.\n"); } for (streamNum = 0; streamNum < numStreams; streamNum++) { IOAudioStream *inputStream = NULL, *outputStream = NULL; UInt32 maxBitWidth = 0; UInt32 maxNumChannels = 0; OSCollectionIterator *formatIterator = NULL, *sampleRateIterator = NULL; OSDictionary *formatDict; IOAudioSampleRate sampleRate; IOAudioStreamFormat initialFormat; bool initialFormatSet; UInt32 channelID; char outputStreamName[20], inputStreamName[20]; UInt32 streamBufferSize; initialFormatSet = false; sampleRate.whole = 0; sampleRate.fraction = 0; inputStream = new IOAudioStream; if (inputStream == NULL) { goto Error; } outputStream = new IOAudioStream; if (outputStream == NULL) { goto Error; } sprintf(inputStreamName, "Input Stream #%ld", streamNum + 1); sprintf(outputStreamName, "Output Stream #%ld", streamNum + 1); if (!inputStream->initWithAudioEngine(this, kIOAudioStreamDirectionInput, startingChannelID, inputStreamName) || !outputStream->initWithAudioEngine(this, kIOAudioStreamDirectionOutput, startingChannelID, outputStreamName)) { goto Error; } formatIterator = OSCollectionIterator::withCollection(formatArray); if (!formatIterator) { goto Error; } sampleRateIterator = OSCollectionIterator::withCollection(sampleRateArray); if (!sampleRateIterator) { goto Error; } formatIterator->reset(); while (formatDict = (OSDictionary *)formatIterator->getNextObject()) { IOAudioStreamFormat format; if (OSDynamicCast(OSDictionary, formatDict) == NULL) { goto Error; } if (IOAudioStream::createFormatFromDictionary(formatDict, &format) == NULL) { goto Error; } if (!initialFormatSet) { initialFormat = format; } sampleRateIterator->reset(); while (number = (OSNumber *)sampleRateIterator->getNextObject()) { if (!OSDynamicCast(OSNumber, number)) { goto Error; } sampleRate.whole = number->unsigned32BitValue(); inputStream->addAvailableFormat(&format, &sampleRate, &sampleRate); if (format.fBitDepth == 24) { IOAudioStream::AudioIOFunction functions[2]; functions[0] = process24BitSamples; functions[1] = clip24BitSamples; //outputStream->addAvailableFormat(&format, &sampleRate, &sampleRate, functions, 2); outputStream->addAvailableFormat(&format, &sampleRate, &sampleRate, (IOAudioStream::AudioIOFunction)clip24BitSamples); if (format.fNumericRepresentation == kIOAudioStreamSampleFormatLinearPCM && format.fIsMixable == TRUE) { format.fIsMixable = FALSE; outputStream->addAvailableFormat(&format, &sampleRate, &sampleRate, (IOAudioStream::AudioIOFunction)clip24BitSamples); } } else if (format.fBitDepth == 16) { IOAudioStream::AudioIOFunction functions[2]; functions[0] = process16BitSamples; functions[1] = clip16BitSamples; //outputStream->addAvailableFormat(&format, &sampleRate, &sampleRate, functions, 2); outputStream->addAvailableFormat(&format, &sampleRate, &sampleRate, (IOAudioStream::AudioIOFunction)clip16BitSamples); if (format.fNumericRepresentation == kIOAudioStreamSampleFormatLinearPCM && format.fIsMixable == TRUE) { format.fIsMixable = FALSE; outputStream->addAvailableFormat(&format, &sampleRate, &sampleRate, (IOAudioStream::AudioIOFunction)clip24BitSamples); } } else { outputStream->addAvailableFormat(&format, &sampleRate, &sampleRate); if (format.fNumericRepresentation == kIOAudioStreamSampleFormatLinearPCM && format.fIsMixable == TRUE) { format.fIsMixable = FALSE; outputStream->addAvailableFormat(&format, &sampleRate, &sampleRate, (IOAudioStream::AudioIOFunction)clip24BitSamples); } } if (format.fNumChannels > maxNumChannels) { maxNumChannels = format.fNumChannels; } if (format.fBitWidth > maxBitWidth) { maxBitWidth = format.fBitWidth; } if (initialSampleRate->whole == 0) { initialSampleRate->whole = sampleRate.whole; } } } streamBufferSize = blockSize * numBlocks * maxNumChannels * maxBitWidth / 8; if (outputBuffer == NULL) { if (separateStreamBuffers) { outputBufferSize = streamBufferSize * numStreams; } else { outputBufferSize = streamBufferSize; } outputBuffer = (void *)IOMalloc(outputBufferSize); if (!outputBuffer) { IOLog("Error allocating output buffer - %lu bytes.\n", outputBufferSize); goto Error; } inputBufferSize = outputBufferSize; if (separateInputBuffers) { inputBuffer = (void *)IOMalloc(inputBufferSize); if (!inputBuffer) { IOLog("Error allocating input buffer - %lu bytes.\n", inputBufferSize); goto Error; } } else { inputBuffer = outputBuffer; } } inputStream->setFormat(&initialFormat); outputStream->setFormat(&initialFormat); if (separateStreamBuffers) { inputStream->setSampleBuffer(&((UInt8 *)inputBuffer)[streamBufferSize * streamNum], streamBufferSize); outputStream->setSampleBuffer(&((UInt8 *)outputBuffer)[streamBufferSize * streamNum], streamBufferSize); } else { inputStream->setSampleBuffer(inputBuffer, streamBufferSize); outputStream->setSampleBuffer(outputBuffer, streamBufferSize); } addAudioStream(inputStream); inputStream->release(); addAudioStream(outputStream); outputStream->release(); formatIterator->release(); sampleRateIterator->release(); for (channelID = startingChannelID; channelID < (startingChannelID + maxNumChannels); channelID++) { char channelName[20]; sprintf(channelName, "Channel %lu", channelID); control = IOAudioLevelControl::createVolumeControl(65535, 0, 65535, (-22 << 16) + (32768), 0, channelID, channelName, 0, kIOAudioControlUsageOutput); if (!control) { goto Error; } control->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)PhantomAudioDevice::volumeChangeHandler, audioDevice); addDefaultAudioControl(control); control->release(); control = IOAudioToggleControl::createMuteControl(false, channelID, channelName, 0, kIOAudioControlUsageOutput); if (!control) { goto Error; } control->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)PhantomAudioDevice::outputMuteChangeHandler, audioDevice); addDefaultAudioControl(control); control->release(); control = IOAudioLevelControl::createVolumeControl(65535, 0, 65535, (-22 << 16) + (32768), 0, channelID, channelName, 0, kIOAudioControlUsageInput); if (!control) { goto Error; } control->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)PhantomAudioDevice::gainChangeHandler, audioDevice); addDefaultAudioControl(control); control->release(); control = IOAudioToggleControl::createMuteControl(false, channelID, channelName, 0, kIOAudioControlUsageInput); if (!control) { goto Error; } control->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)PhantomAudioDevice::inputMuteChangeHandler, audioDevice); addDefaultAudioControl(control); control->release(); control = IOAudioToggleControl::createMuteControl(true, channelID, channelName, 0, kIOAudioControlUsagePassThru); if (!control) { goto Error; } control->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)PhantomAudioDevice::passThruChangeHandler, audioDevice); addDefaultAudioControl(control); control->release(); } startingChannelID += maxNumChannels; continue; Error: IOLog("PhantomAudioEngine[%p]::createAudioStreams() - ERROR\n", this); if (inputStream) { inputStream->release(); } if (outputStream) { outputStream->release(); } if (formatIterator) { formatIterator->release(); } if (sampleRateIterator) { sampleRateIterator->release(); } goto Done; } control = IOAudioLevelControl::createVolumeControl(65535, 0, 65535, (-22 << 16) + (32768), 0, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlUsageOutput); if (!control) { goto Done; } control->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)PhantomAudioDevice::volumeChangeHandler, audioDevice); addDefaultAudioControl(control); control->release(); control = IOAudioToggleControl::createMuteControl(false, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlUsageOutput); if (!control) { goto Done; } control->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)PhantomAudioDevice::outputMuteChangeHandler, audioDevice); addDefaultAudioControl(control); control->release(); control = IOAudioLevelControl::createVolumeControl(65535, 0, 65535, (-22 << 16) + (32768), 0, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlUsageInput); if (!control) { goto Done; } control->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)PhantomAudioDevice::gainChangeHandler, audioDevice); addDefaultAudioControl(control); control->release(); control = IOAudioToggleControl::createMuteControl(false, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlUsageInput); if (!control) { goto Done; } control->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)PhantomAudioDevice::inputMuteChangeHandler, audioDevice); addDefaultAudioControl(control); control->release(); control = IOAudioToggleControl::createMuteControl(true, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlUsagePassThru); if (!control) { goto Done; } control->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)PhantomAudioDevice::passThruChangeHandler, audioDevice); addDefaultAudioControl(control); control->release(); result = true; Done: if (!result) { IOLog("PhantomAudioEngine[%p]::createAudioStreams() - failed!\n", this); } return result; }