| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 1 | /* | 
 | 2 | ** | 
 | 3 | ** Copyright 2010, The Android Open Source Project | 
 | 4 | ** | 
 | 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 6 | ** you may not use this file except in compliance with the License. | 
 | 7 | ** You may obtain a copy of the License at | 
 | 8 | ** | 
 | 9 | **     http://www.apache.org/licenses/LICENSE-2.0 | 
 | 10 | ** | 
 | 11 | ** Unless required by applicable law or agreed to in writing, software | 
 | 12 | ** distributed under the License is distributed on an "AS IS" BASIS, | 
 | 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 14 | ** See the License for the specific language governing permissions and | 
 | 15 | ** limitations under the License. | 
 | 16 | */ | 
 | 17 |  | 
 | 18 |  | 
 | 19 | //#define LOG_NDEBUG 0 | 
 | 20 | #define LOG_TAG "AudioEffect" | 
 | 21 |  | 
 | 22 | #include <stdint.h> | 
 | 23 | #include <sys/types.h> | 
 | 24 | #include <limits.h> | 
 | 25 |  | 
 | 26 | #include <private/media/AudioEffectShared.h> | 
 | 27 | #include <media/AudioEffect.h> | 
 | 28 |  | 
 | 29 | #include <utils/Log.h> | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 30 | #include <binder/IPCThreadState.h> | 
 | 31 |  | 
 | 32 |  | 
 | 33 |  | 
 | 34 | namespace android { | 
 | 35 |  | 
 | 36 | // --------------------------------------------------------------------------- | 
 | 37 |  | 
| Svet Ganov | be71aa2 | 2015-04-28 12:06:02 -0700 | [diff] [blame] | 38 | AudioEffect::AudioEffect(const String16& opPackageName) | 
 | 39 |     : mStatus(NO_INIT), mOpPackageName(opPackageName) | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 40 | { | 
 | 41 | } | 
 | 42 |  | 
 | 43 |  | 
 | 44 | AudioEffect::AudioEffect(const effect_uuid_t *type, | 
| Svet Ganov | be71aa2 | 2015-04-28 12:06:02 -0700 | [diff] [blame] | 45 |                 const String16& opPackageName, | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 46 |                 const effect_uuid_t *uuid, | 
 | 47 |                 int32_t priority, | 
 | 48 |                 effect_callback_t cbf, | 
 | 49 |                 void* user, | 
| Glenn Kasten | d848eb4 | 2016-03-08 13:42:11 -0800 | [diff] [blame] | 50 |                 audio_session_t sessionId, | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 51 |                 audio_io_handle_t io | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 52 |                 ) | 
| Svet Ganov | be71aa2 | 2015-04-28 12:06:02 -0700 | [diff] [blame] | 53 |     : mStatus(NO_INIT), mOpPackageName(opPackageName) | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 54 | { | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 55 |     mStatus = set(type, uuid, priority, cbf, user, sessionId, io); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 56 | } | 
 | 57 |  | 
 | 58 | AudioEffect::AudioEffect(const char *typeStr, | 
| Svet Ganov | be71aa2 | 2015-04-28 12:06:02 -0700 | [diff] [blame] | 59 |                 const String16& opPackageName, | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 60 |                 const char *uuidStr, | 
 | 61 |                 int32_t priority, | 
 | 62 |                 effect_callback_t cbf, | 
 | 63 |                 void* user, | 
| Glenn Kasten | d848eb4 | 2016-03-08 13:42:11 -0800 | [diff] [blame] | 64 |                 audio_session_t sessionId, | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 65 |                 audio_io_handle_t io | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 66 |                 ) | 
| Svet Ganov | be71aa2 | 2015-04-28 12:06:02 -0700 | [diff] [blame] | 67 |     : mStatus(NO_INIT), mOpPackageName(opPackageName) | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 68 | { | 
 | 69 |     effect_uuid_t type; | 
 | 70 |     effect_uuid_t *pType = NULL; | 
 | 71 |     effect_uuid_t uuid; | 
 | 72 |     effect_uuid_t *pUuid = NULL; | 
 | 73 |  | 
| Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 74 |     ALOGV("Constructor string\n - type: %s\n - uuid: %s", typeStr, uuidStr); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 75 |  | 
 | 76 |     if (typeStr != NULL) { | 
 | 77 |         if (stringToGuid(typeStr, &type) == NO_ERROR) { | 
 | 78 |             pType = &type; | 
 | 79 |         } | 
 | 80 |     } | 
 | 81 |  | 
 | 82 |     if (uuidStr != NULL) { | 
 | 83 |         if (stringToGuid(uuidStr, &uuid) == NO_ERROR) { | 
 | 84 |             pUuid = &uuid; | 
 | 85 |         } | 
 | 86 |     } | 
 | 87 |  | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 88 |     mStatus = set(pType, pUuid, priority, cbf, user, sessionId, io); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 89 | } | 
 | 90 |  | 
 | 91 | status_t AudioEffect::set(const effect_uuid_t *type, | 
 | 92 |                 const effect_uuid_t *uuid, | 
 | 93 |                 int32_t priority, | 
 | 94 |                 effect_callback_t cbf, | 
 | 95 |                 void* user, | 
| Glenn Kasten | d848eb4 | 2016-03-08 13:42:11 -0800 | [diff] [blame] | 96 |                 audio_session_t sessionId, | 
| Eric Laurent | 7c7f10b | 2011-06-17 21:29:58 -0700 | [diff] [blame] | 97 |                 audio_io_handle_t io) | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 98 | { | 
 | 99 |     sp<IEffect> iEffect; | 
 | 100 |     sp<IMemory> cblk; | 
 | 101 |     int enabled; | 
 | 102 |  | 
| Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 103 |     ALOGV("set %p mUserData: %p uuid: %p timeLow %08x", this, user, type, type ? type->timeLow : 0); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 104 |  | 
 | 105 |     if (mIEffect != 0) { | 
| Steve Block | 5ff1dd5 | 2012-01-05 23:22:43 +0000 | [diff] [blame] | 106 |         ALOGW("Effect already in use"); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 107 |         return INVALID_OPERATION; | 
 | 108 |     } | 
 | 109 |  | 
 | 110 |     const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); | 
 | 111 |     if (audioFlinger == 0) { | 
| Steve Block | 29357bc | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 112 |         ALOGE("set(): Could not get audioflinger"); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 113 |         return NO_INIT; | 
 | 114 |     } | 
 | 115 |  | 
 | 116 |     if (type == NULL && uuid == NULL) { | 
| Steve Block | 5ff1dd5 | 2012-01-05 23:22:43 +0000 | [diff] [blame] | 117 |         ALOGW("Must specify at least type or uuid"); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 118 |         return BAD_VALUE; | 
 | 119 |     } | 
 | 120 |  | 
 | 121 |     mPriority = priority; | 
 | 122 |     mCbf = cbf; | 
 | 123 |     mUserData = user; | 
 | 124 |     mSessionId = sessionId; | 
 | 125 |  | 
 | 126 |     memset(&mDescriptor, 0, sizeof(effect_descriptor_t)); | 
| Glenn Kasten | a189a68 | 2012-02-20 12:16:30 -0800 | [diff] [blame] | 127 |     mDescriptor.type = *(type != NULL ? type : EFFECT_UUID_NULL); | 
 | 128 |     mDescriptor.uuid = *(uuid != NULL ? uuid : EFFECT_UUID_NULL); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 129 |  | 
 | 130 |     mIEffectClient = new EffectClient(this); | 
 | 131 |  | 
| Glenn Kasten | 8d6cc84 | 2012-02-03 11:06:53 -0800 | [diff] [blame] | 132 |     iEffect = audioFlinger->createEffect((effect_descriptor_t *)&mDescriptor, | 
| Svet Ganov | be71aa2 | 2015-04-28 12:06:02 -0700 | [diff] [blame] | 133 |             mIEffectClient, priority, io, mSessionId, mOpPackageName, &mStatus, &mId, &enabled); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 134 |  | 
 | 135 |     if (iEffect == 0 || (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS)) { | 
| Steve Block | 29357bc | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 136 |         ALOGE("set(): AudioFlinger could not create effect, status: %d", mStatus); | 
| Eric Laurent | eecd765 | 2015-06-04 16:20:16 -0700 | [diff] [blame] | 137 |         if (iEffect == 0) { | 
 | 138 |             mStatus = NO_INIT; | 
 | 139 |         } | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 140 |         return mStatus; | 
 | 141 |     } | 
 | 142 |  | 
 | 143 |     mEnabled = (volatile int32_t)enabled; | 
 | 144 |  | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 145 |     cblk = iEffect->getCblk(); | 
 | 146 |     if (cblk == 0) { | 
 | 147 |         mStatus = NO_INIT; | 
| Steve Block | 29357bc | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 148 |         ALOGE("Could not get control block"); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 149 |         return mStatus; | 
 | 150 |     } | 
 | 151 |  | 
| Eric Laurent | eecd765 | 2015-06-04 16:20:16 -0700 | [diff] [blame] | 152 |     mIEffect = iEffect; | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 153 |     mCblkMemory = cblk; | 
 | 154 |     mCblk = static_cast<effect_param_cblk_t*>(cblk->pointer()); | 
 | 155 |     int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int); | 
 | 156 |     mCblk->buffer = (uint8_t *)mCblk + bufOffset; | 
 | 157 |  | 
