IEffectSend.c revision fef6033d852daec8d88060b252e72f322724dca1
161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/* 261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * Copyright (C) 2010 The Android Open Source Project 361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * 461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * you may not use this file except in compliance with the License. 661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * You may obtain a copy of the License at 761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * 861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * 1061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * Unless required by applicable law or agreed to in writing, software 1161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 1261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * See the License for the specific language governing permissions and 1461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * limitations under the License. 1561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten */ 1661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 1761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/* EffectSend implementation */ 1861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 1961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten#include "sles_allinclusive.h" 2061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 21343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kasten 22343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kasten/** \brief Maps AUX index to OutputMix interface index */ 23510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 24510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kastenstatic const unsigned char AUX_to_MPH[AUX_MAX] = { 25510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten MPH_ENVIRONMENTALREVERB, 26510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten MPH_PRESETREVERB 27510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten}; 28510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 29343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kasten 30e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten/** \brief This is a private function that validates the effect interface specified by the 31e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten * application when it calls EnableEffectSend, IsEnabled, SetSendLevel, or GetSendLevel. 32e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten * For the interface to be valid, it has to satisfy these requirements: 33e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten * - object is an audio player (MIDI player is not supported yet) 34e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten * - audio sink is an output mix 35e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten * - interface was exposed at object creation time or by DynamicInterface::AddInterface 36e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten * - interface was "gotten" with Object::GetInterface 37e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten */ 38343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kasten 39d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic struct EnableLevel *getEnableLevel(IEffectSend *this, const void *pAuxEffect) 4061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 41343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kasten // Make sure this effect send is on an audio player, not a MIDI player 42343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kasten CAudioPlayer *audioPlayer = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(this)) ? 43343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kasten (CAudioPlayer *) this->mThis : NULL; 44343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kasten if (NULL == audioPlayer) 45343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kasten return NULL; 4661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten // Make sure the sink for this player is an output mix 47343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kasten COutputMix *outputMix = audioPlayer->mOutputMix; 4861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (NULL == outputMix) 4961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return NULL; 50510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten unsigned aux; 51510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten if (pAuxEffect == &outputMix->mEnvironmentalReverb.mItf) 52510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten aux = AUX_ENVIRONMENTALREVERB; 53510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten else if (pAuxEffect == &outputMix->mPresetReverb.mItf) 54510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten aux = AUX_PRESETREVERB; 55510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten else 56510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten return NULL; 57510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten assert(aux < AUX_MAX); 58e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten // Validate that the application has a valid interface for the effect. The interface must have 59e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten // been exposed at object creation time or by DynamicInterface::AddInterface, and it also must 60e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten // have been "gotten" with Object::GetInterface. 61510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten int index = MPH_to_OutputMix[AUX_to_MPH[aux]]; 62510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten if (0 > index) 63510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten return NULL; 64510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten unsigned mask = 1 << index; 65510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten object_lock_shared(&outputMix->mObject); 66510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten SLuint32 state = outputMix->mObject.mInterfaceStates[index]; 67510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten mask &= outputMix->mObject.mGottenMask; 68510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten object_unlock_shared(&outputMix->mObject); 69510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten switch (state) { 70510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_EXPOSED: 71510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_ADDED: 72510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_SUSPENDED: 73510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_SUSPENDING: 74510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_RESUMING_1: 75510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_RESUMING_2: 76510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten if (mask) 77510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten return &this->mEnableLevels[aux]; 78510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 79510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten default: 80510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 81510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } 8261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten return NULL; 8361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 8461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 8591bfd060b992810ca092f640f77f795bc3d008beGlenn Kasten#if defined(ANDROID) && !defined(USE_BACKPORT) 86172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi/** \brief This is a private function that translates an Android effect framework status code 87172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi * to the SL ES result code used in the EnableEffectSend() function of the SLEffectSendItf 88172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi * interface. 89172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi */ 90172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivistatic SLresult translateEnableFxSendError(android::status_t status) { 91172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi switch (status) { 92172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi case android::NO_ERROR: 93172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi return SL_RESULT_SUCCESS; 94172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi break; 95172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi case android::INVALID_OPERATION: 96172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi case android::BAD_VALUE: 97172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi default: 98172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi return SL_RESULT_RESOURCE_ERROR; 99172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi break; 100172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi } 101172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi} 10291bfd060b992810ca092f640f77f795bc3d008beGlenn Kasten#endif 103172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi 104ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 10561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IEffectSend_EnableEffectSend(SLEffectSendItf self, 10661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten const void *pAuxEffect, SLboolean enable, SLmillibel initialLevel) 10761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 108ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 109ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 110ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (!((SL_MILLIBEL_MIN <= initialLevel) && (initialLevel <= 0))) { 111ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 112ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 113ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten IEffectSend *this = (IEffectSend *) self; 114ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect); 115ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == enableLevel) { 116ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 117ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 118ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten interface_lock_exclusive(this); 119ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten enableLevel->mEnable = SL_BOOLEAN_FALSE != enable; // normalize 120ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten enableLevel->mSendLevel = initialLevel; 121172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi#if !defined(ANDROID) || defined(USE_BACKPORT) 122ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 123172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi#else 124172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi // TODO do not repeat querying of CAudioPlayer, done inside getEnableLevel() 125172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi CAudioPlayer *ap = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(this)) ? 126172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi (CAudioPlayer *) this->mThis : NULL; 127172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi // check which effect the send is attached to, attach and set level 128172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi if (NULL == ap) { 129172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi result = SL_RESULT_RESOURCE_ERROR; 130172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi } else { 131172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi if (pAuxEffect == &ap->mOutputMix->mPresetReverb.mItf) { 132172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi result = translateEnableFxSendError( 133172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi android_fxSend_attach( ap, (bool) enable, 134172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi ap->mOutputMix->mPresetReverb.mPresetReverbEffect, 135172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi initialLevel) ); 136172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi } else if (pAuxEffect == &ap->mOutputMix->mEnvironmentalReverb.mItf) { 137172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi result = translateEnableFxSendError( 138172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi android_fxSend_attach( ap, (bool) enable, 139172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi ap->mOutputMix->mEnvironmentalReverb.mEnvironmentalReverbEffect, 140172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi initialLevel) ); 141172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi } else { 142172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi result = SL_RESULT_RESOURCE_ERROR; 143172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi } 144172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi } 145172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi#endif 146172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi interface_unlock_exclusive(this); 147ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 148ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 149ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 150ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 15161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 15261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 153ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 15461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IEffectSend_IsEnabled(SLEffectSendItf self, 15561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten const void *pAuxEffect, SLboolean *pEnable) 15661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 157ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 158ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 159ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pEnable) { 160ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 161ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 162ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten IEffectSend *this = (IEffectSend *) self; 163ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect); 164ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == enableLevel) { 165ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 166ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 167ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten interface_lock_peek(this); 168ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLboolean enable = enableLevel->mEnable; 169ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten interface_unlock_peek(this); 170ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pEnable = enable; 171ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 172ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 173ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 174ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 175ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 17661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 17761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 178ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 179d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEffectSend_SetDirectLevel(SLEffectSendItf self, SLmillibel directLevel) 18061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 181ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 182ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 183ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (!((SL_MILLIBEL_MIN <= directLevel) && (directLevel <= 0))) { 184ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 185ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 186ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten IEffectSend *this = (IEffectSend *) self; 187172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi interface_lock_exclusive(this); 188fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi CAudioPlayer *ap = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(this)) ? 189fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi (CAudioPlayer *) this->mThis : NULL; 190fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi if (NULL != ap) { 191fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi SLmillibel oldDirectLevel = ap->mDirectLevel; 192fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi if (oldDirectLevel != directLevel) { 193fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi ap->mDirectLevel = directLevel; 194fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi#if defined(ANDROID) 195172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi ap->mAmplFromDirectLevel = sles_to_android_amplification(directLevel); 196fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi interface_unlock_exclusive_attributes(this, ATTR_GAIN); 197fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi#else 198fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi interface_unlock_exclusive(this); 19991bfd060b992810ca092f640f77f795bc3d008beGlenn Kasten#endif 200fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi } else { 201fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi interface_unlock_exclusive(this); 202fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi } 203fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi result = SL_RESULT_SUCCESS; 204172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi } else { 205172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi interface_unlock_exclusive(this); 206fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi // the interface itself is invalid because it is not attached to an AudioPlayer 207fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi result = SL_RESULT_PARAMETER_INVALID; 208172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi } 209ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 210ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 211ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 21261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 21361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 214ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 215d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEffectSend_GetDirectLevel(SLEffectSendItf self, SLmillibel *pDirectLevel) 21661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 217ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 218ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 219ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pDirectLevel) { 220ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 221ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 222ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten IEffectSend *this = (IEffectSend *) self; 223fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi interface_lock_shared(this); 224fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi CAudioPlayer *ap = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(this)) ? 225fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi (CAudioPlayer *) this->mThis : NULL; 226fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi if (NULL != ap) { 227fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi *pDirectLevel = ap->mDirectLevel; 228fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi result = SL_RESULT_SUCCESS; 229fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi } else { 230fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi // the interface itself is invalid because it is not attached to an AudioPlayer 231fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi result = SL_RESULT_PARAMETER_INVALID; 232fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi } 233fef6033d852daec8d88060b252e72f322724dca1Jean-Michel Trivi interface_unlock_shared(this); 234ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 235ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 236ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 23761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 23861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 239ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 240e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic SLresult IEffectSend_SetSendLevel(SLEffectSendItf self, const void *pAuxEffect, 241e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten SLmillibel sendLevel) 24261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 243ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 244ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 245ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (!((SL_MILLIBEL_MIN <= sendLevel) && (sendLevel <= 0))) { 246ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 247ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 248ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten IEffectSend *this = (IEffectSend *) self; 249ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect); 250ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == enableLevel) { 251ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 252ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 253ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // EnableEffectSend is exclusive, so this has to be also 254ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten interface_lock_exclusive(this); 255ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten enableLevel->mSendLevel = sendLevel; 256172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi#if defined(ANDROID) && !defined(USE_BACKPORT) 257172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi CAudioPlayer *ap = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(this)) ? 258172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi (CAudioPlayer *) this->mThis : NULL; 259172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi if (NULL != ap) { 260172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi android_fxSend_setSendLevel(ap, sendLevel); 261172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi } 262172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi#endif 263ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten interface_unlock_exclusive(this); 264ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 265ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 266ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 267ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 268ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 26961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 27061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 271ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 272e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic SLresult IEffectSend_GetSendLevel(SLEffectSendItf self, const void *pAuxEffect, 273e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten SLmillibel *pSendLevel) 27461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 275ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 276ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 277ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pSendLevel) { 278ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 279ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 280ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten IEffectSend *this = (IEffectSend *) self; 281ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect); 282ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == enableLevel) { 283ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 284ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 285ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten interface_lock_peek(this); 286ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLmillibel sendLevel = enableLevel->mSendLevel; 287ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten interface_unlock_peek(this); 288ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pSendLevel = sendLevel; 289ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 290ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 291ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 292ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 293ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 29461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 29561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 296ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 29761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic const struct SLEffectSendItf_ IEffectSend_Itf = { 29861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IEffectSend_EnableEffectSend, 29961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IEffectSend_IsEnabled, 30061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IEffectSend_SetDirectLevel, 30161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IEffectSend_GetDirectLevel, 30261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IEffectSend_SetSendLevel, 30361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IEffectSend_GetSendLevel 30461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}; 30561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 30661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenvoid IEffectSend_init(void *self) 30761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 30861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IEffectSend *this = (IEffectSend *) self; 30961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten this->mItf = &IEffectSend_Itf; 3106a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten struct EnableLevel *enableLevel = this->mEnableLevels; 3116a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten unsigned aux; 3126a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten for (aux = 0; aux < AUX_MAX; ++aux, ++enableLevel) { 3136a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten enableLevel->mEnable = SL_BOOLEAN_FALSE; 3146a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten enableLevel->mSendLevel = SL_MILLIBEL_MIN; 3156a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten } 31661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 317