| /* | |
| * Copyright (C) 2010 The Android Open Source Project | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| /* MuteSolo implementation */ | |
| #include "sles_allinclusive.h" | |
| static SLresult IMuteSolo_SetChannelMute(SLMuteSoloItf self, SLuint8 chan, SLboolean mute) | |
| { | |
| SL_ENTER_INTERFACE | |
| IMuteSolo *thiz = (IMuteSolo *) self; | |
| IObject *thisObject = thiz->mThis; | |
| if (SL_OBJECTID_AUDIOPLAYER != IObjectToObjectID(thisObject)) { | |
| result = SL_RESULT_FEATURE_UNSUPPORTED; | |
| } else { | |
| CAudioPlayer *ap = (CAudioPlayer *) thisObject; | |
| interface_lock_exclusive(thiz); | |
| SLuint8 numChannels = ap->mNumChannels; | |
| if (1 >= numChannels) { | |
| interface_unlock_exclusive(thiz); | |
| result = SL_RESULT_FEATURE_UNSUPPORTED; | |
| } else if (numChannels <= chan) { | |
| interface_unlock_exclusive(thiz); | |
| result = SL_RESULT_PARAMETER_INVALID; | |
| } else { | |
| SLuint8 mask = 1 << chan; | |
| SLuint8 oldMuteMask = ap->mMuteMask; | |
| if (mute) { | |
| ap->mMuteMask |= mask; | |
| } else { | |
| ap->mMuteMask &= ~mask; | |
| } | |
| interface_unlock_exclusive_attributes(thiz, oldMuteMask != ap->mMuteMask ? ATTR_GAIN : | |
| ATTR_NONE); | |
| result = SL_RESULT_SUCCESS; | |
| } | |
| } | |
| SL_LEAVE_INTERFACE | |
| } | |
| static SLresult IMuteSolo_GetChannelMute(SLMuteSoloItf self, SLuint8 chan, SLboolean *pMute) | |
| { | |
| SL_ENTER_INTERFACE | |
| if (NULL == pMute) { | |
| result = SL_RESULT_PARAMETER_INVALID; | |
| } else { | |
| IMuteSolo *thiz = (IMuteSolo *) self; | |
| IObject *thisObject = thiz->mThis; | |
| if (SL_OBJECTID_AUDIOPLAYER != IObjectToObjectID(thisObject)) { | |
| result = SL_RESULT_FEATURE_UNSUPPORTED; | |
| } else { | |
| CAudioPlayer *ap = (CAudioPlayer *) thisObject; | |
| SLboolean mute; | |
| interface_lock_shared(thiz); | |
| SLuint8 numChannels = ap->mNumChannels; | |
| if (1 >= numChannels) { | |
| mute = SL_BOOLEAN_FALSE; | |
| result = SL_RESULT_FEATURE_UNSUPPORTED; | |
| } else if (numChannels <= chan) { | |
| mute = SL_BOOLEAN_FALSE; | |
| result = SL_RESULT_PARAMETER_INVALID; | |
| } else { | |
| SLuint8 mask = ap->mMuteMask; | |
| mute = (SLboolean) ((mask >> chan) & 1); | |
| result = SL_RESULT_SUCCESS; | |
| } | |
| interface_unlock_shared(thiz); | |
| *pMute = mute; | |
| } | |
| } | |
| SL_LEAVE_INTERFACE | |
| } | |
| static SLresult IMuteSolo_SetChannelSolo(SLMuteSoloItf self, SLuint8 chan, SLboolean solo) | |
| { | |
| SL_ENTER_INTERFACE | |
| IMuteSolo *thiz = (IMuteSolo *) self; | |
| IObject *thisObject = thiz->mThis; | |
| if (SL_OBJECTID_AUDIOPLAYER != IObjectToObjectID(thisObject)) { | |
| result = SL_RESULT_FEATURE_UNSUPPORTED; | |
| } else { | |
| CAudioPlayer *ap = (CAudioPlayer *) thisObject; | |
| interface_lock_exclusive(thiz); | |
| SLuint8 numChannels = ap->mNumChannels; | |
| if (1 >= numChannels) { | |
| interface_unlock_exclusive(thiz); | |
| result = SL_RESULT_FEATURE_UNSUPPORTED; | |
| } else if (numChannels <= chan) { | |
| interface_unlock_exclusive(thiz); | |
| result = SL_RESULT_PARAMETER_INVALID; | |
| } else { | |
| SLuint8 mask = 1 << chan; | |
| SLuint8 oldSoloMask = ap->mSoloMask; | |
| if (solo) { | |
| ap->mSoloMask |= mask; | |
| } else { | |
| ap->mSoloMask &= ~mask; | |
| } | |
| interface_unlock_exclusive_attributes(thiz, oldSoloMask != ap->mSoloMask ? ATTR_GAIN : | |
| ATTR_NONE); | |
| result = SL_RESULT_SUCCESS; | |
| } | |
| } | |
| SL_LEAVE_INTERFACE | |
| } | |
| static SLresult IMuteSolo_GetChannelSolo(SLMuteSoloItf self, SLuint8 chan, SLboolean *pSolo) | |
| { | |
| SL_ENTER_INTERFACE | |
| if (NULL == pSolo) { | |
| result = SL_RESULT_PARAMETER_INVALID; | |
| } else { | |
| IMuteSolo *thiz = (IMuteSolo *) self; | |
| IObject *thisObject = thiz->mThis; | |
| if (SL_OBJECTID_AUDIOPLAYER != IObjectToObjectID(thisObject)) { | |
| result = SL_RESULT_FEATURE_UNSUPPORTED; | |
| } else { | |
| CAudioPlayer *ap = (CAudioPlayer *) thisObject; | |
| SLboolean solo; | |
| interface_lock_shared(thiz); | |
| SLuint8 numChannels = ap->mNumChannels; | |
| if (1 >= numChannels) { | |
| solo = SL_BOOLEAN_FALSE; | |
| result = SL_RESULT_FEATURE_UNSUPPORTED; | |
| } else if (numChannels <= chan) { | |
| solo = SL_BOOLEAN_FALSE; | |
| result = SL_RESULT_PARAMETER_INVALID; | |
| } else { | |
| SLuint8 mask = ap->mSoloMask; | |
| solo = (SLboolean) ((mask >> chan) & 1); | |
| result = SL_RESULT_SUCCESS; | |
| } | |
| interface_unlock_shared(thiz); | |
| *pSolo = solo; | |
| } | |
| } | |
| SL_LEAVE_INTERFACE | |
| } | |
| static SLresult IMuteSolo_GetNumChannels(SLMuteSoloItf self, SLuint8 *pNumChannels) | |
| { | |
| SL_ENTER_INTERFACE | |
| if (NULL == pNumChannels) { | |
| result = SL_RESULT_PARAMETER_INVALID; | |
| } else { | |
| IMuteSolo *thiz = (IMuteSolo *) self; | |
| IObject *thisObject = thiz->mThis; | |
| if (SL_OBJECTID_AUDIOPLAYER != IObjectToObjectID(thisObject)) { | |
| result = SL_RESULT_FEATURE_UNSUPPORTED; | |
| } else { | |
| CAudioPlayer *ap = (CAudioPlayer *) thisObject; | |
| object_lock_shared(thisObject); | |
| SLuint8 numChannels = ap->mNumChannels; | |
| object_unlock_shared(thisObject); | |
| *pNumChannels = numChannels; | |
| // spec errata says to return 0 (== UNKNOWN_NUMCHANNELS) if channel count is unknown | |
| result = SL_RESULT_SUCCESS; | |
| } | |
| } | |
| SL_LEAVE_INTERFACE | |
| } | |
| static const struct SLMuteSoloItf_ IMuteSolo_Itf = { | |
| IMuteSolo_SetChannelMute, | |
| IMuteSolo_GetChannelMute, | |
| IMuteSolo_SetChannelSolo, | |
| IMuteSolo_GetChannelSolo, | |
| IMuteSolo_GetNumChannels | |
| }; | |
| void IMuteSolo_init(void *self) | |
| { | |
| IMuteSolo *thiz = (IMuteSolo *) self; | |
| thiz->mItf = &IMuteSolo_Itf; | |
| } |