| Marco Nelissen | 06b4606 | 2014-11-14 07:58:25 -0800 | [diff] [blame] | 158 |     IInterface::asBinder(iEffect)->linkToDeath(mIEffectClient); | 
| Jean-Michel Trivi | a0fd9ca | 2014-09-18 14:07:18 -0700 | [diff] [blame] | 159 |     mClientPid = IPCThreadState::self()->getCallingPid(); | 
 | 160 |     ALOGV("set() %p OK effect: %s id: %d status %d enabled %d pid %d", this, mDescriptor.name, mId, | 
 | 161 |             mStatus, mEnabled, mClientPid); | 
 | 162 |  | 
 | 163 |     if (mSessionId > AUDIO_SESSION_OUTPUT_MIX) { | 
 | 164 |         AudioSystem::acquireAudioSessionId(mSessionId, mClientPid); | 
 | 165 |     } | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 166 |  | 
 | 167 |     return mStatus; | 
 | 168 | } | 
 | 169 |  | 
 | 170 |  | 
 | 171 | AudioEffect::~AudioEffect() | 
 | 172 | { | 
| Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 173 |     ALOGV("Destructor %p", this); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 174 |  | 
 | 175 |     if (mStatus == NO_ERROR || mStatus == ALREADY_EXISTS) { | 
| Jean-Michel Trivi | a0fd9ca | 2014-09-18 14:07:18 -0700 | [diff] [blame] | 176 |         if (mSessionId > AUDIO_SESSION_OUTPUT_MIX) { | 
 | 177 |             AudioSystem::releaseAudioSessionId(mSessionId, mClientPid); | 
 | 178 |         } | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 179 |         if (mIEffect != NULL) { | 
 | 180 |             mIEffect->disconnect(); | 
| Marco Nelissen | 06b4606 | 2014-11-14 07:58:25 -0800 | [diff] [blame] | 181 |             IInterface::asBinder(mIEffect)->unlinkToDeath(mIEffectClient); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 182 |         } | 
| Eric Laurent | eecd765 | 2015-06-04 16:20:16 -0700 | [diff] [blame] | 183 |         mIEffect.clear(); | 
 | 184 |         mCblkMemory.clear(); | 
 | 185 |         mIEffectClient.clear(); | 
| Glenn Kasten | e53b9ea | 2012-03-12 16:29:55 -0700 | [diff] [blame] | 186 |         IPCThreadState::self()->flushCommands(); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 187 |     } | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 188 | } | 
 | 189 |  | 
 | 190 |  | 
 | 191 | status_t AudioEffect::initCheck() const | 
 | 192 | { | 
 | 193 |     return mStatus; | 
 | 194 | } | 
 | 195 |  | 
 | 196 | // ------------------------------------------------------------------------- | 
 | 197 |  | 
 | 198 | effect_descriptor_t AudioEffect::descriptor() const | 
 | 199 | { | 
 | 200 |     return mDescriptor; | 
 | 201 | } | 
 | 202 |  | 
