Audio Unit和ExtendedAudioFile播放音频

2021-08-12  本文已影响0人  辉辉岁月

前言

相关文章:
Audio Unit播放PCM文件
Audio Unit录音(播放伴奏+耳返)
Audio Unit播放aac/m4a/mp3等文件

前文介绍了AudioUnit的录音/播放功能,也介绍了通过AudioConvert进行音频的转换,但是AudioConvert的API使用起来较为麻烦,除了需要调用AudioFileGetProperty获取许多信息之外,还要调用AudioConverterFillComplexBuffer进行ConvertBuffer的填充,并在其数据输入回调中调用AudioFileReadPacketData,且要考虑AudioStreamPacketDescription的赋值。
本文尝试使用更为简单的方法 Extended Audio File Services
Extended Audio File Services是high-level的API,提供音频文件的读/写,是Audio File Services 和 Audio Converter Services 的结合,在AudioFile和AudioConvert的基础上提供统一的接口进行读写操作。

正文

概念储备

CF_ENUM(ExtAudioFilePropertyID) {
    kExtAudioFileProperty_FileDataFormat        = 'ffmt',   // AudioStreamBasicDescription
    kExtAudioFileProperty_FileChannelLayout     = 'fclo',   // AudioChannelLayout
    kExtAudioFileProperty_ClientDataFormat      = 'cfmt',   // AudioStreamBasicDescription
    kExtAudioFileProperty_ClientChannelLayout   = 'cclo',   // AudioChannelLayout
    kExtAudioFileProperty_CodecManufacturer     = 'cman',   // UInt32

    // read-only:
    kExtAudioFileProperty_AudioConverter        = 'acnv',   // AudioConverterRef
    kExtAudioFileProperty_AudioFile             = 'afil',   // AudioFileID
    kExtAudioFileProperty_FileMaxPacketSize     = 'fmps',   // UInt32
    kExtAudioFileProperty_ClientMaxPacketSize   = 'cmps',   // UInt32
    kExtAudioFileProperty_FileLengthFrames      = '#frm',   // SInt64

    // writable:
    kExtAudioFileProperty_ConverterConfig       = 'accf',   // CFPropertyListRef
    kExtAudioFileProperty_IOBufferSizeBytes     = 'iobs',   // UInt32
    kExtAudioFileProperty_IOBuffer              = 'iobf',   // void *
    kExtAudioFileProperty_PacketTable           = 'xpti'    // AudioFilePacketTableInfo
};

介绍其中常用的属性:

具体细节

1、获取的音频frame帧数不正常

如果在未设置好输入输出格式前,就通过kExtAudioFileProperty_FileLengthFrames获取的总frame数,此时获取的frame是不准确的,并且会导致后续的操作错误。
正确的做法是先设置好 kExtAudioFileProperty_ClientDataFormat属性的值,再获取总的frame数。

2、播放进度不准确

播放的进度=当前播放的帧数/音频文件的总帧数;
进度不准确问题是因为获取的是frame数,之前在计算已播放的帧数时没有正确的把读取的字节长度除以输出格式的mBytesPerFrame。
当前已播放的帧数 += 读取的字节长度 / ASBD.mBytesPerFrame。

总结

ExtendedAudioFile相对Audio File Services 和 Audio Converter Services ,API调用非常简单和明确,并且不需要去处理AudioStreamPacketDescription,在实际开发中逻辑更为清晰。
demo 的代码在这里,可以看到ExtendedAudioFile具体使用方式。

上一篇下一篇

猜你喜欢

热点阅读