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