0

我想缓存 CAF 文件,然后在播放时将它们转换为 PCM。

例如,

char *mybuffer = malloc(mysoundsize);
FILE *f = fopen("mysound.caf", "rb");
fread(mybuffer, mysoundsize, 1, f);
fclose(f);

char *pcmBuffer = malloc(pcmsoundsize);
// Convert to PCM for playing
AudioFileReadBytes(mybuffer, false, 0, mysoundsize, &numbytes, pcmBuffer);

这样,每当播放声音时,压缩的 CAF 文件就已经加载到内存中,从而避免了磁盘访问。如何使用“AudioFileID”打开一块内存以使 AudioFileReadBytes 满意?我可以使用另一种方法吗?

4

2 回答 2

0

我自己没有这样做,但是从文档中我认为您必须使用AudioFileOpenWithCallbacks和实现从内存缓冲区读取的回调函数。

于 2012-09-05T17:39:38.503 回答
0

你可以用AudioFileStreamOpen


fileprivate var streamID: AudioFileStreamID?


public func parse(data: Data) throws {
       
        
        let streamID = self.streamID!
        let count = data.count
        _ = try data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) in
            let result = AudioFileStreamParseBytes(streamID, UInt32(count), bytes, [])
            guard result == noErr else {
               
                throw ParserError.failedToParseBytes(result)
            }
        }
    }

您可以将数据存储在内存中callback

func ParserPacketCallback(_ context: UnsafeMutableRawPointer, _ byteCount: UInt32, _ packetCount: UInt32, _ data: UnsafeRawPointer, _ packetDescriptions: Optional<UnsafeMutablePointer<AudioStreamPacketDescription>>) {
    let parser = Unmanaged<Parser>.fromOpaque(context).takeUnretainedValue()
    
    /// At this point we should definitely have a data format
    guard let dataFormat = parser.dataFormatD else {
        return
    }
    
   
    let format = dataFormat.streamDescription.pointee
    let bytesPerPacket = Int(format.mBytesPerPacket)
    for i in 0 ..< Int(packetCount) {
        let packetStart = i * bytesPerPacket
        let packetSize = bytesPerPacket
        let packetData = Data(bytes: data.advanced(by: packetStart), count: packetSize)
        parser.packetsX.append(packetData)
    }
    
}

github repo中的完整代码

于 2020-11-24T09:51:02.253 回答