| Eric Laurent | da7581b | 2010-07-02 08:12:41 -0700 | [diff] [blame] | 203 | bool AudioEffect::getEnabled() const | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 204 | { | 
 | 205 |     return (mEnabled != 0); | 
 | 206 | } | 
 | 207 |  | 
| Eric Laurent | da7581b | 2010-07-02 08:12:41 -0700 | [diff] [blame] | 208 | status_t AudioEffect::setEnabled(bool enabled) | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 209 | { | 
 | 210 |     if (mStatus != NO_ERROR) { | 
| Glenn Kasten | f063b49 | 2012-02-17 16:24:10 -0800 | [diff] [blame] | 211 |         return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus; | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 212 |     } | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 213 |  | 
| Eric Laurent | f5aafb2 | 2010-11-18 08:40:16 -0800 | [diff] [blame] | 214 |     status_t status = NO_ERROR; | 
 | 215 |  | 
 | 216 |     AutoMutex lock(mLock); | 
 | 217 |     if (enabled != mEnabled) { | 
 | 218 |         if (enabled) { | 
| Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 219 |             ALOGV("enable %p", this); | 
| Eric Laurent | f5aafb2 | 2010-11-18 08:40:16 -0800 | [diff] [blame] | 220 |             status = mIEffect->enable(); | 
 | 221 |         } else { | 
| Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 222 |             ALOGV("disable %p", this); | 
| Eric Laurent | f5aafb2 | 2010-11-18 08:40:16 -0800 | [diff] [blame] | 223 |             status = mIEffect->disable(); | 
| Eric Laurent | da7581b | 2010-07-02 08:12:41 -0700 | [diff] [blame] | 224 |         } | 
| Eric Laurent | f5aafb2 | 2010-11-18 08:40:16 -0800 | [diff] [blame] | 225 |         if (status == NO_ERROR) { | 
 | 226 |             mEnabled = enabled; | 
| Eric Laurent | da7581b | 2010-07-02 08:12:41 -0700 | [diff] [blame] | 227 |         } | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 228 |     } | 
| Eric Laurent | f5aafb2 | 2010-11-18 08:40:16 -0800 | [diff] [blame] | 229 |     return status; | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 230 | } | 
 | 231 |  | 
