Crashlytics已经表明,在使用CoreAudio框架通过AudioUnit插件更改流音频速度的函数中,发生了很多崩溃。我无法自己复制崩溃,但是它正在影响20%的用户。
在这方面,我不太精通低级C编程或目标C,所以我真的不知道自己在做什么错。也许比我自己更懂C的人可以很容易地指出问题。对于非托管代码,我不太了解内存管理问题。我怀疑这可能是问题所在。我正在使用使用获取新娘头文件技术的Swift代码调用C框架。
这是发生崩溃的功能。我试图设置AudioUnit的参数,该参数是流媒体的AudioGraph的一部分。同样,它在80%的时间内都有效。
var speedNode: AUNode = 0
var speedUnit: AudioUnit? // could this be the problem? I call speedUnit before it is initiated? How I suspect it is initiated be the core audio code since I am not doing it. Maybe I should check it's not nil before calling it.
func changeRate(rate: Double) {
self.playbackRate = rate
CheckError(AudioUnitSetParameter(speedUnit!, kTimePitchParam_Rate, kAudioUnitScope_Global, 0, AudioUnitParameterValue(self.playbackRate), UInt32(Double(MemoryLayout<Double>.size))), "Error")
}
这是我将AudioGraph连接到媒体流输出的替代功能的代码。
override func attempt(toDeliverAudioFrames audioFrames: UnsafeRawPointer!, ofCount frameCount: Int, streamDescription audioDescription: AudioStreamBasicDescription) -> Int {
return super.attempt(toDeliverAudioFrames: audioFrames, ofCount: frameCount, streamDescription: audioDescription)
}
override func connectOutputBus(_ sourceOutputBusNumber: UInt32, ofNode sourceNode: AUNode, toInputBus destinationInputBusNumber: UInt32, ofNode destinationNode: AUNode, in graph: AUGraph!) throws {
var speedCd: AudioComponentDescription =
AudioComponentDescription(componentType: kAudioUnitType_FormatConverter, componentSubType: kAudioUnitSubType_NewTimePitch, componentManufacturer: kAudioUnitManufacturer_Apple, componentFlags: 0, componentFlagsMask: 0)
CheckError(AUGraphAddNode(graph, &speedCd, &speedNode), "AUGraphAddNode speed failed")
CheckError(AUGraphNodeInfo(graph,
speedNode,
nil,
&speedUnit), "AUGraphNodeInfo failed")
// CheckError(AudioUnitSetParameter(speedUnit!, kTimePitchParam_Rate, kAudioUnitScope_Global, 0, AudioUnitParameterValue(self.playbackRate), UInt32(Double(MemoryLayout<Double>.size))), "whatup")
CheckError(AUGraphConnectNodeInput(graph, sourceNode, sourceOutputBusNumber, speedNode, 0), "connect fail")
CheckError(AUGraphConnectNodeInput(graph, speedNode, sourceOutputBusNumber, destinationNode, 0), "connect fail")
}
override func disposeOfCustomNodes(in graph: AUGraph!) {
// if != nil {
// AudioUnitUninitialize(pbUnit!)
// }
//
// pbUnit = nil
//
// AUGraphRemoveNode(graph, pbNode)
// pbNode = 0
}
虽然我不太了解代码,但我能够将其一起破解,并且它对80%的用户都有效。代码运行时,允许最终用户移动滑块,从而降低他们正在收听的媒体的速度。