IEffectSend.cpp revision 510f3671f716f6835282e4b0fd0275c20e9dadd8
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
21510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten// Maps AUX index to OutputMix interface index
22510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten
23510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kastenstatic const unsigned char AUX_to_MPH[AUX_MAX] = {
24510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    MPH_ENVIRONMENTALREVERB,
25510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    MPH_PRESETREVERB
26510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten};
27510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten
28d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic struct EnableLevel *getEnableLevel(IEffectSend *this, const void *pAuxEffect)
2961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
3061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    COutputMix *outputMix = this->mOutputMix;
3161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    // Make sure the sink for this player is an output mix
3261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (NULL == outputMix)
3361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        return NULL;
34510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    unsigned aux;
35510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    if (pAuxEffect == &outputMix->mEnvironmentalReverb.mItf)
36510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten        aux = AUX_ENVIRONMENTALREVERB;
37510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    else if (pAuxEffect == &outputMix->mPresetReverb.mItf)
38510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten        aux = AUX_PRESETREVERB;
39510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    else
40510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten        return NULL;
41510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    assert(aux < AUX_MAX);
42510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    // App couldn't have an interface for effect without exposure
43510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    int index = MPH_to_OutputMix[AUX_to_MPH[aux]];
44510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    if (0 > index)
45510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten        return NULL;
46510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    unsigned mask = 1 << index;
47510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    object_lock_shared(&outputMix->mObject);
48510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    SLuint32 state = outputMix->mObject.mInterfaceStates[index];
49510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    mask &= outputMix->mObject.mGottenMask;
50510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    object_unlock_shared(&outputMix->mObject);
51510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    switch (state) {
52510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    case INTERFACE_EXPOSED:
53510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    case INTERFACE_ADDED:
54510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    case INTERFACE_SUSPENDED:
55510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    case INTERFACE_SUSPENDING:
56510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    case INTERFACE_RESUMING_1:
57510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    case INTERFACE_RESUMING_2:
58510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten        if (mask)
59510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten            return &this->mEnableLevels[aux];
60510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten        break;
61510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    default:
62510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten        break;
63510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    }
6461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    return NULL;
6561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
6661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
6761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IEffectSend_EnableEffectSend(SLEffectSendItf self,
6861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    const void *pAuxEffect, SLboolean enable, SLmillibel initialLevel)
6961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
70d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten    if (!((SL_MILLIBEL_MIN <= initialLevel) && (initialLevel <= 0)))
71d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
7261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend *this = (IEffectSend *) self;
7361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect);
7461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (NULL == enableLevel)
7561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
7661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    interface_lock_exclusive(this);
77d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten    enableLevel->mEnable = SL_BOOLEAN_FALSE != enable; // normalize
7861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    enableLevel->mSendLevel = initialLevel;
7961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    interface_unlock_exclusive(this);
8061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    return SL_RESULT_SUCCESS;
8161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
8261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
8361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IEffectSend_IsEnabled(SLEffectSendItf self,
8461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    const void *pAuxEffect, SLboolean *pEnable)
8561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
8661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (NULL == pEnable)
8761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
8861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend *this = (IEffectSend *) self;
8961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect);
9061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (NULL == enableLevel)
9161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
9261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    interface_lock_peek(this);
9361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    SLboolean enable = enableLevel->mEnable;
9461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    interface_unlock_peek(this);
9561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    *pEnable = enable;
9661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    return SL_RESULT_SUCCESS;
9761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
9861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
99d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEffectSend_SetDirectLevel(SLEffectSendItf self, SLmillibel directLevel)
10061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
101d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten    if (!((SL_MILLIBEL_MIN <= directLevel) && (directLevel <= 0)))
102d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
10361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend *this = (IEffectSend *) self;
10461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    interface_lock_poke(this);
10561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mDirectLevel = directLevel;
10661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    interface_unlock_poke(this);
10761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    return SL_RESULT_SUCCESS;
10861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
10961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
110d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEffectSend_GetDirectLevel(SLEffectSendItf self, SLmillibel *pDirectLevel)
11161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
11261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (NULL == pDirectLevel)
11361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
11461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend *this = (IEffectSend *) self;
11561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    interface_lock_peek(this);
11661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    SLmillibel directLevel = this->mDirectLevel;
11761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    interface_unlock_peek(this);
11861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    *pDirectLevel = directLevel;
11961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    return SL_RESULT_SUCCESS;
12061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
12161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
122d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEffectSend_SetSendLevel(SLEffectSendItf self, const void *pAuxEffect, SLmillibel sendLevel)
12361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
124d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten    if (!((SL_MILLIBEL_MIN <= sendLevel) && (sendLevel <= 0)))
125d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
12661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend *this = (IEffectSend *) self;
12761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect);
12861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (NULL == enableLevel)
12961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
13061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    // EnableEffectSend is exclusive, so this has to be also
13161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    interface_lock_exclusive(this);
13261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    enableLevel->mSendLevel = sendLevel;
13361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    interface_unlock_exclusive(this);
13461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    return SL_RESULT_SUCCESS;
13561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
13661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
137d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEffectSend_GetSendLevel(SLEffectSendItf self, const void *pAuxEffect, SLmillibel *pSendLevel)
13861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
13961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (NULL == pSendLevel)
14061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
14161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend *this = (IEffectSend *) self;
14261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect);
14361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (NULL == enableLevel)
14461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
14561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    interface_lock_peek(this);
14661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    SLmillibel sendLevel = enableLevel->mSendLevel;
14761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    interface_unlock_peek(this);
14861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    *pSendLevel = sendLevel;
14961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    return SL_RESULT_SUCCESS;
15061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
15161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
15261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic const struct SLEffectSendItf_ IEffectSend_Itf = {
15361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_EnableEffectSend,
15461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_IsEnabled,
15561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_SetDirectLevel,
15661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_GetDirectLevel,
15761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_SetSendLevel,
15861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_GetSendLevel
15961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten};
16061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
16161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenvoid IEffectSend_init(void *self)
16261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
16361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend *this = (IEffectSend *) self;
16461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mItf = &IEffectSend_Itf;
16561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mOutputMix = NULL; // FIXME wrong
16661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mDirectLevel = 0;
1670b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // FIXME hard-coded array initialization should be loop on AUX_MAX
16861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mEnableLevels[AUX_ENVIRONMENTALREVERB].mEnable = SL_BOOLEAN_FALSE;
169d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten    this->mEnableLevels[AUX_ENVIRONMENTALREVERB].mSendLevel = SL_MILLIBEL_MIN;
17061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mEnableLevels[AUX_PRESETREVERB].mEnable = SL_BOOLEAN_FALSE;
171d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten    this->mEnableLevels[AUX_PRESETREVERB].mSendLevel = SL_MILLIBEL_MIN;
17261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
173