| Eric Laurent | 25f4395 | 2010-07-28 05:40:18 -0700 | [diff] [blame] | 232 | status_t AudioEffect::command(uint32_t cmdCode, | 
 | 233 |                               uint32_t cmdSize, | 
 | 234 |                               void *cmdData, | 
 | 235 |                               uint32_t *replySize, | 
 | 236 |                               void *replyData) | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 237 | { | 
 | 238 |     if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) { | 
| Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 239 |         ALOGV("command() bad status %d", mStatus); | 
| John Grossman | af7d818 | 2012-01-11 12:23:42 -0800 | [diff] [blame] | 240 |         return mStatus; | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 241 |     } | 
 | 242 |  | 
| Eric Laurent | f5aafb2 | 2010-11-18 08:40:16 -0800 | [diff] [blame] | 243 |     if (cmdCode == EFFECT_CMD_ENABLE || cmdCode == EFFECT_CMD_DISABLE) { | 
 | 244 |         if (mEnabled == (cmdCode == EFFECT_CMD_ENABLE)) { | 
 | 245 |             return NO_ERROR; | 
 | 246 |         } | 
 | 247 |         if (replySize == NULL || *replySize != sizeof(status_t) || replyData == NULL) { | 
 | 248 |             return BAD_VALUE; | 
 | 249 |         } | 
 | 250 |         mLock.lock(); | 
| Eric Laurent | 0fa449c | 2010-09-24 11:52:04 -0700 | [diff] [blame] | 251 |     } | 
 | 252 |  | 
