IEngine.c revision 0b167267bda99b68346045ccab14e810121d5de4
10b167267bda99b68346045ccab14e810121d5de4Glenn Kasten/* 20b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Copyright (C) 2010 The Android Open Source Project 30b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * 40b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 50b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * you may not use this file except in compliance with the License. 60b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * You may obtain a copy of the License at 70b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * 80b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 90b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * 100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Unless required by applicable law or agreed to in writing, software 110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * See the License for the specific language governing permissions and 140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * limitations under the License. 150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten */ 160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten/* Engine implementation */ 180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten//#include "sles_allinclusive.h" 200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 210b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice, 220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 deviceID, SLuint32 numInterfaces, 230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pDevice || SL_DEFAULTDEVICEID_LED != deviceID) 260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pDevice = NULL; 280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned exposedMask; 290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLresult result = checkInterfaces(&CLEDDevice_class, numInterfaces, 300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (SL_RESULT_SUCCESS != result) 320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return result; 330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten CLEDDevice *this = (CLEDDevice *) 340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten construct(&CLEDDevice_class, exposedMask, self); 350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == this) 360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_MEMORY_FAILURE; 370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLHSL *color = (SLHSL *) malloc(sizeof(SLHSL) * this->mLEDArray.mCount); 380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // FIXME 390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten assert(NULL != this->mLEDArray.mColor); 400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mLEDArray.mColor = color; 410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned i; 420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten for (i = 0; i < this->mLEDArray.mCount; ++i) { 430b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // per specification 1.0.1 pg. 259: "Default color is undefined." 440b167267bda99b68346045ccab14e810121d5de4Glenn Kasten color->hue = 0; 450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten color->saturation = 1000; 460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten color->lightness = 1000; 470b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 480b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mDeviceID = deviceID; 490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pDevice = &this->mObject.mItf; 500b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_SUCCESS; 510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 520b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 530b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_CreateVibraDevice(SLEngineItf self, 540b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLObjectItf *pDevice, SLuint32 deviceID, SLuint32 numInterfaces, 550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 560b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pDevice || SL_DEFAULTDEVICEID_VIBRA != deviceID) 580b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 590b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pDevice = NULL; 600b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned exposedMask; 610b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLresult result = checkInterfaces(&CVibraDevice_class, numInterfaces, 620b167267bda99b68346045ccab14e810121d5de4Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 630b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (SL_RESULT_SUCCESS != result) 640b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return result; 650b167267bda99b68346045ccab14e810121d5de4Glenn Kasten CVibraDevice *this = (CVibraDevice *) 660b167267bda99b68346045ccab14e810121d5de4Glenn Kasten construct(&CVibraDevice_class, exposedMask, self); 670b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == this) 680b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_MEMORY_FAILURE; 690b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mDeviceID = deviceID; 700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pDevice = &this->mObject.mItf; 710b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_SUCCESS; 720b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 730b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 740b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 750b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer, 760b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces, 770b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 790b167267bda99b68346045ccab14e810121d5de4Glenn Kasten fprintf(stderr, "entering IEngine_CreateAudioPlayer()\n"); 800b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pPlayer) 820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 830b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pPlayer = NULL; 840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned exposedMask; 850b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLresult result = checkInterfaces(&CAudioPlayer_class, numInterfaces, 860b167267bda99b68346045ccab14e810121d5de4Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 870b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (SL_RESULT_SUCCESS != result) 880b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return result; 890b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // check the audio source and sinks 900b167267bda99b68346045ccab14e810121d5de4Glenn Kasten result = sles_checkAudioPlayerSourceSink(pAudioSrc, pAudioSnk); 910b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (result != SL_RESULT_SUCCESS) { 920b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return result; 930b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 940b167267bda99b68346045ccab14e810121d5de4Glenn Kasten fprintf(stderr, "\t after sles_checkSourceSink()\n"); 950b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // check the audio source and sink parameters against platform support 960b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifdef USE_ANDROID 970b167267bda99b68346045ccab14e810121d5de4Glenn Kasten result = sles_to_android_checkAudioPlayerSourceSink(pAudioSrc, pAudioSnk); 980b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (result != SL_RESULT_SUCCESS) { 990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return result; 1000b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 1010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten fprintf(stderr, "\t after sles_to_android_checkAudioPlayerSourceSink()\n"); 1020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif 1030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 1040b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifdef USE_SNDFILE 1050b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator; 1060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat; 1070b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 numBuffers = 0; 1080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLDataFormat_PCM *df_pcm = NULL; 1090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLchar *pathname = NULL; 1100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (locatorType) { 1110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 1120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { 1130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLDataLocator_BufferQueue *dl_bq = 1140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten (SLDataLocator_BufferQueue *) pAudioSrc->pLocator; 1150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten numBuffers = dl_bq->numBuffers; 1160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (0 == numBuffers) 1170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 1180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (formatType) { 1190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATAFORMAT_PCM: 1200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { 1210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat; 1220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (df_pcm->numChannels) { 1230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case 1: 1240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case 2: 1250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 1260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 1270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 1280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 1290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (df_pcm->samplesPerSec) { 1300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case 44100: 1310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 1320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#if 1 // wrong units for samplesPerSec! 1330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_SAMPLINGRATE_44_1: 1340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 1350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif 1360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // others 1370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 1380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 1390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 1400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (df_pcm->bitsPerSample) { 1410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_PCMSAMPLEFORMAT_FIXED_16: 1420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 1430b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // others 1440b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 1450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 1460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 1470b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (df_pcm->containerSize) { 1480b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case 16: 1490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 1500b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // others 1510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 1520b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 1530b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 1540b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (df_pcm->channelMask) { 1550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // needs work 1560b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 1570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 1580b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 1590b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (df_pcm->endianness) { 1600b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_BYTEORDER_LITTLEENDIAN: 1610b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 1620b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // others esp. big and native (new not in spec) 1630b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 1640b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 1650b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 1660b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 1670b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 1680b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATAFORMAT_MIME: 1690b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATAFORMAT_RESERVED3: 1700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 1710b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 1720b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 1730b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 1740b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 1750b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 1760b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_URI: 1770b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { 1780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator; 1790b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLchar *uri = dl_uri->URI; 1800b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == uri) 1810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 1820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (strncmp((const char *) uri, "file:///", 8)) 1830b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 1840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten pathname = &uri[8]; 1850b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (formatType) { 1860b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATAFORMAT_MIME: 1870b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { 1880b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLDataFormat_MIME *df_mime = 1890b167267bda99b68346045ccab14e810121d5de4Glenn Kasten (SLDataFormat_MIME *) pAudioSrc->pFormat; 1900b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLchar *mimeType = df_mime->mimeType; 1910b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == mimeType) 1920b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 1930b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 containerType = df_mime->containerType; 1940b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (!strcmp((const char *) mimeType, "audio/x-wav")) 1950b167267bda99b68346045ccab14e810121d5de4Glenn Kasten ; 1960b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // else if (others) 1970b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // ; 1980b167267bda99b68346045ccab14e810121d5de4Glenn Kasten else 1990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 2000b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (containerType) { 2010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_CONTAINERTYPE_WAV: 2020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 2030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // others 2040b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 2050b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 2060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 2070b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 2080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 2090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 2100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 2110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 2120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // FIXME magic number, should be configurable 2130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten numBuffers = 2; 2140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 2150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 2160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_ADDRESS: 2170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_IODEVICE: 2180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 2190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_RESERVED5: 2200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 2210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_RESERVED8: 2220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 2230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 2240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 2250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 2260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif // USE_SNDFILE 2270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 2280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifdef USE_OUTPUTMIXEXT 2290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten struct Track *track = NULL; 2300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (*(SLuint32 *)pAudioSnk->pLocator) { 2310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_OUTPUTMIX: 2320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { 2330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // pAudioSnk->pFormat is ignored 2340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLDataLocator_OutputMix *dl_outmix = 2350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten (SLDataLocator_OutputMix *) pAudioSnk->pLocator; 2360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLObjectItf outputMix = dl_outmix->outputMix; 2370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // FIXME make this an operation on Object: GetClass 2380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if ((NULL == outputMix) || (&COutputMix_class != 2390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten ((IObject *) outputMix)->mClass)) 2400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 2410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IOutputMix *om = 2420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten &((COutputMix *) outputMix)->mOutputMix; 2430b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // allocate an entry within OutputMix for this track 2440b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // FIXME O(n) 2450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned i; 2460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten for (i = 0, track = &om->mTracks[0]; i < 32; ++i, ++track) { 2470b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (om->mActiveMask & (1 << i)) 2480b167267bda99b68346045ccab14e810121d5de4Glenn Kasten continue; 2490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten om->mActiveMask |= 1 << i; 2500b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 2510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 2520b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (32 <= i) { 2530b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // FIXME Need a better error code for all slots full in output mix 2540b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_MEMORY_FAILURE; 2550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 2560b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // FIXME replace the above for Android - do not use our own mixer! 2570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 2580b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 2590b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 2600b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_URI: 2610b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_ADDRESS: 2620b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_IODEVICE: 2630b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_RESERVED5: 2640b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_MIDIBUFFERQUEUE: 2650b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_RESERVED8: 2660b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 2670b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 2680b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 2690b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 2700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif // USE_OUTPUTMIXEXT 2710b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 2720b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // Construct our new AudioPlayer instance 2730b167267bda99b68346045ccab14e810121d5de4Glenn Kasten CAudioPlayer *this = (CAudioPlayer *) 2740b167267bda99b68346045ccab14e810121d5de4Glenn Kasten construct(&CAudioPlayer_class, exposedMask, self); 2750b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == this) 2760b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_MEMORY_FAILURE; 2770b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 2780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // DataSource specific initializations 2790b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch(*(SLuint32 *)pAudioSrc->pLocator) { 2800b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_URI: 2810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifndef USE_OUTPUTMIXEXT // e.g. USE_ANDROID 2820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 2830b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#else 2840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // fall through 2850b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif 2860b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 2870b167267bda99b68346045ccab14e810121d5de4Glenn Kasten { 2880b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLDataLocator_BufferQueue *dl_bq = (SLDataLocator_BufferQueue *) pAudioSrc->pLocator; 2890b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 numBuffs = dl_bq->numBuffers; 2900b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (0 == numBuffs) { 2910b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 2920b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 2930b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mBufferQueue.mNumBuffers = numBuffs; 2940b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // inline allocation of circular mArray, up to a typical max 2950b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (BUFFER_HEADER_TYPICAL >= numBuffs) { 2960b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mBufferQueue.mArray = this->mBufferQueue.mTypical; 2970b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } else { 2980b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // FIXME integer overflow possible during multiplication 2990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mBufferQueue.mArray = (struct BufferHeader *) 3000b167267bda99b68346045ccab14e810121d5de4Glenn Kasten malloc((numBuffs + 1) * sizeof(struct BufferHeader)); 3010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == this->mBufferQueue.mArray) { 3020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten free(this); 3030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_MEMORY_FAILURE; 3040b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 3050b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 3060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mBufferQueue.mFront = this->mBufferQueue.mArray; 3070b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mBufferQueue.mRear = this->mBufferQueue.mArray; 3080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 3090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 3100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 3110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // no other init required 3120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 3130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 3140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 3150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // used to store the data source of our audio player 3160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mDynamicSource.mDataSource = pAudioSrc; 3170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifdef USE_SNDFILE 3180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mSndFile.mPathname = pathname; 3190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mSndFile.mIs0 = SL_BOOLEAN_TRUE; 3200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifndef NDEBUG 3210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mSndFile.mSNDFILE = NULL; 3220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mSndFile.mRetryBuffer = NULL; 3230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mSndFile.mRetrySize = 0; 3240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif 3250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif // USE_SNDFILE 3260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifdef USE_OUTPUTMIXEXT 3270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // link track to player (NOT for Android!!) 3280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten track->mDfPcm = df_pcm; 3290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten track->mBufferQueue = &this->mBufferQueue; 3300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten track->mPlay = &this->mPlay; 3310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // next 2 fields must be initialized explicitly (not part of this) 3320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten track->mReader = NULL; 3330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten track->mAvail = 0; 3340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif 3350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifdef USE_ANDROID 3360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten sles_to_android_createAudioPlayer(pAudioSrc, pAudioSnk, this); 3370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif 3380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // return the new audio player object 3390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pPlayer = &this->mObject.mItf; 3400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_SUCCESS; 3410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 3420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 3430b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_CreateAudioRecorder(SLEngineItf self, 3440b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLObjectItf *pRecorder, SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, 3450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 3460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLboolean *pInterfaceRequired) 3470b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 3480b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pRecorder) 3490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 3500b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pRecorder = NULL; 3510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned exposedMask; 3520b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLresult result = checkInterfaces(&CAudioRecorder_class, numInterfaces, 3530b167267bda99b68346045ccab14e810121d5de4Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 3540b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (SL_RESULT_SUCCESS != result) 3550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return result; 3560b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_SUCCESS; 3570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 3580b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 3590b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer, 3600b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput, 3610b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces, 3620b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 3630b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 3640b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pPlayer) 3650b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 3660b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pPlayer = NULL; 3670b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned exposedMask; 3680b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLresult result = checkInterfaces(&CMidiPlayer_class, numInterfaces, 3690b167267bda99b68346045ccab14e810121d5de4Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 3700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (SL_RESULT_SUCCESS != result) 3710b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return result; 3720b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pMIDISrc || NULL == pAudioOutput) 3730b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 3740b167267bda99b68346045ccab14e810121d5de4Glenn Kasten CMidiPlayer *this = (CMidiPlayer *) 3750b167267bda99b68346045ccab14e810121d5de4Glenn Kasten construct(&CMidiPlayer_class, exposedMask, self); 3760b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == this) 3770b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_MEMORY_FAILURE; 3780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // return the new MIDI player object 3790b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pPlayer = &this->mObject.mItf; 3800b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_SUCCESS; 3810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 3820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 3830b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_CreateListener(SLEngineItf self, SLObjectItf *pListener, 3840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 3850b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLboolean *pInterfaceRequired) 3860b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 3870b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pListener) 3880b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 3890b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pListener = NULL; 3900b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned exposedMask; 3910b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLresult result = checkInterfaces(&CListener_class, numInterfaces, 3920b167267bda99b68346045ccab14e810121d5de4Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 3930b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (SL_RESULT_SUCCESS != result) 3940b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return result; 3950b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 3960b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 3970b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 3980b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup, 3990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 4000b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLboolean *pInterfaceRequired) 4010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 4020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pGroup) 4030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 4040b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pGroup = NULL; 4050b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned exposedMask; 4060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLresult result = checkInterfaces(&C3DGroup_class, numInterfaces, 4070b167267bda99b68346045ccab14e810121d5de4Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 4080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (SL_RESULT_SUCCESS != result) 4090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return result; 4100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 4110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 4120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 4130b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix, 4140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 4150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLboolean *pInterfaceRequired) 4160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 4170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pMix) 4180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 4190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pMix = NULL; 4200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned exposedMask; 4210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLresult result = checkInterfaces(&COutputMix_class, numInterfaces, 4220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 4230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (SL_RESULT_SUCCESS != result) 4240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return result; 4250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten COutputMix *this = (COutputMix *) 4260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten construct(&COutputMix_class, exposedMask, self); 4270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == this) 4280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_MEMORY_FAILURE; 4290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pMix = &this->mObject.mItf; 4300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_SUCCESS; 4310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 4320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 4330b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_CreateMetadataExtractor(SLEngineItf self, 4340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLObjectItf *pMetadataExtractor, SLDataSource *pDataSource, 4350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 4360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLboolean *pInterfaceRequired) 4370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 4380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pMetadataExtractor) 4390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 4400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pMetadataExtractor = NULL; 4410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned exposedMask; 4420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLresult result = checkInterfaces(&CMetadataExtractor_class, numInterfaces, 4430b167267bda99b68346045ccab14e810121d5de4Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 4440b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (SL_RESULT_SUCCESS != result) 4450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return result; 4460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten CMetadataExtractor *this = (CMetadataExtractor *) 4470b167267bda99b68346045ccab14e810121d5de4Glenn Kasten construct(&CMetadataExtractor_class, exposedMask, self); 4480b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == this) 4490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_MEMORY_FAILURE; 4500b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pMetadataExtractor = &this->mObject.mItf; 4510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_SUCCESS; 4520b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 4530b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 4540b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_CreateExtensionObject(SLEngineItf self, 4550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLObjectItf *pObject, void *pParameters, SLuint32 objectID, 4560b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 4570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLboolean *pInterfaceRequired) 4580b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 4590b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pObject) 4600b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 4610b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pObject = NULL; 4620b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 4630b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 4640b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 4650b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_QueryNumSupportedInterfaces(SLEngineItf self, 4660b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 objectID, SLuint32 *pNumSupportedInterfaces) 4670b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 4680b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pNumSupportedInterfaces) 4690b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 4700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const ClassTable *class__ = objectIDtoClass(objectID); 4710b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == class__) 4720b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 4730b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pNumSupportedInterfaces = class__->mInterfaceCount; 4740b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_SUCCESS; 4750b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 4760b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 4770b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_QuerySupportedInterfaces(SLEngineItf self, 4780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId) 4790b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 4800b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pInterfaceId) 4810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 4820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const ClassTable *class__ = objectIDtoClass(objectID); 4830b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == class__) 4840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_FEATURE_UNSUPPORTED; 4850b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (index >= class__->mInterfaceCount) 4860b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 4870b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pInterfaceId = &SL_IID_array[class__->mInterfaces[index].mMPH]; 4880b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_SUCCESS; 4890b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}; 4900b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 4910b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_QueryNumSupportedExtensions(SLEngineItf self, 4920b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 *pNumExtensions) 4930b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 4940b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pNumExtensions) 4950b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 4960b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pNumExtensions = 0; 4970b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_SUCCESS; 4980b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 4990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 5000b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_QuerySupportedExtension(SLEngineItf self, 5010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength) 5020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 5030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // any index >= 0 will be >= number of supported extensions 5040b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 5050b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 5060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 5070b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_IsExtensionSupported(SLEngineItf self, 5080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLchar *pExtensionName, SLboolean *pSupported) 5090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 5100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten if (NULL == pExtensionName || NULL == pSupported) 5110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_PARAMETER_INVALID; 5120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *pSupported = SL_BOOLEAN_FALSE; 5130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten return SL_RESULT_SUCCESS; 5140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 5150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 5160b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic const struct SLEngineItf_ IEngine_Itf = { 5170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateLEDDevice, 5180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateVibraDevice, 5190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateAudioPlayer, 5200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateAudioRecorder, 5210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateMidiPlayer, 5220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateListener, 5230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_Create3DGroup, 5240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateOutputMix, 5250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateMetadataExtractor, 5260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateExtensionObject, 5270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_QueryNumSupportedInterfaces, 5280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_QuerySupportedInterfaces, 5290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_QueryNumSupportedExtensions, 5300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_QuerySupportedExtension, 5310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_IsExtensionSupported 5320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}; 5330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 5340b167267bda99b68346045ccab14e810121d5de4Glenn Kastenvoid IEngine_init(void *self) 5350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 5360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine *this = (IEngine *) self; 5370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mItf = &IEngine_Itf; 5380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // mLossOfControlGlobal is initialized in CreateEngine 5390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifndef NDEBUG 5400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mInstanceCount = 0; 5410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned i; 5420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten for (i = 0; i < INSTANCE_MAX; ++i) 5430b167267bda99b68346045ccab14e810121d5de4Glenn Kasten this->mInstances[i] = NULL; 5440b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif 5450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 546