0

I'd like to cache CAF files before converting them to PCM whenever they play.

For example,

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);

This way, whenever the sound plays, the compressed CAF file is already loaded into memory, avoiding disk access. How can I open a block of memory with an 'AudioFileID' to make AudioFileReadBytes happy? Is there another method I can use?

user1054922
  • 2,101
  • 2
  • 23
  • 37

2 Answers2

0

I have not done it myself, but from the documentation I would think that you have to use AudioFileOpenWithCallbacks and implement callback functions that read from your memory buffer.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
0

You can finish it with 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)
            }
        }
    }

you can store the data in memory within the 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)
    }
    
}

full code in github repo

dengST30
  • 3,643
  • 24
  • 25