SndFile.c revision 276cab2d983b892d1b634474b6249f6bec400c76
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 17b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten/* libsndfile integration */ 18b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 19b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#include "sles_allinclusive.h" 20b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 21b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#ifdef USE_SNDFILE 22b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 23276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten// FIXME Needs some mutexes here and there 24276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten 25b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten// FIXME should run this asynchronously esp. for socket fd, not on mix thread 267324a5ab12cc734e2feb4cef8baeda26566d3c92Glenn Kastenvoid /*SLAPIENTRY*/ SndFile_Callback(SLBufferQueueItf caller, void *pContext) 27b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten{ 28276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten CAudioPlayer *thisAP = (CAudioPlayer *) pContext; 29276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten if (thisAP->mPlay.mState != SL_PLAYSTATE_PLAYING) 30276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten return; 31276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten struct SndFile *this = &thisAP->mSndFile; 32b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten SLresult result; 33b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten if (NULL != this->mRetryBuffer && 0 < this->mRetrySize) { 3427f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten result = (*caller)->Enqueue(caller, this->mRetryBuffer, this->mRetrySize); 35b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten if (SL_RESULT_BUFFER_INSUFFICIENT == result) 36b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return; // what, again? 37b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten assert(SL_RESULT_SUCCESS == result); 38b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten this->mRetryBuffer = NULL; 39b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten this->mRetrySize = 0; 40b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return; 41b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 42b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten short *pBuffer = this->mIs0 ? this->mBuffer0 : this->mBuffer1; 43b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten this->mIs0 ^= SL_BOOLEAN_TRUE; 44b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten sf_count_t count; 45b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten // FIXME magic number 46b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten count = sf_read_short(this->mSNDFILE, pBuffer, (sf_count_t) 512); 47b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten if (0 < count) { 487324a5ab12cc734e2feb4cef8baeda26566d3c92Glenn Kasten SLuint32 size = (SLuint32) (count * sizeof(short)); 49b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten // FIXME if we had an internal API, could call this directly 50b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten result = (*caller)->Enqueue(caller, pBuffer, size); 51b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten if (SL_RESULT_BUFFER_INSUFFICIENT == result) { 52b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten this->mRetryBuffer = pBuffer; 53b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten this->mRetrySize = size; 54b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return; 55b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 56b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten assert(SL_RESULT_SUCCESS == result); 57276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten } else { 58276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten thisAP->mPlay.mState = SL_PLAYSTATE_PAUSED; 59276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten (void) sf_seek(this->mSNDFILE, (sf_count_t) 0, SEEK_SET); 60b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 61b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten} 62b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 63b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn KastenSLboolean SndFile_IsSupported(const SF_INFO *sfinfo) 64b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten{ 65b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten switch (sfinfo->format & SF_FORMAT_TYPEMASK) { 66b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten case SF_FORMAT_WAV: 67b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten break; 68b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten default: 69b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_BOOLEAN_FALSE; 70b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 71b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten switch (sfinfo->format & SF_FORMAT_SUBMASK) { 72276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten case SF_FORMAT_PCM_U8: 73b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten case SF_FORMAT_PCM_16: 74b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten break; 75b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten default: 76b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_BOOLEAN_FALSE; 77b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 78b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten switch (sfinfo->samplerate) { 79276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten case 11025: 80276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten case 22050: 81b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten case 44100: 82b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten break; 83b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten default: 84b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_BOOLEAN_FALSE; 85b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 86b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten switch (sfinfo->channels) { 87276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten case 1: 88b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten case 2: 89b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten break; 90b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten default: 91b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_BOOLEAN_FALSE; 92b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 93b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_BOOLEAN_TRUE; 94b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten} 95b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 96acd88797a1d3b8225bab888d29036e245f275be5Glenn KastenSLresult SndFile_checkAudioPlayerSourceSink(CAudioPlayer *this) 97daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 98acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten const SLDataSource *pAudioSrc = &this->mDataSource.u.mSource; 99acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten //const SLDataSink *pAudioSnk = &this->mDataSink.u.mSink; 100daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator; 101daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat; 102daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (locatorType) { 103daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 104acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten this->mBufferQueue.mNumBuffers = 105acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten ((SLDataLocator_BufferQueue *) pAudioSrc->pLocator)->numBuffers; 106daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 107daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_URI: 108daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten { 109daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator; 110daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLchar *uri = dl_uri->URI; 111daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == uri) 112daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 11327f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten // FIXME check other schemes and handle, or return SL_RESULT_CONTENT_UNSUPPORTED 11427f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten if (!strncmp((const char *) uri, "file:///", 8)) 11527f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten uri += 8; 116daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (formatType) { 117daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATAFORMAT_MIME: 118daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 119daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 120daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 121daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 12227f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten this->mSndFile.mPathname = uri; 123daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // FIXME magic number, should be configurable 124acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten this->mBufferQueue.mNumBuffers = 2; 125daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 126daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 127daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 128daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 129daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 130acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten this->mSndFile.mIs0 = SL_BOOLEAN_TRUE; 131acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten this->mSndFile.mSNDFILE = NULL; 132acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten this->mSndFile.mRetryBuffer = NULL; 133acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten this->mSndFile.mRetrySize = 0; 134daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 135daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 136daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 137b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#endif // USE_SNDFILE 138