SndFile.c revision 369f3138f19f7102bf0f98b890ab84c8df633a93
1b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten/* 2b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * Copyright (C) 2010 The Android Open Source Project 3b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * 4b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 5b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * you may not use this file except in compliance with the License. 6b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * You may obtain a copy of the License at 7b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * 8b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 9b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * 10b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * Unless required by applicable law or agreed to in writing, software 11b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 12b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * See the License for the specific language governing permissions and 14b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * limitations under the License. 15b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten */ 16b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 17369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten/** \brief libsndfile integration */ 18b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 19b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#include "sles_allinclusive.h" 20b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 21b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#ifdef USE_SNDFILE 22b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 23369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten/** \brief Called by BufferQueue after each buffer is consumed */ 24369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten 256a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kastenvoid SndFile_Callback(SLBufferQueueItf caller, void *pContext) 26b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten{ 27276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten CAudioPlayer *thisAP = (CAudioPlayer *) pContext; 28e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten object_lock_peek(&thisAP->mObject); 29e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten SLuint32 state = thisAP->mPlay.mState; 30e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten object_unlock_peek(&thisAP->mObject); 314b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // FIXME should not muck around directly at this low level 32e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if (SL_PLAYSTATE_PLAYING != state) 33276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten return; 34276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten struct SndFile *this = &thisAP->mSndFile; 35b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten SLresult result; 364b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten pthread_mutex_lock(&this->mMutex); 374b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if ((NULL != this->mRetryBuffer) && (0 < this->mRetrySize)) { 3827f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten result = (*caller)->Enqueue(caller, this->mRetryBuffer, this->mRetrySize); 394b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if (SL_RESULT_BUFFER_INSUFFICIENT == result) { 404b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten pthread_mutex_unlock(&this->mMutex); 41b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return; // what, again? 424b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 43b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten assert(SL_RESULT_SUCCESS == result); 44b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten this->mRetryBuffer = NULL; 45b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten this->mRetrySize = 0; 464b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten pthread_mutex_unlock(&this->mMutex); 47b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return; 48b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 49e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if (this->mEOF) { 50e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten pthread_mutex_unlock(&this->mMutex); 51e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten return; 52e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 536a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten short *pBuffer = &this->mBuffer[this->mWhich * SndFile_BUFSIZE]; 546a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten if (++this->mWhich >= SndFile_NUMBUFS) 556a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten this->mWhich = 0; 56b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten sf_count_t count; 576a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten count = sf_read_short(this->mSNDFILE, pBuffer, (sf_count_t) SndFile_BUFSIZE); 58e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if (0 >= count) 59e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten this->mEOF = SL_BOOLEAN_TRUE; 60e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten pthread_mutex_unlock(&this->mMutex); 61b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten if (0 < count) { 627324a5ab12cc734e2feb4cef8baeda26566d3c92Glenn Kasten SLuint32 size = (SLuint32) (count * sizeof(short)); 63b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten result = (*caller)->Enqueue(caller, pBuffer, size); 644b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // this should not happen, but if it does, who will call us to kick off again? 65b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten if (SL_RESULT_BUFFER_INSUFFICIENT == result) { 66b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten this->mRetryBuffer = pBuffer; 67b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten this->mRetrySize = size; 68b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return; 69b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 70b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten assert(SL_RESULT_SUCCESS == result); 71276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten } else { 72e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten object_lock_exclusive(&thisAP->mObject); 734b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // FIXME This is really hosed, you can't do this anymore! 744b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // FIXME Need a state PAUSE_WHEN_EMPTY 757a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten // Should not pause yet - we just ran out of new data to enqueue, 76e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten // but there may still be (partially) full buffers in the queue. 77276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten thisAP->mPlay.mState = SL_PLAYSTATE_PAUSED; 78e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten thisAP->mPlay.mPosition = thisAP->mPlay.mDuration; 79e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten object_unlock_exclusive_attributes(&thisAP->mObject, ATTR_TRANSPORT); 80b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 81b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten} 82b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 83369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten 84369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten/** \brief Check whether the supplied libsndfile format is supported by us */ 85369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten 86b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn KastenSLboolean SndFile_IsSupported(const SF_INFO *sfinfo) 87b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten{ 88b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten switch (sfinfo->format & SF_FORMAT_TYPEMASK) { 89b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten case SF_FORMAT_WAV: 90b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten break; 91b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten default: 92b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_BOOLEAN_FALSE; 93b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 94b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten switch (sfinfo->format & SF_FORMAT_SUBMASK) { 95276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten case SF_FORMAT_PCM_U8: 96b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten case SF_FORMAT_PCM_16: 97b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten break; 98b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten default: 99b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_BOOLEAN_FALSE; 100b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 101b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten switch (sfinfo->samplerate) { 102276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten case 11025: 103276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten case 22050: 104b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten case 44100: 105b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten break; 106b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten default: 107b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_BOOLEAN_FALSE; 108b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 109b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten switch (sfinfo->channels) { 110276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten case 1: 111b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten case 2: 112b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten break; 113b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten default: 114b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_BOOLEAN_FALSE; 115b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 116b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_BOOLEAN_TRUE; 117b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten} 118b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 119369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten 120369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten/** \brief Check whether the partially-constructed AudioPlayer is compatible with libsndfile */ 121369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten 122acd88797a1d3b8225bab888d29036e245f275be5Glenn KastenSLresult SndFile_checkAudioPlayerSourceSink(CAudioPlayer *this) 123daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 124acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten const SLDataSource *pAudioSrc = &this->mDataSource.u.mSource; 125daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator; 126daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat; 127daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (locatorType) { 128daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 129daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 130daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_URI: 131daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten { 132daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator; 133daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLchar *uri = dl_uri->URI; 134daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == uri) 135daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 13627f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten if (!strncmp((const char *) uri, "file:///", 8)) 13727f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten uri += 8; 138daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (formatType) { 139a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATAFORMAT_NULL: // OK to omit the data format 140a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten case SL_DATAFORMAT_MIME: // we ignore a MIME type if specified 141daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 142daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 143daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 144daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 14527f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten this->mSndFile.mPathname = uri; 14640d1c40832a448e23d0bb37512aee53222575c2eGlenn Kasten this->mBufferQueue.mNumBuffers = SndFile_NUMBUFS; 147daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 148daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 149daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 150daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 151daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 1523d81b8ca5d3cee893672beb76e00849d4f3fa8b8Glenn Kasten const SLDataSink *pAudioSnk = &this->mDataSink.u.mSink; 1536a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten this->mSndFile.mWhich = 0; 154acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten this->mSndFile.mSNDFILE = NULL; 155e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten // this->mSndFile.mMutex is initialized only when there is a valid mSNDFILE 156e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten this->mSndFile.mEOF = SL_BOOLEAN_FALSE; 157acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten this->mSndFile.mRetryBuffer = NULL; 158acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten this->mSndFile.mRetrySize = 0; 1593d81b8ca5d3cee893672beb76e00849d4f3fa8b8Glenn Kasten if (SL_DATALOCATOR_OUTPUTMIX == ((SLDataLocator_OutputMix *)pAudioSnk->pLocator)->locatorType) { 1603d81b8ca5d3cee893672beb76e00849d4f3fa8b8Glenn Kasten // FIXME possible race between the earlier check and here - should atomically link these 161369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten this->mEffectSend.mOutputMix = (COutputMix*) ((SLDataLocator_OutputMix *)pAudioSnk->pLocator)->outputMix; 1623d81b8ca5d3cee893672beb76e00849d4f3fa8b8Glenn Kasten } 1633d81b8ca5d3cee893672beb76e00849d4f3fa8b8Glenn Kasten 164daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 165daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 166daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 167369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten/** \brief Called with mutex unlocked for marker and position updates, and play state change */ 1684b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 169e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenvoid audioPlayerTransportUpdate(CAudioPlayer *audioPlayer) 170e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten{ 171369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten // FIXME should use two separate hooks since we have separate attributes TRANSPORT and POSITION 1724b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 1734b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if (NULL != audioPlayer->mSndFile.mSNDFILE) { 1744b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 1754b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten object_lock_exclusive(&audioPlayer->mObject); 1764b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten SLmillisecond pos = audioPlayer->mSeek.mPos; 1774b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten audioPlayer->mSeek.mPos = SL_TIME_UNKNOWN; 1784b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten SLboolean empty = 0 == audioPlayer->mBufferQueue.mState.count; 1793d81b8ca5d3cee893672beb76e00849d4f3fa8b8Glenn Kasten // FIXME a made-up number that should depend on player state and prefetch status 1803d81b8ca5d3cee893672beb76e00849d4f3fa8b8Glenn Kasten audioPlayer->mPrefetchStatus.mLevel = 1000; 1814b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten object_unlock_exclusive(&audioPlayer->mObject); 1824b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 1834b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if (SL_TIME_UNKNOWN != pos) { 1844b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 1854b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // discard any enqueued buffers for the old position 1864b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten (*&audioPlayer->mBufferQueue.mItf)->Clear(&audioPlayer->mBufferQueue.mItf); 1874b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten empty = SL_BOOLEAN_TRUE; 1884b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 1894b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten pthread_mutex_lock(&audioPlayer->mSndFile.mMutex); 1904b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten (void) sf_seek(audioPlayer->mSndFile.mSNDFILE, (sf_count_t) (((long long) pos * 1914b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten audioPlayer->mSndFile.mSfInfo.samplerate) / 1000LL), SEEK_SET); 1924b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten audioPlayer->mSndFile.mEOF = SL_BOOLEAN_FALSE; 1934b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten audioPlayer->mSndFile.mRetryBuffer = NULL; 1944b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten audioPlayer->mSndFile.mRetrySize = 0; 1954b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten audioPlayer->mSndFile.mWhich = 0; 1964b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten pthread_mutex_unlock(&audioPlayer->mSndFile.mMutex); 1974b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 1984b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 1994b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 2004b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // FIXME only on seek or play state change (STOPPED, PAUSED) -> PLAYING 2014b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if (empty) { 2024b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten SndFile_Callback(&audioPlayer->mBufferQueue.mItf, audioPlayer); 2034b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 2044b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 205e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 206e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten 207e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten} 208e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten 209b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#endif // USE_SNDFILE 210