| Eric Laurent | 8569f0d | 2010-07-29 23:43:43 -0700 | [diff] [blame] | 253 |     status_t status = mIEffect->command(cmdCode, cmdSize, cmdData, replySize, replyData); | 
| Eric Laurent | 0fa449c | 2010-09-24 11:52:04 -0700 | [diff] [blame] | 254 |  | 
 | 255 |     if (cmdCode == EFFECT_CMD_ENABLE || cmdCode == EFFECT_CMD_DISABLE) { | 
| Eric Laurent | f5aafb2 | 2010-11-18 08:40:16 -0800 | [diff] [blame] | 256 |         if (status == NO_ERROR) { | 
 | 257 |             status = *(status_t *)replyData; | 
| Eric Laurent | 0fa449c | 2010-09-24 11:52:04 -0700 | [diff] [blame] | 258 |         } | 
| Eric Laurent | f5aafb2 | 2010-11-18 08:40:16 -0800 | [diff] [blame] | 259 |         if (status == NO_ERROR) { | 
 | 260 |             mEnabled = (cmdCode == EFFECT_CMD_ENABLE); | 
| Eric Laurent | 0fa449c | 2010-09-24 11:52:04 -0700 | [diff] [blame] | 261 |         } | 
| Eric Laurent | f5aafb2 | 2010-11-18 08:40:16 -0800 | [diff] [blame] | 262 |         mLock.unlock(); | 
| Eric Laurent | 8569f0d | 2010-07-29 23:43:43 -0700 | [diff] [blame] | 263 |     } | 
 | 264 |  | 
| Eric Laurent | 8569f0d | 2010-07-29 23:43:43 -0700 | [diff] [blame] | 265 |     return status; | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 266 | } | 
 | 267 |  | 
 | 268 |  | 
 | 269 | status_t AudioEffect::setParameter(effect_param_t *param) | 
 | 270 | { | 
 | 271 |     if (mStatus != NO_ERROR) { | 
| Glenn Kasten | f063b49 | 2012-02-17 16:24:10 -0800 | [diff] [blame] | 272 |         return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus; | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 273 |     } | 
 | 274 |  | 
 | 275 |     if (param == NULL || param->psize == 0 || param->vsize == 0) { | 
 | 276 |         return BAD_VALUE; | 
 | 277 |     } | 
 | 278 |  | 
| Eric Laurent | 25f4395 | 2010-07-28 05:40:18 -0700 | [diff] [blame] | 279 |     uint32_t size = sizeof(int); | 
 | 280 |     uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize; | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 281 |  | 
| Glenn Kasten | 85ab62c | 2012-11-01 11:11:38 -0700 | [diff] [blame] | 282 |     ALOGV("setParameter: param: %d, param2: %d", *(int *)param->data, | 
 | 283 |             (param->psize == 8) ? *((int *)param->data + 1): -1); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 284 |  | 
| Glenn Kasten | 85ab62c | 2012-11-01 11:11:38 -0700 | [diff] [blame] | 285 |     return mIEffect->command(EFFECT_CMD_SET_PARAM, sizeof (effect_param_t) + psize, param, &size, | 
 | 286 |             ¶m->status); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 287 | } | 
 | 288 |  | 
 | 289 | status_t AudioEffect::setParameterDeferred(effect_param_t *param) | 
 | 290 | { | 
 | 291 |     if (mStatus != NO_ERROR) { | 
| Glenn Kasten | f063b49 | 2012-02-17 16:24:10 -0800 | [diff] [blame] | 292 |         return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus; | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 293 |     } | 
 | 294 |  | 
 | 295 |     if (param == NULL || param->psize == 0 || param->vsize == 0) { | 
 | 296 |         return BAD_VALUE; | 
 | 297 |     } | 
 | 298 |  | 
 | 299 |     Mutex::Autolock _l(mCblk->lock); | 
 | 300 |  | 
 | 301 |     int psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize; | 
 | 302 |     int size = ((sizeof(effect_param_t) + psize - 1) / sizeof(int) + 1) * sizeof(int); | 
 | 303 |  | 
 | 304 |     if (mCblk->clientIndex + size > EFFECT_PARAM_BUFFER_SIZE) { | 
 | 305 |         return NO_MEMORY; | 
 | 306 |     } | 
 | 307 |     int *p = (int *)(mCblk->buffer + mCblk->clientIndex); | 
 | 308 |     *p++ = size; | 
 | 309 |     memcpy(p, param, sizeof(effect_param_t) + psize); | 
 | 310 |     mCblk->clientIndex += size; | 
 | 311 |  | 
 | 312 |     return NO_ERROR; | 
 | 313 | } | 
 | 314 |  | 
 | 315 | status_t AudioEffect::setParameterCommit() | 
 | 316 | { | 
 | 317 |     if (mStatus != NO_ERROR) { | 
| Glenn Kasten | f063b49 | 2012-02-17 16:24:10 -0800 | [diff] [blame] | 318 |         return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus; | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 319 |     } | 
 | 320 |  | 
 | 321 |     Mutex::Autolock _l(mCblk->lock); | 
 | 322 |     if (mCblk->clientIndex == 0) { | 
 | 323 |         return INVALID_OPERATION; | 
 | 324 |     } | 
| Eric Laurent | 25f4395 | 2010-07-28 05:40:18 -0700 | [diff] [blame] | 325 |     uint32_t size = 0; | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 326 |     return mIEffect->command(EFFECT_CMD_SET_PARAM_COMMIT, 0, NULL, &size, NULL); | 
 | 327 | } | 
 | 328 |  | 
 | 329 | status_t AudioEffect::getParameter(effect_param_t *param) | 
 | 330 | { | 
 | 331 |     if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) { | 
| John Grossman | af7d818 | 2012-01-11 12:23:42 -0800 | [diff] [blame] | 332 |         return mStatus; | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 333 |     } | 
 | 334 |  | 
 | 335 |     if (param == NULL || param->psize == 0 || param->vsize == 0) { | 
 | 336 |         return BAD_VALUE; | 
 | 337 |     } | 
 | 338 |  | 
