Objective-c - How to serialize audio file into small packets that can be played?

后端 未结 3 768
生来不讨喜
生来不讨喜 2020-12-14 04:56

So, I would like to get a sound file and convert it in packets, and send it to another computer. I would like that the other computer be able to play the packets as they arr

3条回答
  •  再見小時候
    2020-12-14 05:37

    It seems you are solving wrong task, because AVAudioPlayer capable play only whole audiofile. You should use Audio Queue Service from AudioToolbox framework instead, to play audio on packet-by-packet basis. In fact you need not divide audiofile into real sound packets, you can use any data block like in your own example above, but then you should read received data chuncks using Audiofile Service or Audio File Stream Services functions (from AudioToolbox) and feed them to audioqueue buffers.

    If you nevertheless want to divide audiofile into sound packets, you can easily do it with Audiofile Service functions. Audiofile consist of header where its properties like number of packets, samplerate, number of channels etc. are stored, and raw sound data.

    Use AudioFileOpenURL to open audiofile and take all its properties with AudioFileGetProperty function. Basicaly you need only kAudioFilePropertyDataFormat and kAudioFilePropertyAudioDataPacketCount properties:

    AudioFileID  fileID;    // the identifier for the audio file
    CFURLRef     fileURL = ...; // file URL
    AudioStreamBasicDescription format; // structure containing audio header info
        UInt64  packetsCount;
    
    AudioFileOpenURL(fileURL, 
        0x01, //fsRdPerm,                       // read only
        0, //no hint
        &fileID
    );
    
    UInt32 sizeOfPlaybackFormatASBDStruct = sizeof format;
    AudioFileGetProperty (
        fileID, 
        kAudioFilePropertyDataFormat,
        &sizeOfPlaybackFormatASBDStruct,
        &format
    );
    
    propertySize = sizeof(packetsCount);
    AudioFileGetProperty(fileID, kAudioFilePropertyAudioDataPacketCount, &propertySize, &packetsCount);
    

    Then you can take any range of audiopackets data with:

       OSStatus AudioFileReadPackets (
           AudioFileID                  inAudioFile,
           Boolean                      inUseCache,
           UInt32                       *outNumBytes,
           AudioStreamPacketDescription *outPacketDescriptions,
           SInt64                       inStartingPacket,
           UInt32                       *ioNumPackets,
           void                         *outBuffer
        );
    

提交回复
热议问题