SndFile.c revision 27f8dfaea17ab7831a1bd34a02f85d55bacf67b7
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 23b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten// FIXME should run this asynchronously esp. for socket fd, not on mix thread 24b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kastenvoid SLAPIENTRY SndFile_Callback(SLBufferQueueItf caller, void *pContext) 25b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten{ 26b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten struct SndFile *this = (struct SndFile *) pContext; 27b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten SLresult result; 28b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten if (NULL != this->mRetryBuffer && 0 < this->mRetrySize) { 2927f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten result = (*caller)->Enqueue(caller, this->mRetryBuffer, this->mRetrySize); 30b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten if (SL_RESULT_BUFFER_INSUFFICIENT == result) 31b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return; // what, again? 32b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten assert(SL_RESULT_SUCCESS == result); 33b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten this->mRetryBuffer = NULL; 34b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten this->mRetrySize = 0; 35b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return; 36b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 37b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten short *pBuffer = this->mIs0 ? this->mBuffer0 : this->mBuffer1; 38b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten this->mIs0 ^= SL_BOOLEAN_TRUE; 39b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten sf_count_t count; 40b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten // FIXME magic number 41b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten count = sf_read_short(this->mSNDFILE, pBuffer, (sf_count_t) 512); 42b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten if (0 < count) { 43b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten SLuint32 size = count * sizeof(short); 44b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten // FIXME if we had an internal API, could call this directly 45b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten result = (*caller)->Enqueue(caller, pBuffer, size); 46b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten if (SL_RESULT_BUFFER_INSUFFICIENT == result) { 47b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten this->mRetryBuffer = pBuffer; 48b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten this->mRetrySize = size; 49b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return; 50b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 51b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten assert(SL_RESULT_SUCCESS == result); 52b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 53b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten} 54b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 55b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn KastenSLboolean SndFile_IsSupported(const SF_INFO *sfinfo) 56b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten{ 57b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten switch (sfinfo->format & SF_FORMAT_TYPEMASK) { 58b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten case SF_FORMAT_WAV: 59b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten break; 60b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten default: 61b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_BOOLEAN_FALSE; 62b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 63b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten switch (sfinfo->format & SF_FORMAT_SUBMASK) { 64b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten case SF_FORMAT_PCM_16: 65b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten break; 66b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten default: 67b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_BOOLEAN_FALSE; 68b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 69b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten switch (sfinfo->samplerate) { 70b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten case 44100: 71b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten break; 72b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten default: 73b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_BOOLEAN_FALSE; 74b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 75b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten switch (sfinfo->channels) { 76b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten case 2: 77b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten break; 78b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten default: 79b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_BOOLEAN_FALSE; 80b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten } 81b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten return SL_BOOLEAN_TRUE; 82b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten} 83b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten 84acd88797a1d3b8225bab888d29036e245f275be5Glenn KastenSLresult SndFile_checkAudioPlayerSourceSink(CAudioPlayer *this) 85daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{ 86acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten const SLDataSource *pAudioSrc = &this->mDataSource.u.mSource; 87acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten //const SLDataSink *pAudioSnk = &this->mDataSink.u.mSink; 88daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator; 89daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat; 90daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (locatorType) { 91daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 92acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten this->mBufferQueue.mNumBuffers = 93acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten ((SLDataLocator_BufferQueue *) pAudioSrc->pLocator)->numBuffers; 94daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 95daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATALOCATOR_URI: 96daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten { 97daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator; 98daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLchar *uri = dl_uri->URI; 99daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten if (NULL == uri) 100daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 10127f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten // FIXME check other schemes and handle, or return SL_RESULT_CONTENT_UNSUPPORTED 10227f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten if (!strncmp((const char *) uri, "file:///", 8)) 10327f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten uri += 8; 104daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten switch (formatType) { 105daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten case SL_DATAFORMAT_MIME: 106daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 107daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 108daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 109daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 11027f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten this->mSndFile.mPathname = uri; 111daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten // FIXME magic number, should be configurable 112acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten this->mBufferQueue.mNumBuffers = 2; 113daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 114daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten break; 115daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten default: 116daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 117daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten } 118acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten this->mSndFile.mIs0 = SL_BOOLEAN_TRUE; 119acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten this->mSndFile.mSNDFILE = NULL; 120acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten this->mSndFile.mRetryBuffer = NULL; 121acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten this->mSndFile.mRetrySize = 0; 122daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten return SL_RESULT_SUCCESS; 123daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten} 124daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 125b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#endif // USE_SNDFILE 126