| Glenn Kasten | 85ab62c | 2012-11-01 11:11:38 -0700 | [diff] [blame] | 339 |     ALOGV("getParameter: param: %d, param2: %d", *(int *)param->data, | 
 | 340 |             (param->psize == 8) ? *((int *)param->data + 1): -1); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 341 |  | 
| Glenn Kasten | 85ab62c | 2012-11-01 11:11:38 -0700 | [diff] [blame] | 342 |     uint32_t psize = sizeof(effect_param_t) + ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + | 
 | 343 |             param->vsize; | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 344 |  | 
| Glenn Kasten | 85ab62c | 2012-11-01 11:11:38 -0700 | [diff] [blame] | 345 |     return mIEffect->command(EFFECT_CMD_GET_PARAM, sizeof(effect_param_t) + param->psize, param, | 
 | 346 |             &psize, param); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 347 | } | 
 | 348 |  | 
 | 349 |  | 
 | 350 | // ------------------------------------------------------------------------- | 
 | 351 |  | 
 | 352 | void AudioEffect::binderDied() | 
 | 353 | { | 
| Steve Block | 5ff1dd5 | 2012-01-05 23:22:43 +0000 | [diff] [blame] | 354 |     ALOGW("IEffect died"); | 
| John Grossman | af7d818 | 2012-01-11 12:23:42 -0800 | [diff] [blame] | 355 |     mStatus = DEAD_OBJECT; | 
| Glenn Kasten | a0d6833 | 2012-01-27 16:47:15 -0800 | [diff] [blame] | 356 |     if (mCbf != NULL) { | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 357 |         status_t status = DEAD_OBJECT; | 
 | 358 |         mCbf(EVENT_ERROR, mUserData, &status); | 
 | 359 |     } | 
 | 360 |     mIEffect.clear(); | 
 | 361 | } | 
 | 362 |  | 
 | 363 | // ------------------------------------------------------------------------- | 
 | 364 |  | 
 | 365 | void AudioEffect::controlStatusChanged(bool controlGranted) | 
 | 366 | { | 
| Glenn Kasten | 85ab62c | 2012-11-01 11:11:38 -0700 | [diff] [blame] | 367 |     ALOGV("controlStatusChanged %p control %d callback %p mUserData %p", this, controlGranted, mCbf, | 
 | 368 |             mUserData); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 369 |     if (controlGranted) { | 
 | 370 |         if (mStatus == ALREADY_EXISTS) { | 
 | 371 |             mStatus = NO_ERROR; | 
 | 372 |         } | 
 | 373 |     } else { | 
 | 374 |         if (mStatus == NO_ERROR) { | 
 | 375 |             mStatus = ALREADY_EXISTS; | 
 | 376 |         } | 
 | 377 |     } | 
| Glenn Kasten | a0d6833 | 2012-01-27 16:47:15 -0800 | [diff] [blame] | 378 |     if (mCbf != NULL) { | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 379 |         mCbf(EVENT_CONTROL_STATUS_CHANGED, mUserData, &controlGranted); | 
 | 380 |     } | 
 | 381 | } | 
 | 382 |  | 
 | 383 | void AudioEffect::enableStatusChanged(bool enabled) | 
 | 384 | { | 
| Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 385 |     ALOGV("enableStatusChanged %p enabled %d mCbf %p", this, enabled, mCbf); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 386 |     if (mStatus == ALREADY_EXISTS) { | 
| Eric Laurent | f5aafb2 | 2010-11-18 08:40:16 -0800 | [diff] [blame] | 387 |         mEnabled = enabled; | 
| Glenn Kasten | a0d6833 | 2012-01-27 16:47:15 -0800 | [diff] [blame] | 388 |         if (mCbf != NULL) { | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 389 |             mCbf(EVENT_ENABLE_STATUS_CHANGED, mUserData, &enabled); | 
 | 390 |         } | 
 | 391 |     } | 
 | 392 | } | 
 | 393 |  | 
