AVAudioConverter with AVAudioConverterInputBlock stutters audio after processing
For anybody finding this, the actual underlying cause is the incorrect use of AVAudioConverterInputBlock
. The destination buffer capacity doesn't matter as long as it is large enough, however the block will be called repeatedly until the destination buffer is filled.
If your source buffer contains ABC
, it will fill up the destination with ABCABCABC...
. Then, if you pipe it to realtime playback, the chunks are getting cut off randomly to fit the playback timing, resulting in this weird crackle.
The actual solution is to properly set AVAudioConverterInputStatus
to .noDataNow
once the buffer is submitted to the converter. Note that returning .endOfStream
will lock up the converter object forever.
var gotData = false
self.converter.convert(to: convertedBuffer, error: nil, withInputFrom: { (_, outStatus) -> AVAudioBuffer? in
if gotData {
outStatus.pointee = .noDataNow
return nil
}
gotData = true
outStatus.pointee = .haveData
return inputBuffer
})
AVAudioConverter is broken in iOS 10
So, it turned out that the outBuffer frameLength has to be set to the frameCapacity. As default the length is 0 and is apparently treated differently on iOS 10
Related Topics
Switch to Match Multiple Cases from Optionsettype
Performseguewithidentifier Not Working If Called from Viewdidload
Difference Between Sort and Sortinplace in Swift 2
Ambiguous Reference to Member 'Buildblock()'
Dependency Injection in View Controller
What's The Difference Between [String] VS. [(String)]
Localize iOS 14 Dynamic Widget Configuration
Xcode 13.1 Bug Editing Dependency as Local
How to Get Textfields from Static Cells in UItableviewcontroller? Swift
Extend All Number Types in Swift
How to Find Realm File Location of a MAC App
Destructuring Tuple of Tuple in Closure
Enum of String Type Vs Struct with Static Constant
How to Detect If The User Was Deleted from Firebase Auth
Type 'Int' Does Not Conform to Protocol 'Booleantype'