Core Audio Matrix Mixer 在设置输入或输出元素数量时卡住并滥用内存
Core Audio Matrix Mixer gets stuck and abuses memory when setting number of input or output elements
我设法通过 Core Audio 和 Swift 构建并使用了简单的音频图,但我找不到使用矩阵混音器的正确方法。
当我尝试设置元素的数量时,程序似乎进入了一个无限循环,最终使用了大量内存并且永远不会回来。
这可能与 discussed here.
不太一样
重现该行为的最简单代码如下:
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))
执行最后一行时,程序挂起,内存使用率飙升。我先尝试连接图表,但没有任何区别。关于应该如何完成的任何提示?
CheckResult 函数在此处可用:
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))")
}
}
事实证明问题出在 AudioUnitParameterValue 的使用上,它应该只与 AudioUnitSetParameter 一起使用。
一旦将类型更改为 UInt32,问题就消失了。
非常感谢 Apple 开发论坛中的 OOper 指出了我的愚蠢错误。
我设法通过 Core Audio 和 Swift 构建并使用了简单的音频图,但我找不到使用矩阵混音器的正确方法。 当我尝试设置元素的数量时,程序似乎进入了一个无限循环,最终使用了大量内存并且永远不会回来。
这可能与 discussed here.
不太一样重现该行为的最简单代码如下:
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))
执行最后一行时,程序挂起,内存使用率飙升。我先尝试连接图表,但没有任何区别。关于应该如何完成的任何提示?
CheckResult 函数在此处可用:
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))")
}
}
事实证明问题出在 AudioUnitParameterValue 的使用上,它应该只与 AudioUnitSetParameter 一起使用。
一旦将类型更改为 UInt32,问题就消失了。
非常感谢 Apple 开发论坛中的 OOper 指出了我的愚蠢错误。