Crashlytics указал, что я получаю довольно много сбоев, происходящих в функции, которая использует каркас CoreAudio для изменения скорости потоковой передачи звука с помощью плагина AudioUnit. Я не могу воспроизвести аварию самостоятельно, однако она затрагивает 20% моих пользователей.
Я не очень опытен в программировании на низком уровне C или Objective C, поэтому я не знаю, что я делаю неправильно. Может быть, кто-то с большим знанием C, чем я, может довольно легко указать на проблему. Когда дело доходит до неуправляемого кода, я не совсем понимаю проблемы управления памятью. Я подозреваю, что это может быть проблемой. Я вызываю фреймворк C, используя код Swift, используя метод заголовочного файла get bride.
Это функция, где происходит сбой. Я пытаюсь установить параметр 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% моих пользователей. Когда он работает, код позволяет конечному пользователю перемещать ползунок, который замедляет скорость прослушиваемого мультимедиа.