- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
此方法处理来自 AVAudioEngine 输入节点上 installTap 的回调。我已确认我正在获取单声道 float32/48000hz 缓冲区数据,我想将其转换为单声道 int16/16000hz。
var converter: AVAudioConverter? = nil
var convertBuffer: AVAudioPCMBuffer? = nil
let targetFormat = AVAudioFormat(commonFormat: AVAudioCommonFormat.pcmFormatInt16, sampleRate: 16000, channels: 1, interleaved: false)
func recordCallback(buffer: AVAudioPCMBuffer, time: AVAudioTime) {
if converter == nil {
convertBuffer = AVAudioPCMBuffer(pcmFormat: targetFormat, frameCapacity: buffer.frameCapacity)
convertBuffer?.frameLength = convertBuffer!.frameCapacity
converter = AVAudioConverter(from: buffer.format, to: convertBuffer!.format)
converter?.sampleRateConverterAlgorithm = AVSampleRateConverterAlgorithm_Normal
converter?.sampleRateConverterQuality = .max
}
guard let convertBuffer = convertBuffer else { return }
log.info("Converter: \(self.converter!)")
log.info("Converter buffer: \(self.convertBuffer!)")
log.info("Converter buffer format: \(self.convertBuffer!.format)")
log.info("Source buffer: \(buffer)")
log.info("Source buffer format: \(buffer.format)")
do {
try converter!.convert(to: convertBuffer, from: buffer)
} catch let error {
log.error("Conversion error: \(error)")
observer?.onError(EngineRecordTaskError.ConversionError(error: error))
return
}
…
}
这给了我有用的错误:
Conversion error: Error Domain=NSOSStatusErrorDomain Code=-50 "(null)"
如果我使用替代方法 .convert(to:error:withInputFrom:),它不会填充 NSError,也不会填充目标缓冲区 - 静默失败。
记录的信息:
Converter: <AVAudioConverter: 0x17001cd40>
Converter buffer: <AVAudioPCMBuffer@0x17021e310: 9600/9600 bytes>
Converter buffer format: <AVAudioFormat 0x17448ba90: 1 ch, 16000 Hz, Int16>
Source buffer: <AVAudioPCMBuffer@0x17021e1b0: 19200/19200 bytes>
Source buffer format: <AVAudioFormat 0x174480910: 1 ch, 48000 Hz, Float32>
Conversion error: Error Domain=NSOSStatusErrorDomain Code=-50 "(null)"
来自调试器的附加信息:
(lldb) po buffer.frameCapacity
4800
(lldb) po convertBuffer.frameCapacity
4800
(lldb) po buffer.frameLength
4800
(lldb) po convertBuffer.frameLength
4800
这是我尝试过的替代转换代码:
var conversionError: NSError? = nil
converter!.convert(to: convertBuffer, error: &conversionError, withInputFrom: { (_, _) in
return buffer
})
if let conversionError = conversionError {
log.error("Conversion error: \(conversionError)")
observer?.onError(EngineRecordTaskError.ConversionError(error: conversionError))
return
}
最佳答案
来自头文件中convert
的讨论:
The output buffer's frameCapacity should be at least at large as the inputBuffer's frameLength. If the conversion involves a codec or sample rate conversion, you instead must use convertToBuffer:error:withInputFromBlock:.
您正在从 48kHz 转换为 16kHz,这算作速率转换,因此您必须使用 convertToBuffer
:
let inputBlock: AVAudioConverterInputBlock = { inNumPackets, outStatus in
outStatus.pointee = AVAudioConverterInputStatus.haveData
return buffer
}
var error: NSError? = nil
let status: AVAudioConverterOutputStatus = converter!.convert(to: convertBuffer, error: &error, withInputFrom: inputBlock)
// TODO: check status
附注在 apple 创建新的 NSError
code'n'strings 一定非常昂贵 - 他们的预算无法支付“速率转换需要 convertToBuffer”消息。
关于ios - AVAudioConverter float32/48khz -> int16/16khz 转换失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42660859/
我需要将用 2 个音频 channel 录制的 .wav 文件转换为只有 1 个 channel 的 .wav 文件,并将位深度从 32 减少到 16。我一直在尝试使用 AVAudioConverte
AVAudioConverter 在 iOS 10 中似乎坏了。该代码在 iOS 9 中运行,现在 错误域=NSOSStatusErrorDomain 代码=-50“(空)” 无论使用什么音频格式,都
我遇到了 AVAudioConverter 的问题.我正在尝试转换 AVAudioPCMBuffers至 AAC . 这是我用于转换的函数,取自“What's new in Core Audio” s
我正在尝试将音频缓冲区转换为不同的格式,并且我正在使用 AVAudioConverter。当您具有相同的采样率并且您不需要使用 AVAudioConverterInputBlock 时,AVAudio
此方法处理来自 AVAudioEngine 输入节点上 installTap 的回调。我已确认我正在获取单声道 float32/48000hz 缓冲区数据,我想将其转换为单声道 int16/16000
如何在 Swift 上使用 AVAudioConverter、AVAudioCompressedBuffer 和 AVAudioPCMBuffer 将 AAC 转换为 PCM? 在 WWDC 2015
我是一名优秀的程序员,十分优秀!