苹果ExtAudioFileRead与客户端数据格式(mp3)是否真正同步

时间:2018-07-19 10:12:17

标签: core-audio audio-converter extaudiofileread

与包含客户端数据格式(即mp3)的ExtAudioFileRef配合使用时,ExtAudioFileRead是否真的同步?

在文档中说:

    /*!
    @function   ExtAudioFileRead

    @abstract   Perform a synchronous sequential read.

    @param      inExtAudioFile
                    The extended audio file object.
    @param      ioNumberFrames
                    On entry, ioNumberFrames is the number of frames to be read from the file.
                    On exit, it is the number of frames actually read. A number of factors may
                    cause a fewer number of frames to be read, including the supplied buffers
                    not being large enough, and internal optimizations. If 0 frames are
                    returned, however, this indicates that end-of-file was reached.
    @param      ioData
                    Buffer(s) into which the audio data is read.
    @result     An OSStatus error code.

    @discussion
                If the file has a client data format, then the audio data from the file is
                translated from the file data format to the client format, via the
                ExtAudioFile's internal AudioConverter.

                (Note that the use of sequential reads/writes means that an ExtAudioFile must
                not be read on multiple threads; clients wishing to do this should use the
                lower-level AudioFile API set).
*/

extern OSStatus
ExtAudioFileRead(           ExtAudioFileRef         inExtAudioFile,
                            UInt32 *                ioNumberFrames,
                            AudioBufferList *       ioData)

但是有时在调用ExtAudioFileRead之后立即销毁ioData时,我有时会有一个奇怪的堆栈:

0   0x0000000184a5cea8 in CrashIfClientProvidedBogusAudioBufferList ()
1   0x000000018493f270 in AudioConverterConvertComplexBuffer ()
2   0x0000000184939460 in AUSpatialMixer::Render(unsigned int&, AudioTimeStamp const&, unsigned int) ()
3   0x0000000184a62a20 in AUBase::DoRenderBus(unsigned int&, AudioTimeStamp const&, unsigned int, AUOutputElement*, unsigned int, AudioBufferList&) ()
4   0x0000000184a621ac in AUBase::DoRender(unsigned int&, AudioTimeStamp const&, unsigned int, unsigned int, AudioBufferList&) ()
5   0x0000000184a6b550 in AUMethodRender(void*, unsigned int*, AudioTimeStamp const*, unsigned int, unsigned int, AudioBufferList*) ()
6   0x0000000184a5d284 in AUInputElement::PullInput(unsigned int&, AudioTimeStamp const&, unsigned int, unsigned int) ()
7   0x00000001847e8e00 in AUInputFormatConverter2::InputProc(OpaqueAudioConverter*, unsigned int*, AudioBufferList*, AudioStreamPacketDescription**, void*) ()
8   0x000000018474fdd4 in AudioConverterChain::CallInputProc(unsigned int) ()
9   0x000000018474fa64 in AudioConverterChain::FillBufferFromInputProc(unsigned int*, CABufferList*) ()
10  0x000000018472be38 in BufferedAudioConverter::GetInputBytes(unsigned int, unsigned int&, CABufferList const*&) ()
11  0x00000001849906f8 in Resampler2Wrapper::RenderOutput(CABufferList*, unsigned int, unsigned int&) ()
#12 0x0000000184752a7c in SampleRateConverter::RenderOutput(CABufferList*, unsigned int, unsigned int&, AudioStreamPacketDescription*) ()
13  0x000000018472bcc8 in BufferedAudioConverter::FillBuffer(unsigned int&, AudioBufferList&, AudioStreamPacketDescription*) ()
14  0x000000018474f65c in AudioConverterChain::RenderOutput(CABufferList*, unsigned int, unsigned int&, AudioStreamPacketDescription*) ()
15  0x000000018472bcc8 in BufferedAudioConverter::FillBuffer(unsigned int&, AudioBufferList&, AudioStreamPacketDescription*) ()
16  0x000000018493ec98 in AudioConverterFillComplexBuffer ()
17  0x00000001847e864c in AUConverterBase::RenderBus(unsigned int&, AudioTimeStamp const&, unsigned int, unsigned int) ()
18  0x00000001846cd07c in AURemoteIO::RenderBus(unsigned int&, AudioTimeStamp const&, unsigned int, unsigned int) ()
19  0x0000000184a62a20 in AUBase::DoRenderBus(unsigned int&, AudioTimeStamp const&, unsigned int, AUOutputElement*, unsigned int, AudioBufferList&) ()
20  0x0000000184a621ac in AUBase::DoRender(unsigned int&, AudioTimeStamp const&, unsigned int, unsigned int, AudioBufferList&) ()
21  0x00000001846ccd28 in AURemoteIO::PerformIO(unsigned int, unsigned int, unsigned int, AudioTimeStamp const&, AudioTimeStamp const&, AudioBufferList const*, AudioBufferList*, int&) ()
22  0x00000001846ce1a0 in AURIOCallbackReceiver_PerformIO ()
23  0x0000000184860018 in _XPerformIO ()
24  0x0000000184a4a5ec in mshMIGPerform ()
25  0x0000000184a4a804 in MSHMIGDispatchMessage ()
26  0x00000001846cd4c0 in AURemoteIO::IOThread::Run() ()
27  0x00000001846d1a40 in AURemoteIO::IOThread::Entry(void*) ()
28  0x0000000184a52630 in CAPThread::Entry(CAPThread*) ()
29  0x00000001808c432c in _pthread_body ()
30  0x00000001808c41f8 in _pthread_start ()
31  0x00000001808c2c38 in thread_start ()

根据我的收集,看起来从客户端数据格式到线性pcm的转换是在AURemoteIO线程中完成的,该线程在删除缓冲区后可能还没有完成数据的转换。

1°)真的是什么意思吗?

2°)如果是,这是正常行为吗?如果缓冲区破坏得太快,ExtAudioFileRead是否应该崩溃?

3°)如果这确实是在发生什么,并且是正常现象,那么我该如何避免崩溃(例如,如果缓冲区被破坏,则停止转换)

谢谢

0 个答案:

没有答案