| Eric Laurent | 25f4395 | 2010-07-28 05:40:18 -0700 | [diff] [blame] | 394 | void AudioEffect::commandExecuted(uint32_t cmdCode, | 
| Glenn Kasten | 0f11b51 | 2014-01-31 16:18:54 -0800 | [diff] [blame] | 395 |                                   uint32_t cmdSize __unused, | 
| Eric Laurent | 25f4395 | 2010-07-28 05:40:18 -0700 | [diff] [blame] | 396 |                                   void *cmdData, | 
| Glenn Kasten | 0f11b51 | 2014-01-31 16:18:54 -0800 | [diff] [blame] | 397 |                                   uint32_t replySize __unused, | 
| Eric Laurent | 25f4395 | 2010-07-28 05:40:18 -0700 | [diff] [blame] | 398 |                                   void *replyData) | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 399 | { | 
 | 400 |     if (cmdData == NULL || replyData == NULL) { | 
 | 401 |         return; | 
 | 402 |     } | 
 | 403 |  | 
| Glenn Kasten | a0d6833 | 2012-01-27 16:47:15 -0800 | [diff] [blame] | 404 |     if (mCbf != NULL && cmdCode == EFFECT_CMD_SET_PARAM) { | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 405 |         effect_param_t *cmd = (effect_param_t *)cmdData; | 
 | 406 |         cmd->status = *(int32_t *)replyData; | 
 | 407 |         mCbf(EVENT_PARAMETER_CHANGED, mUserData, cmd); | 
 | 408 |     } | 
 | 409 | } | 
 | 410 |  | 
 | 411 | // ------------------------------------------------------------------------- | 
 | 412 |  | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 413 | status_t AudioEffect::queryNumberEffects(uint32_t *numEffects) | 
 | 414 | { | 
 | 415 |     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); | 
 | 416 |     if (af == 0) return PERMISSION_DENIED; | 
 | 417 |     return af->queryNumberEffects(numEffects); | 
 | 418 | } | 
 | 419 |  | 
| Eric Laurent | ffe9c25 | 2010-06-23 17:38:20 -0700 | [diff] [blame] | 420 | status_t AudioEffect::queryEffect(uint32_t index, effect_descriptor_t *descriptor) | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 421 | { | 
 | 422 |     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); | 
 | 423 |     if (af == 0) return PERMISSION_DENIED; | 
| Eric Laurent | ffe9c25 | 2010-06-23 17:38:20 -0700 | [diff] [blame] | 424 |     return af->queryEffect(index, descriptor); | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 425 | } | 
 | 426 |  | 
