IEffectSend.c revision ed46c29d6a09112dbbf584c82953f63289596fd6
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
67ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
6861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IEffectSend_EnableEffectSend(SLEffectSendItf self,
6961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    const void *pAuxEffect, SLboolean enable, SLmillibel initialLevel)
7061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
71ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
72ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
73ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (!((SL_MILLIBEL_MIN <= initialLevel) && (initialLevel <= 0))) {
74ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
75ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
76ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEffectSend *this = (IEffectSend *) self;
77ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect);
78ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL == enableLevel) {
79ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
80ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
81ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_lock_exclusive(this);
82ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            enableLevel->mEnable = SL_BOOLEAN_FALSE != enable; // normalize
83ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            enableLevel->mSendLevel = initialLevel;
84ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_unlock_exclusive(this);
85ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
86ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
87ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
88ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
89ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
9061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
9161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
92ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
9361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IEffectSend_IsEnabled(SLEffectSendItf self,
9461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    const void *pAuxEffect, SLboolean *pEnable)
9561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
96ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
97ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
98ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pEnable) {
99ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
100ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
101ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEffectSend *this = (IEffectSend *) self;
102ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect);
103ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL == enableLevel) {
104ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
105ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
106ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_lock_peek(this);
107ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            SLboolean enable = enableLevel->mEnable;
108ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_unlock_peek(this);
109ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *pEnable = enable;
110ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
111ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
112ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
113ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
114ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
11561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
11661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
117ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
118d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEffectSend_SetDirectLevel(SLEffectSendItf self, SLmillibel directLevel)
11961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
120ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
121ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
122ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (!((SL_MILLIBEL_MIN <= directLevel) && (directLevel <= 0))) {
123ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
124ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
125ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEffectSend *this = (IEffectSend *) self;
126ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_lock_poke(this);
127ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        this->mDirectLevel = directLevel;
128ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_unlock_poke(this);
129ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
130ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
131ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
132ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
13361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
13461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
135ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
136d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEffectSend_GetDirectLevel(SLEffectSendItf self, SLmillibel *pDirectLevel)
13761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
138ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
139ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
140ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pDirectLevel) {
141ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
142ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
143ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEffectSend *this = (IEffectSend *) self;
144ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_lock_peek(this);
145ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        SLmillibel directLevel = this->mDirectLevel;
146ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_unlock_peek(this);
147ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pDirectLevel = directLevel;
148ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
149ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
150ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
151ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
15261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
15361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
154ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
155e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic SLresult IEffectSend_SetSendLevel(SLEffectSendItf self, const void *pAuxEffect,
156e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    SLmillibel sendLevel)
15761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
158ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
159ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
160ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (!((SL_MILLIBEL_MIN <= sendLevel) && (sendLevel <= 0))) {
161ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
162ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
163ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEffectSend *this = (IEffectSend *) self;
164ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect);
165ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL == enableLevel) {
166ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
167ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
168ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            // EnableEffectSend is exclusive, so this has to be also
169ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_lock_exclusive(this);
170ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            enableLevel->mSendLevel = sendLevel;
171ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_unlock_exclusive(this);
172ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
173ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
174ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
175ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
176ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
17761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
17861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
179ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
180e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic SLresult IEffectSend_GetSendLevel(SLEffectSendItf self, const void *pAuxEffect,
181e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    SLmillibel *pSendLevel)
18261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
183ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
184ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
185ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pSendLevel) {
186ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
187ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
188ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEffectSend *this = (IEffectSend *) self;
189ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        struct EnableLevel *enableLevel = getEnableLevel(this, pAuxEffect);
190ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL == enableLevel) {
191ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
192ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
193ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_lock_peek(this);
194ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            SLmillibel sendLevel = enableLevel->mSendLevel;
195ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            interface_unlock_peek(this);
196ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *pSendLevel = sendLevel;
197ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
198ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
199ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
200ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
201ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
20261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
20361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
204ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
20561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic const struct SLEffectSendItf_ IEffectSend_Itf = {
20661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_EnableEffectSend,
20761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_IsEnabled,
20861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_SetDirectLevel,
20961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_GetDirectLevel,
21061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_SetSendLevel,
21161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend_GetSendLevel
21261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten};
21361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
21461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenvoid IEffectSend_init(void *self)
21561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
21661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IEffectSend *this = (IEffectSend *) self;
21761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mItf = &IEffectSend_Itf;
2186a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten    this->mOutputMix = NULL; // CAudioPlayer will need to re-initialize
21961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mDirectLevel = 0;
2206a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten    struct EnableLevel *enableLevel = this->mEnableLevels;
2216a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten    unsigned aux;
2226a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten    for (aux = 0; aux < AUX_MAX; ++aux, ++enableLevel) {
2236a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten        enableLevel->mEnable = SL_BOOLEAN_FALSE;
2246a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten        enableLevel->mSendLevel = SL_MILLIBEL_MIN;
2256a357b8fa57b0bc1557cd5ab9f9fb86aabaaa18cGlenn Kasten    }
22661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
227