来自内存块的AudioFileReadBytes,而不是文件

时间:2012-09-05 15:58:48

标签: ios caf

我希望缓存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开心吗?我可以使用另一种方法吗?

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分: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中的完整代码