Apple ExtAudioFileRead с клиентским форматом данных (mp3) действительно синхронна

Является ли ExtAudioFileRead действительно синхронным при использовании в сочетании с ExtAudioFileRef, который содержит формат данных клиента (а именно, mp3)?

В документе сказано, что:

    /*!
    @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)

Но иногда при удалении ioData сразу после вызова ExtAudioFileRead возникает странный стек:

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 ответов

Другие вопросы по тегам