Swift调用whisper C API时指针类型不匹配错误求助
解决Swift调用whisper_full时的指针转换问题
你遇到的错误本质是指针类型不匹配:
AVAudioPCMBuffer.floatChannelData的类型是UnsafePointer<UnsafeMutablePointer<Float>>?,对应C里的float**——它是一个指向「多个通道音频数据指针」的数组指针(比如立体声就是两个float*元素)。- 而
whisper_full要求的const float * samples是UnsafePointer<Float>?,对应C里的float*——指向单通道连续音频样本的起始指针。
另外你原代码还有隐藏问题:只创建了AVAudioPCMBuffer但没有将音频文件内容读取进去,即使指针转换正确也会导致处理失败。
解决方案
步骤1:确保输入音频符合Whisper要求
Whisper默认要求单通道、16kHz采样率、Float32格式的音频,所以首先要将原音频转换为该格式(如果原格式不符)。
步骤2:完整的修正代码
do { let audioFile = try AVAudioFile(forReading: fileURL) // 定义Whisper要求的目标音频格式 let targetFormat = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: 16000, channels: 1, interleaved: false)! // 初始化音频转换器 guard let converter = AVAudioConverter(from: audioFile.processingFormat, to: targetFormat) else { print("Failed to create audio converter") return } // 计算转换后的buffer容量 let targetFrameCount = UInt32(audioFile.length * targetFormat.sampleRate / audioFile.processingFormat.sampleRate) guard let audioBuffer = AVAudioPCMBuffer(pcmFormat: targetFormat, frameCapacity: targetFrameCount) else { print("Failed to create PCM buffer") return } // 执行音频转换 var conversionError: NSError? let inputBlock: AVAudioConverterInputBlock = { inNumPackets, outStatus in outStatus.pointee = .haveData return try? audioFile.read(into: audioBuffer, frameCount: inNumPackets) } converter.convert(to: audioBuffer, error: &conversionError, withInputFrom: inputBlock) if let error = conversionError { print("Audio conversion failed: \(error.localizedDescription)") return } // 获取单通道的音频样本指针 guard let channelDataArray = audioBuffer.floatChannelData, let samplePointer = channelDataArray.pointee else { print("No valid audio channel data") return } // 调用whisper_full let sampleCount = Int32(audioBuffer.frameLength) if whisper_full(ctx, wparams, samplePointer, sampleCount) != 0 { print("Failed to process audio with whisper") return } } catch { print("Failed to read audio file: \(error.localizedDescription)") }
关键指针转换说明
audioBuffer.floatChannelData是UnsafePointer<UnsafeMutablePointer<Float>>?,调用pointee可以取出数组的第一个元素——也就是单通道音频数据的UnsafeMutablePointer<Float>。- Swift会自动将
UnsafeMutablePointer<Float>转换为UnsafePointer<Float>(匹配Whisper的const float*参数要求),不需要额外强制转换。
注意事项
- 不要用
try!强制解包,改用do-catch处理错误,避免运行时崩溃。 - 必须确保输入是单通道音频,否则直接传递多通道的某一个指针会导致识别结果混乱(Whisper无法处理多通道交错数据)。
内容的提问来源于stack exchange,提问作者Vimy
相关产品推荐
相关产品推荐

