I managed to build and use simple audio graphs with Core Audio and Swift but I can't find the right way to use the Matrix Mixer. When I try to set the number of elements, it looks like the program goes in an infinite loop which ends up using lots of memory and never come back.
This is possibly not quite the same as what discussed here.
The simplest possible code to reproduce the behaviour is this:
var graph = AUGraph()
var filePlayerAU = AudioUnit()
var mixerAU = AudioUnit()
var outputAU = AudioUnit()
NewAUGraph(&graph)
// Add file player node
var filePlayerNode = AUNode()
var filePlayerDesc = AudioComponentDescription(componentType: OSType(kAudioUnitType_Generator),
componentSubType: OSType(kAudioUnitSubType_AudioFilePlayer),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0, componentFlagsMask: 0)
CheckResult("Adding file player node", status: AUGraphAddNode(graph, &filePlayerDesc, &filePlayerNode))
// Add matrix mixer node
var mixerNode = AUNode()
var mixerDesc = AudioComponentDescription(componentType: OSType(kAudioUnitType_Mixer),
componentSubType: OSType(kAudioUnitSubType_MatrixMixer),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0, componentFlagsMask: 0)
CheckResult("Adding matrix mixer node", status: AUGraphAddNode(graph, &mixerDesc, &mixerNode))
// Add output node
var outputNode = AUNode()
var outputDesc = AudioComponentDescription(componentType: OSType(kAudioUnitType_Output),
componentSubType: OSType(kAudioUnitSubType_RemoteIO),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0, componentFlagsMask: 0)
CheckResult("Adding output node", status: AUGraphAddNode(graph, &outputDesc, &outputNode))
// Graph must be opened before we can get node info, i.e. the Audio Units
CheckResult("Opening graph", status: AUGraphOpen(graph))
CheckResult("Getting file player node info", status: AUGraphNodeInfo(graph, filePlayerNode, nil, &filePlayerAU))
CheckResult("Getting mixer node info", status: AUGraphNodeInfo(graph, mixerNode, nil, &mixerAU))
CheckResult("Getting output node info", status: AUGraphNodeInfo(graph, outputNode, nil, &outputAU))
var outputBusNumber: AudioUnitParameterValue = 1
var propSize = UInt32(sizeof(AudioUnitParameterValue))
// Setting default parameters for the mixer unit
CheckResult("Setting mixer output elements count", status: AudioUnitSetProperty(mixerAU, AudioUnitPropertyID(kAudioUnitProperty_ElementCount), OSType(kAudioUnitScope_Output), 0, &outputBusNumber, propSize))
When executing this last line, the program hangs and the memory usage goes to the roof. I tried connecting the graph first but it doesn't make any difference. Any hint on how this should be done?
The CheckResult function is available here:
func CheckResult(msg:String, status:OSStatus) {
print(msg + ": ")
switch(Int(status)) {
case 0:
println("OK")
// AudioToolbox
case kAUGraphErr_NodeNotFound:
println("Error:kAUGraphErr_NodeNotFound")
case kAUGraphErr_OutputNodeErr:
println("Error:kAUGraphErr_OutputNodeErr")
case kAUGraphErr_InvalidConnection:
println("Error:kAUGraphErr_InvalidConnection")
case kAUGraphErr_CannotDoInCurrentContext:
println("Error:kAUGraphErr_CannotDoInCurrentContext")
case kAUGraphErr_InvalidAudioUnit:
println("Error:kAUGraphErr_InvalidAudioUnit")
case kAudioToolboxErr_InvalidSequenceType :
println("kAudioToolboxErr_InvalidSequenceType")
case kAudioToolboxErr_TrackIndexError :
println("kAudioToolboxErr_TrackIndexError")
case kAudioToolboxErr_TrackNotFound :
println("kAudioToolboxErr_TrackNotFound")
case kAudioToolboxErr_EndOfTrack :
println("kAudioToolboxErr_EndOfTrack")
case kAudioToolboxErr_StartOfTrack :
println("kAudioToolboxErr_StartOfTrack")
case kAudioToolboxErr_IllegalTrackDestination :
println("kAudioToolboxErr_IllegalTrackDestination")
case kAudioToolboxErr_NoSequence :
println("kAudioToolboxErr_NoSequence")
case kAudioToolboxErr_InvalidEventType :
println("kAudioToolboxErr_InvalidEventType")
case kAudioToolboxErr_InvalidPlayerState :
println("kAudioToolboxErr_InvalidPlayerState")
case kAudioUnitErr_InvalidProperty :
println("kAudioUnitErr_InvalidProperty")
case kAudioUnitErr_InvalidParameter :
println("kAudioUnitErr_InvalidParameter")
case kAudioUnitErr_InvalidElement :
println("kAudioUnitErr_InvalidElement")
case kAudioUnitErr_NoConnection :
println("kAudioUnitErr_NoConnection")
case kAudioUnitErr_FailedInitialization :
println("kAudioUnitErr_FailedInitialization")
case kAudioUnitErr_TooManyFramesToProcess :
println("kAudioUnitErr_TooManyFramesToProcess")
case kAudioUnitErr_InvalidFile :
println("kAudioUnitErr_InvalidFile")
case kAudioUnitErr_FormatNotSupported :
println("kAudioUnitErr_FormatNotSupported")
case kAudioUnitErr_Uninitialized :
println("kAudioUnitErr_Uninitialized")
case kAudioUnitErr_InvalidScope :
println("kAudioUnitErr_InvalidScope")
case kAudioUnitErr_PropertyNotWritable :
println("kAudioUnitErr_PropertyNotWritable")
case kAudioUnitErr_InvalidPropertyValue :
println("kAudioUnitErr_InvalidPropertyValue")
case kAudioUnitErr_PropertyNotInUse :
println("kAudioUnitErr_PropertyNotInUse")
case kAudioUnitErr_Initialized :
println("kAudioUnitErr_Initialized")
case kAudioUnitErr_InvalidOfflineRender :
println("kAudioUnitErr_InvalidOfflineRender")
case kAudioUnitErr_Unauthorized :
println("kAudioUnitErr_Unauthorized")
case kAudioFileUnspecifiedError:
println("kAudioFileUnspecifiedError")
case kAudioFileUnsupportedFileTypeError:
println("kAudioFileUnsupportedFileTypeError")
case kAudioFileUnsupportedDataFormatError:
println("kAudioFileUnsupportedDataFormatError")
case kAudioFileUnsupportedPropertyError:
println("kAudioFileUnsupportedPropertyError")
case kAudioFileBadPropertySizeError:
println("kAudioFileBadPropertySizeError")
case kAudioFilePermissionsError:
println("kAudioFilePermissionsError")
case kAudioFileNotOptimizedError:
println("kAudioFileNotOptimizedError")
case kAudioFileInvalidChunkError:
println("kAudioFileInvalidChunkError")
case kAudioFileDoesNotAllow64BitDataSizeError:
println("kAudioFileDoesNotAllow64BitDataSizeError")
case kAudioFileInvalidPacketOffsetError:
println("kAudioFileInvalidPacketOffsetError")
case kAudioFileInvalidFileError:
println("kAudioFileInvalidFileError")
case kAudioFileOperationNotSupportedError:
println("kAudioFileOperationNotSupportedError")
case kAudioFileNotOpenError:
println("kAudioFileNotOpenError")
case kAudioFileEndOfFileError:
println("kAudioFileEndOfFileError")
case kAudioFilePositionError:
println("kAudioFilePositionError")
case kAudioFileFileNotFoundError:
println("kAudioFileFileNotFoundError")
default:
println("huh? (OSStatus: \(status))")
}
}