| Glenn Kasten | 5e92a78 | 2012-01-30 07:40:52 -0800 | [diff] [blame] | 427 | status_t AudioEffect::getEffectDescriptor(const effect_uuid_t *uuid, | 
| Glenn Kasten | f587ba5 | 2012-01-26 16:25:10 -0800 | [diff] [blame] | 428 |         effect_descriptor_t *descriptor) /*const*/ | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 429 | { | 
 | 430 |     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); | 
 | 431 |     if (af == 0) return PERMISSION_DENIED; | 
 | 432 |     return af->getEffectDescriptor(uuid, descriptor); | 
 | 433 | } | 
 | 434 |  | 
| Eric Laurent | 57dae99 | 2011-07-24 13:36:09 -0700 | [diff] [blame] | 435 |  | 
| Glenn Kasten | d848eb4 | 2016-03-08 13:42:11 -0800 | [diff] [blame] | 436 | status_t AudioEffect::queryDefaultPreProcessing(audio_session_t audioSession, | 
| Eric Laurent | 57dae99 | 2011-07-24 13:36:09 -0700 | [diff] [blame] | 437 |                                           effect_descriptor_t *descriptors, | 
 | 438 |                                           uint32_t *count) | 
 | 439 | { | 
 | 440 |     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); | 
 | 441 |     if (aps == 0) return PERMISSION_DENIED; | 
 | 442 |     return aps->queryDefaultPreProcessing(audioSession, descriptors, count); | 
 | 443 | } | 
| Eric Laurent | 801a118 | 2010-06-09 00:17:29 -0700 | [diff] [blame] | 444 | // ------------------------------------------------------------------------- | 
 | 445 |  | 
 | 446 | status_t AudioEffect::stringToGuid(const char *str, effect_uuid_t *guid) | 
 | 447 | { | 
 | 448 |     if (str == NULL || guid == NULL) { | 
 | 449 |         return BAD_VALUE; | 
 | 450 |     } | 
 | 451 |  | 
 | 452 |     int tmp[10]; | 
 | 453 |  | 
 | 454 |     if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", | 
 | 455 |             tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) { | 
 | 456 |         return BAD_VALUE; | 
 | 457 |     } | 
 | 458 |     guid->timeLow = (uint32_t)tmp[0]; | 
 | 459 |     guid->timeMid = (uint16_t)tmp[1]; | 
 | 460 |     guid->timeHiAndVersion = (uint16_t)tmp[2]; | 
 | 461 |     guid->clockSeq = (uint16_t)tmp[3]; | 
 | 462 |     guid->node[0] = (uint8_t)tmp[4]; | 
 | 463 |     guid->node[1] = (uint8_t)tmp[5]; | 
 | 464 |     guid->node[2] = (uint8_t)tmp[6]; | 
 | 465 |     guid->node[3] = (uint8_t)tmp[7]; | 
 | 466 |     guid->node[4] = (uint8_t)tmp[8]; | 
 | 467 |     guid->node[5] = (uint8_t)tmp[9]; | 
 | 468 |  | 
 | 469 |     return NO_ERROR; | 
 | 470 | } | 
 | 471 |  | 
 | 472 | status_t AudioEffect::guidToString(const effect_uuid_t *guid, char *str, size_t maxLen) | 
 | 473 | { | 
 | 474 |     if (guid == NULL || str == NULL) { | 
 | 475 |         return BAD_VALUE; | 
 | 476 |     } | 
 | 477 |  | 
 | 478 |     snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", | 
 | 479 |             guid->timeLow, | 
 | 480 |             guid->timeMid, | 
 | 481 |             guid->timeHiAndVersion, | 
 | 482 |             guid->clockSeq, | 
 | 483 |             guid->node[0], | 
 | 484 |             guid->node[1], | 
 | 485 |             guid->node[2], | 
 | 486 |             guid->node[3], | 
 | 487 |             guid->node[4], | 
 | 488 |             guid->node[5]); | 
 | 489 |  | 
 | 490 |     return NO_ERROR; | 
 | 491 | } | 
 | 492 |  | 
 | 493 |  | 
| Glenn Kasten | 40bc906 | 2015-03-20 09:09:33 -0700 | [diff] [blame] | 494 | } // namespace android |