IEffectSend.c revision e5d006b298ce7683d66f7ec86136403cf5fb20d6
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
85ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
8661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IEffectSend_EnableEffectSend(SLEffectSendItf self,
8761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    const void *pAuxEffect, SLboolean enable, SLmillibel initialLevel)
8861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
89ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
90ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
91ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (!((SL_MILLIBEL_MIN <= initialLevel) && (initialLevel <= 0))) {
92ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
93ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
94ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEffectSend *this = (IEffectSend *) self;
95ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect);
96ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL == enableLevel) {
97ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
98ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
99ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_lock_exclusive(this);
100ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            enableLevel->mEnable = SL_BOOLEAN_FALSE != enable; // normalize
101ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            enableLevel->mSendLevel = initialLevel;
102ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_unlock_exclusive(this);
103ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
104ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
105ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
106ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
107ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
10861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
10961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
110ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
11161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IEffectSend_IsEnabled(SLEffectSendItf self,
11261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    const void *pAuxEffect, SLboolean *pEnable)
11361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
114ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
115ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
116ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pEnable) {
117ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
118ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
119ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEffectSend *this = (IEffectSend *) self;
120ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect);
121ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL == enableLevel) {
122ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
123ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
124ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_lock_peek(this);
125ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            SLboolean enable = enableLevel->mEnable;
126ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_unlock_peek(this);
127ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *pEnable = enable;
128ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
129ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
130ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
131ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
132ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
13361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
13461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
135ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
136d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEffectSend_SetDirectLevel(SLEffectSendItf self, SLmillibel directLevel)
13761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
138ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
139ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
140ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (!((SL_MILLIBEL_MIN <= directLevel) && (directLevel <= 0))) {
141ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
142ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
143ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEffectSend *this = (IEffectSend *) self;
144ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_lock_poke(this);
145ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        this->mDirectLevel = directLevel;
146ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_unlock_poke(this);
147ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
148ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
149ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
150ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
15161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
15261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
153ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
154d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEffectSend_GetDirectLevel(SLEffectSendItf self, SLmillibel *pDirectLevel)
15561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
156ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
157ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
158ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pDirectLevel) {
159ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
160ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
161ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEffectSend *this = (IEffectSend *) self;
162ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_lock_peek(this);
163ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        SLmillibel directLevel = this->mDirectLevel;
164ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_unlock_peek(this);
165ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pDirectLevel = directLevel;
166ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
167ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
168ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
169ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
17061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
17161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
172ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
173e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic SLresult IEffectSend_SetSendLevel(SLEffectSendItf self, const void *pAuxEffect,
174e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    SLmillibel sendLevel)
17561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
176ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
177ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
178ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (!((SL_MILLIBEL_MIN <= sendLevel) && (sendLevel <= 0))) {
179ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
180ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
181ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEffectSend *this = (IEffectSend *) self;
182ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect);
183ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL == enableLevel) {
184ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
185ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
186ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            // EnableEffectSend is exclusive, so this has to be also
187ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_lock_exclusive(this);
188ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            enableLevel->mSendLevel = sendLevel;
189ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_unlock_exclusive(this);
190ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
191ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
192ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
193ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
194ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
19561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
19661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
197ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
198e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic SLresult IEffectSend_GetSendLevel(SLEffectSendItf self, const void *pAuxEffect,
199e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    SLmillibel *pSendLevel)
20061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
201ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
202ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
203ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pSendLevel) {
204ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
205ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
206ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEffectSend *this = (IEffectSend *) self;
207ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect);
208ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL == enableLevel) {
209ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
210ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
211ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_lock_peek(this);
212ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            SLmillibel sendLevel = enableLevel->mSendLevel;
213ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_unlock_peek(this);
214ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *pSendLevel = sendLevel;
215ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
216ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
217ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
218ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
219ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
22061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
22161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
222ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
22361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic const struct SLEffectSendItf_ IEffectSend_Itf = {
22461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_EnableEffectSend,
22561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_IsEnabled,
22661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_SetDirectLevel,
22761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_GetDirectLevel,
22861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_SetSendLevel,
22961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_GetSendLevel
23061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten};
23161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
23261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenvoid IEffectSend_init(void *self)
23361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
23461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend *this = (IEffectSend *) self;
23561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mItf = &IEffectSend_Itf;
23661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mDirectLevel = 0;
2376a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten    struct EnableLevel *enableLevel = this->mEnableLevels;
2386a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten    unsigned aux;
2396a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten    for (aux = 0; aux < AUX_MAX; ++aux, ++enableLevel) {
2406a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten        enableLevel->mEnable = SL_BOOLEAN_FALSE;
2416a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten        enableLevel->mSendLevel = SL_MILLIBEL_MIN;
2426a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten    }
24361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
244