13af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi/* 23af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project 33af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi * 43af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 53af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi * you may not use this file except in compliance with the License. 63af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi * You may obtain a copy of the License at 73af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi * 83af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 93af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi * 103af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 113af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 123af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi * See the License for the specific language governing permissions and 143af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi * limitations under the License. 153af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi */ 163af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 173af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi#include "sles_allinclusive.h" 1875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi#include "android_prompts.h" 194e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean#include "channels.h" 203af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 212523b697aa1fda376c2ccd72680394d359acbd3fSvet Ganov#include <utils/String16.h> 222523b697aa1fda376c2ccd72680394d359acbd3fSvet Ganov 2310a3840407ac3ed61e7873ee7b86d664ccc6149fDima Zavin#include <system/audio.h> 244e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean#include <SLES/OpenSLES_Android.h> 25ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin 2615f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean#include <android_runtime/AndroidRuntime.h> 2715f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean 28b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi#define KEY_RECORDING_SOURCE_PARAMSIZE sizeof(SLuint32) 29b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi#define KEY_RECORDING_PRESET_PARAMSIZE sizeof(SLuint32) 308c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent#define KEY_PERFORMANCE_MODE_PARAMSIZE sizeof(SLuint32) 31b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 32b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi//----------------------------------------------------------------------------- 33b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi// Internal utility functions 34b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi//---------------------------- 35b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 36b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel TriviSLresult audioRecorder_setPreset(CAudioRecorder* ar, SLuint32 recordPreset) { 37b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi SLresult result = SL_RESULT_SUCCESS; 38b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 39adf8bd5d4360542b6b6c48c4471fdd8d855e05ccGlenn Kasten audio_source_t newRecordSource = AUDIO_SOURCE_DEFAULT; 40b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi switch (recordPreset) { 41e214a8c49938e7356943b59db53474e5fc3ae07cJean-Michel Trivi case SL_ANDROID_RECORDING_PRESET_GENERIC: 42ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin newRecordSource = AUDIO_SOURCE_DEFAULT; 43b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi break; 44b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi case SL_ANDROID_RECORDING_PRESET_CAMCORDER: 45ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin newRecordSource = AUDIO_SOURCE_CAMCORDER; 46b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi break; 47b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi case SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION: 48ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin newRecordSource = AUDIO_SOURCE_VOICE_RECOGNITION; 49b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi break; 50a4b4d478171631eaa97e933eb46c1ff01bd04daaJean-Michel Trivi case SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION: 51ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin newRecordSource = AUDIO_SOURCE_VOICE_COMMUNICATION; 52a4b4d478171631eaa97e933eb46c1ff01bd04daaJean-Michel Trivi break; 53e9b57cefb954e7c1bffc5d4b59f89aca5e050797rago case SL_ANDROID_RECORDING_PRESET_UNPROCESSED: 54e9b57cefb954e7c1bffc5d4b59f89aca5e050797rago newRecordSource = AUDIO_SOURCE_UNPROCESSED; 55e9b57cefb954e7c1bffc5d4b59f89aca5e050797rago break; 56b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi case SL_ANDROID_RECORDING_PRESET_NONE: 57b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi // it is an error to set preset "none" 58b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi default: 5975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi SL_LOGE(ERROR_RECORDERPRESET_SET_UNKNOWN_PRESET); 60b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi result = SL_RESULT_PARAMETER_INVALID; 61b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi } 62b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 6375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi // recording preset needs to be set before the object is realized 64e5ede1a139fcedbf075675179d919fbe731898f0Glenn Kasten // (ap->mAudioRecord is supposed to be 0 until then) 655f71e35da153d194d805e030ab38935599e065d2Jean-Michel Trivi if (SL_OBJECT_STATE_UNREALIZED != ar->mObject.mState) { 6675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi SL_LOGE(ERROR_RECORDERPRESET_REALIZED); 6775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi result = SL_RESULT_PRECONDITIONS_VIOLATED; 6875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi } else { 6975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi ar->mRecordSource = newRecordSource; 7075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi } 7175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi 72b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi return result; 73b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi} 74b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 75b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 768c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent//----------------------------------------------------------------------------- 778c9071f491393fadf767b6164a17b0795eba3fdaEric LaurentSLresult audioRecorder_setPerformanceMode(CAudioRecorder* ar, SLuint32 mode) { 788c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent SLresult result = SL_RESULT_SUCCESS; 798c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent SL_LOGV("performance mode set to %d", mode); 808c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 818c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent SLuint32 perfMode = ANDROID_PERFORMANCE_MODE_DEFAULT; 828c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent switch (mode) { 838c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent case SL_ANDROID_PERFORMANCE_LATENCY: 848c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent perfMode = ANDROID_PERFORMANCE_MODE_LATENCY; 858c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 868c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent case SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS: 878c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent perfMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS; 888c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 898c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent case SL_ANDROID_PERFORMANCE_NONE: 908c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent perfMode = ANDROID_PERFORMANCE_MODE_NONE; 918c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 928c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent case SL_ANDROID_PERFORMANCE_POWER_SAVING: 938c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent perfMode = ANDROID_PERFORMANCE_MODE_POWER_SAVING; 948c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 958c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent default: 968c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent SL_LOGE(ERROR_CONFIG_PERF_MODE_UNKNOWN); 978c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent result = SL_RESULT_PARAMETER_INVALID; 988c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 998c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 1008c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 1018c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // performance mode needs to be set before the object is realized 1028c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // (ar->mAudioRecord is supposed to be NULL until then) 1038c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent if (SL_OBJECT_STATE_UNREALIZED != ar->mObject.mState) { 1048c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent SL_LOGE(ERROR_CONFIG_PERF_MODE_REALIZED); 1058c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent result = SL_RESULT_PRECONDITIONS_VIOLATED; 1068c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } else { 1078c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent ar->mPerformanceMode = perfMode; 1088c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 1098c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 1108c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent return result; 1118c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent} 1128c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 1138c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 114b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel TriviSLresult audioRecorder_getPreset(CAudioRecorder* ar, SLuint32* pPreset) { 115b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi SLresult result = SL_RESULT_SUCCESS; 116b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 117b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi switch (ar->mRecordSource) { 118ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin case AUDIO_SOURCE_DEFAULT: 119ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin case AUDIO_SOURCE_MIC: 120e214a8c49938e7356943b59db53474e5fc3ae07cJean-Michel Trivi *pPreset = SL_ANDROID_RECORDING_PRESET_GENERIC; 121b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi break; 122ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin case AUDIO_SOURCE_VOICE_UPLINK: 123ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin case AUDIO_SOURCE_VOICE_DOWNLINK: 124ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin case AUDIO_SOURCE_VOICE_CALL: 125b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi *pPreset = SL_ANDROID_RECORDING_PRESET_NONE; 126b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi break; 127ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin case AUDIO_SOURCE_VOICE_RECOGNITION: 128b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi *pPreset = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION; 129b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi break; 130ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin case AUDIO_SOURCE_CAMCORDER: 131b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi *pPreset = SL_ANDROID_RECORDING_PRESET_CAMCORDER; 132b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi break; 133ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin case AUDIO_SOURCE_VOICE_COMMUNICATION: 134a4b4d478171631eaa97e933eb46c1ff01bd04daaJean-Michel Trivi *pPreset = SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION; 135a4b4d478171631eaa97e933eb46c1ff01bd04daaJean-Michel Trivi break; 136e9b57cefb954e7c1bffc5d4b59f89aca5e050797rago case AUDIO_SOURCE_UNPROCESSED: 137e9b57cefb954e7c1bffc5d4b59f89aca5e050797rago *pPreset = SL_ANDROID_RECORDING_PRESET_UNPROCESSED; 138e9b57cefb954e7c1bffc5d4b59f89aca5e050797rago break; 139b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi default: 140b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi *pPreset = SL_ANDROID_RECORDING_PRESET_NONE; 141b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi result = SL_RESULT_INTERNAL_ERROR; 142b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi break; 143b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi } 144b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 145b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi return result; 146b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi} 147b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 1483af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 1498c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent//----------------------------------------------------------------------------- 1508c9071f491393fadf767b6164a17b0795eba3fdaEric LaurentSLresult audioRecorder_getPerformanceMode(CAudioRecorder* ar, SLuint32 *pMode) { 1518c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent SLresult result = SL_RESULT_SUCCESS; 1528c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 1538c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent switch (ar->mPerformanceMode) { 1548c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent case ANDROID_PERFORMANCE_MODE_LATENCY: 1558c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent *pMode = SL_ANDROID_PERFORMANCE_LATENCY; 1568c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 1578c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS: 1588c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent *pMode = SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS; 1598c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 1608c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent case ANDROID_PERFORMANCE_MODE_NONE: 1618c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent *pMode = SL_ANDROID_PERFORMANCE_NONE; 1628c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 1638c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent case ANDROID_PERFORMANCE_MODE_POWER_SAVING: 164677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent *pMode = SL_ANDROID_PERFORMANCE_POWER_SAVING; 1658c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 1668c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent default: 1678c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent result = SL_RESULT_INTERNAL_ERROR; 1688c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent *pMode = SL_ANDROID_PERFORMANCE_LATENCY; 1698c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 1708c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 1718c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 1728c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent return result; 1738c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent} 1748c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 1758c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 1763b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivivoid audioRecorder_handleNewPos_lockRecord(CAudioRecorder* ar) { 1773b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi //SL_LOGV("received event EVENT_NEW_POS from AudioRecord"); 1783b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi slRecordCallback callback = NULL; 1793b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi void* callbackPContext = NULL; 1803b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 1813b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi interface_lock_shared(&ar->mRecord); 1823b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi callback = ar->mRecord.mCallback; 1833b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi callbackPContext = ar->mRecord.mContext; 1843b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi interface_unlock_shared(&ar->mRecord); 1853b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 1863b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi if (NULL != callback) { 1873b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi // getting this event implies SL_RECORDEVENT_HEADATNEWPOS was set in the event mask 1883b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi (*callback)(&ar->mRecord.mItf, callbackPContext, SL_RECORDEVENT_HEADATNEWPOS); 1893b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi } 1903b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi} 1913b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 1923b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 1933b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivivoid audioRecorder_handleMarker_lockRecord(CAudioRecorder* ar) { 1943b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi //SL_LOGV("received event EVENT_MARKER from AudioRecord"); 1953b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi slRecordCallback callback = NULL; 1963b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi void* callbackPContext = NULL; 1973b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 1983b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi interface_lock_shared(&ar->mRecord); 1993b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi callback = ar->mRecord.mCallback; 2003b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi callbackPContext = ar->mRecord.mContext; 2013b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi interface_unlock_shared(&ar->mRecord); 2023b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 2033b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi if (NULL != callback) { 2043b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi // getting this event implies SL_RECORDEVENT_HEADATMARKER was set in the event mask 2053b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi (*callback)(&ar->mRecord.mItf, callbackPContext, SL_RECORDEVENT_HEADATMARKER); 2063b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi } 2073b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi} 2083b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 2093b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 2103b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivivoid audioRecorder_handleOverrun_lockRecord(CAudioRecorder* ar) { 2113b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi //SL_LOGV("received event EVENT_OVERRUN from AudioRecord"); 2123b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi slRecordCallback callback = NULL; 2133b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi void* callbackPContext = NULL; 2143b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 2153b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi interface_lock_shared(&ar->mRecord); 216f6cca2f731329d101651348d1b7e51ead7b1290aJean-Michel Trivi if (ar->mRecord.mCallbackEventsMask & SL_RECORDEVENT_HEADSTALLED) { 2173b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi callback = ar->mRecord.mCallback; 2183b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi callbackPContext = ar->mRecord.mContext; 2193b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi } 2203b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi interface_unlock_shared(&ar->mRecord); 2213b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 2223b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi if (NULL != callback) { 223f6cca2f731329d101651348d1b7e51ead7b1290aJean-Michel Trivi (*callback)(&ar->mRecord.mItf, callbackPContext, SL_RECORDEVENT_HEADSTALLED); 2243b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi } 2253b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi} 2263b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 2273af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi//----------------------------------------------------------------------------- 22800a66a027199238a93b2aa9056af126efc09fe38Glenn KastenSLresult android_audioRecorder_checkSourceSink(CAudioRecorder* ar) { 2293af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 2303af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi const SLDataSource *pAudioSrc = &ar->mDataSource.u.mSource; 2313af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi const SLDataSink *pAudioSnk = &ar->mDataSink.u.mSink; 2323af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 233274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator; 234274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSnk->pFormat; 235274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten 236274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten const SLuint32 *df_representation = NULL; // pointer to representation field, if it exists 237274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten 238274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten // sink must be an Android simple buffer queue with PCM data format 239274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten switch (sinkLocatorType) { 240274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: { 241274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten switch (sinkFormatType) { 242274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten case SL_ANDROID_DATAFORMAT_PCM_EX: { 243274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten const SLAndroidDataFormat_PCM_EX *df_pcm = 244274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten (SLAndroidDataFormat_PCM_EX *) pAudioSnk->pFormat; 245df9b397f73d8f063ff66e0fbf86ced075fe6d5aaGlenn Kasten // checkDataFormat() already checked representation 246df9b397f73d8f063ff66e0fbf86ced075fe6d5aaGlenn Kasten df_representation = &df_pcm->representation; 247274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten } // SL_ANDROID_DATAFORMAT_PCM_EX - fall through to next test. 248274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten case SL_DATAFORMAT_PCM: { 249274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten const SLDataFormat_PCM *df_pcm = (const SLDataFormat_PCM *) pAudioSnk->pFormat; 2504e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // checkDataFormat already checked sample rate, channels, and mask 251712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi ar->mNumChannels = df_pcm->numChannels; 252a80a6ff9a1f80792478c9d43578afa24a07eb2f0Glenn Kasten 253a80a6ff9a1f80792478c9d43578afa24a07eb2f0Glenn Kasten if (df_pcm->endianness != ar->mObject.mEngine->mEngine.mNativeEndianness) { 25471065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten SL_LOGE("Cannot create audio recorder: unsupported byte order %u", 25571065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten df_pcm->endianness); 256a80a6ff9a1f80792478c9d43578afa24a07eb2f0Glenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 257a80a6ff9a1f80792478c9d43578afa24a07eb2f0Glenn Kasten } 258a80a6ff9a1f80792478c9d43578afa24a07eb2f0Glenn Kasten 259274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten ar->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES 260a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGV("AudioRecorder requested sample rate = %u mHz, %u channel(s)", 261712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi ar->mSampleRateMilliHz, ar->mNumChannels); 26271065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten 26371065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten // we don't support container size != sample depth 26471065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten if (df_pcm->containerSize != df_pcm->bitsPerSample) { 26571065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten SL_LOGE("Cannot create audio recorder: unsupported container size %u bits for " 26671065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten "sample depth %u bits", 26771065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten df_pcm->containerSize, (SLuint32)df_pcm->bitsPerSample); 26871065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten return SL_RESULT_CONTENT_UNSUPPORTED; 26971065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten } 27071065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten 271274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten } break; 272274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten default: 27375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi SL_LOGE(ERROR_RECORDER_SINK_FORMAT_MUST_BE_PCM); 274712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi return SL_RESULT_PARAMETER_INVALID; 275274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten } // switch (sourceFormatType) 276274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten } break; // case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE 277274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten default: 278274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten SL_LOGE(ERROR_RECORDER_SINK_MUST_BE_ANDROIDSIMPLEBUFFERQUEUE); 279274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten return SL_RESULT_PARAMETER_INVALID; 280274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten } // switch (sourceLocatorType) 2813af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 2823af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // Source check: 2833af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // only input device sources are supported 2843af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // check it's an IO device 2853af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi if (SL_DATALOCATOR_IODEVICE != *(SLuint32 *)pAudioSrc->pLocator) { 28675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi SL_LOGE(ERROR_RECORDER_SOURCE_MUST_BE_IODEVICE); 2873af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi return SL_RESULT_PARAMETER_INVALID; 2883af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } else { 2893af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 2903af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // check it's an input device 29122ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten SLDataLocator_IODevice *dl_iod = (SLDataLocator_IODevice *) pAudioSrc->pLocator; 2923af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi if (SL_IODEVICE_AUDIOINPUT != dl_iod->deviceType) { 29375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi SL_LOGE(ERROR_RECORDER_IODEVICE_MUST_BE_AUDIOINPUT); 2943af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi return SL_RESULT_PARAMETER_INVALID; 2953af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 2963af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 2973af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // check it's the default input device, others aren't supported here 2983af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi if (SL_DEFAULTDEVICEID_AUDIOINPUT != dl_iod->deviceID) { 29975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi SL_LOGE(ERROR_RECORDER_INPUT_ID_MUST_BE_DEFAULT); 3003af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi return SL_RESULT_PARAMETER_INVALID; 3013af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 3023af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 3033af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 3043af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi return SL_RESULT_SUCCESS; 3053af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi} 3063af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi//----------------------------------------------------------------------------- 3073af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivistatic void audioRecorder_callback(int event, void* user, void *info) { 3083af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi //SL_LOGV("audioRecorder_callback(%d, %p, %p) entering", event, user, info); 3093af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 3103af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi CAudioRecorder *ar = (CAudioRecorder *)user; 311460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten 312460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten if (!android::CallbackProtector::enterCbIfOk(ar->mCallbackProtector)) { 313460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten // it is not safe to enter the callback (the track is about to go away) 314460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten return; 315460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten } 316460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten 3173af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi void * callbackPContext = NULL; 3183af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 319ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten switch (event) { 3203af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi case android::AudioRecord::EVENT_MORE_DATA: { 3213af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi slBufferQueueCallback callback = NULL; 3223af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi android::AudioRecord::Buffer* pBuff = (android::AudioRecord::Buffer*)info; 3233af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 3243af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // push data to the buffer queue 3253af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi interface_lock_exclusive(&ar->mBufferQueue); 3263af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 3273af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi if (ar->mBufferQueue.mState.count != 0) { 3283af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi assert(ar->mBufferQueue.mFront != ar->mBufferQueue.mRear); 3293af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 3303af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi BufferHeader *oldFront = ar->mBufferQueue.mFront; 3313af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi BufferHeader *newFront = &oldFront[1]; 3323af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 333274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten size_t availSink = oldFront->mSize - ar->mBufferQueue.mSizeConsumed; 334274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten size_t availSource = pBuff->size; 335274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten size_t bytesToCopy = availSink < availSource ? availSink : availSource; 336274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten void *pDest = (char *)oldFront->mBuffer + ar->mBufferQueue.mSizeConsumed; 337274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten memcpy(pDest, pBuff->raw, bytesToCopy); 338274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten 339274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten if (bytesToCopy < availSink) { 3403af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // can't consume the whole or rest of the buffer in one shot 341274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten ar->mBufferQueue.mSizeConsumed += availSource; 342274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten // pBuff->size is already equal to bytesToCopy in this case 3433af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } else { 3443af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // finish pushing the buffer or push the buffer in one shot 345274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten pBuff->size = bytesToCopy; 3463af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi ar->mBufferQueue.mSizeConsumed = 0; 34722ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten if (newFront == &ar->mBufferQueue.mArray[ar->mBufferQueue.mNumBuffers + 1]) { 3483af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi newFront = ar->mBufferQueue.mArray; 3493af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 3503af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi ar->mBufferQueue.mFront = newFront; 3513af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 3523af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi ar->mBufferQueue.mState.count--; 3533af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi ar->mBufferQueue.mState.playIndex++; 354274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten 3553af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // data has been copied to the buffer, and the buffer queue state has been updated 3563af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // we will notify the client if applicable 3573af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi callback = ar->mBufferQueue.mCallback; 3583af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // save callback data 3593af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi callbackPContext = ar->mBufferQueue.mContext; 3603af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 361274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten } else { // empty queue 3623af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // no destination to push the data 3633af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi pBuff->size = 0; 3643af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 3653af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 3663af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi interface_unlock_exclusive(&ar->mBufferQueue); 367274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten 3683af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // notify client 3693af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi if (NULL != callback) { 3703af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi (*callback)(&ar->mBufferQueue.mItf, callbackPContext); 3713af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 3723af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 3733af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi break; 3743af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 3753b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi case android::AudioRecord::EVENT_OVERRUN: 3763b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi audioRecorder_handleOverrun_lockRecord(ar); 3773b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi break; 3783b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 3793af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi case android::AudioRecord::EVENT_MARKER: 3803b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi audioRecorder_handleMarker_lockRecord(ar); 3813af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi break; 3823af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 3833af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi case android::AudioRecord::EVENT_NEW_POS: 3843b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi audioRecorder_handleNewPos_lockRecord(ar); 3853af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi break; 3863af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 3879f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten case android::AudioRecord::EVENT_NEW_IAUDIORECORD: 3889f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten // ignore for now 3899f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten break; 3909f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten 3919f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten default: 3929f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten SL_LOGE("Encountered unknown AudioRecord event %d for CAudioRecord %p", event, ar); 3939f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten break; 3943af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 395460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten 396460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten ar->mCallbackProtector->exitCb(); 3973af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi} 3983af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 3993af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 4003af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi//----------------------------------------------------------------------------- 4013af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel TriviSLresult android_audioRecorder_create(CAudioRecorder* ar) { 4023af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi SL_LOGV("android_audioRecorder_create(%p) entering", ar); 4033af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 404b2aeb0f1009555181dabb944fe05901cb6e6f632Jean-Michel Trivi const SLDataSource *pAudioSrc = &ar->mDataSource.u.mSource; 405b2aeb0f1009555181dabb944fe05901cb6e6f632Jean-Michel Trivi const SLDataSink *pAudioSnk = &ar->mDataSink.u.mSink; 4063af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi SLresult result = SL_RESULT_SUCCESS; 4073af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 408b2aeb0f1009555181dabb944fe05901cb6e6f632Jean-Michel Trivi const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator; 409b2aeb0f1009555181dabb944fe05901cb6e6f632Jean-Michel Trivi const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator; 410b2aeb0f1009555181dabb944fe05901cb6e6f632Jean-Michel Trivi 411b0cf731f4d81a3d6f8cac31de3cdddbbf555c305Jean-Michel Trivi // the following platform-independent fields have been initialized in CreateAudioRecorder() 412b0cf731f4d81a3d6f8cac31de3cdddbbf555c305Jean-Michel Trivi // ar->mNumChannels 413b0cf731f4d81a3d6f8cac31de3cdddbbf555c305Jean-Michel Trivi // ar->mSampleRateMilliHz 414b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivi 415b2aeb0f1009555181dabb944fe05901cb6e6f632Jean-Michel Trivi if ((SL_DATALOCATOR_IODEVICE == sourceLocatorType) && 416b2aeb0f1009555181dabb944fe05901cb6e6f632Jean-Michel Trivi (SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE == sinkLocatorType)) { 417b2aeb0f1009555181dabb944fe05901cb6e6f632Jean-Michel Trivi // microphone to simple buffer queue 418b05ea38e5131001884aa226f90fd50cf594a23f3Jean-Michel Trivi ar->mAndroidObjType = AUDIORECORDER_FROM_MIC_TO_PCM_BUFFERQUEUE; 419e5ede1a139fcedbf075675179d919fbe731898f0Glenn Kasten ar->mAudioRecord.clear(); 420460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten ar->mCallbackProtector = new android::CallbackProtector(); 421ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin ar->mRecordSource = AUDIO_SOURCE_DEFAULT; 4228c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_DEFAULT; 423b2aeb0f1009555181dabb944fe05901cb6e6f632Jean-Michel Trivi } else { 424b2aeb0f1009555181dabb944fe05901cb6e6f632Jean-Michel Trivi result = SL_RESULT_CONTENT_UNSUPPORTED; 425b2aeb0f1009555181dabb944fe05901cb6e6f632Jean-Michel Trivi } 426b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 427b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi return result; 428b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi} 429b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 430b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 431b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi//----------------------------------------------------------------------------- 432b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel TriviSLresult android_audioRecorder_setConfig(CAudioRecorder* ar, const SLchar *configKey, 433b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi const void *pConfigValue, SLuint32 valueSize) { 434b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 435c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten SLresult result; 436b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 437c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten assert(NULL != ar && NULL != configKey && NULL != pConfigValue); 438ca426f63e9c900ecbd28f8e3037aaf47ef739dd4Glenn Kasten if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_RECORDING_PRESET) == 0) { 439b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 440b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi // recording preset 441b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi if (KEY_RECORDING_PRESET_PARAMSIZE > valueSize) { 44275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 443c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten result = SL_RESULT_BUFFER_INSUFFICIENT; 444b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi } else { 445b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi result = audioRecorder_setPreset(ar, *(SLuint32*)pConfigValue); 446b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi } 447b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 4488c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) { 4498c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 4508c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // performance mode 4518c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent if (KEY_PERFORMANCE_MODE_PARAMSIZE > valueSize) { 4528c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 4538c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent result = SL_RESULT_BUFFER_INSUFFICIENT; 4548c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } else { 4558c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent result = audioRecorder_setPerformanceMode(ar, *(SLuint32*)pConfigValue); 4568c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 457b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi } else { 45875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY); 459b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi result = SL_RESULT_PARAMETER_INVALID; 460b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi } 461b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 462b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi return result; 463b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi} 464b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 465b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 466b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi//----------------------------------------------------------------------------- 467b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel TriviSLresult android_audioRecorder_getConfig(CAudioRecorder* ar, const SLchar *configKey, 468b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi SLuint32* pValueSize, void *pConfigValue) { 469b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 470c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten SLresult result; 471b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 472c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten assert(NULL != ar && NULL != configKey && NULL != pValueSize); 473ca426f63e9c900ecbd28f8e3037aaf47ef739dd4Glenn Kasten if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_RECORDING_PRESET) == 0) { 474b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 475b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi // recording preset 476c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten if (NULL == pConfigValue) { 477c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten result = SL_RESULT_SUCCESS; 478c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten } else if (KEY_RECORDING_PRESET_PARAMSIZE > *pValueSize) { 47975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 480c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten result = SL_RESULT_BUFFER_INSUFFICIENT; 481b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi } else { 482c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten result = audioRecorder_getPreset(ar, (SLuint32*)pConfigValue); 483b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi } 484c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten *pValueSize = KEY_RECORDING_PRESET_PARAMSIZE; 485b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi 4868c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) { 4878c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 4888c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // performance mode 4898c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent if (NULL == pConfigValue) { 4908c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent result = SL_RESULT_SUCCESS; 4918c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } else if (KEY_PERFORMANCE_MODE_PARAMSIZE > *pValueSize) { 4928c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 4938c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent result = SL_RESULT_BUFFER_INSUFFICIENT; 4948c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } else { 4958c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent result = audioRecorder_getPerformanceMode(ar, (SLuint32*)pConfigValue); 4968c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 4978c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent *pValueSize = KEY_PERFORMANCE_MODE_PARAMSIZE; 4988c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 499b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi } else { 50075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY); 501b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi result = SL_RESULT_PARAMETER_INVALID; 502b3e52a63baaea367cf411348b68ecd8fd429b029Jean-Michel Trivi } 5033af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 5043af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi return result; 5053af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi} 5063af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 5078c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent// Called from android_audioRecorder_realize for a PCM buffer queue recorder before creating the 5088c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent// AudioRecord to determine which performance modes are allowed based on effect interfaces present 5098c9071f491393fadf767b6164a17b0795eba3fdaEric Laurentstatic void checkAndSetPerformanceModePre(CAudioRecorder* ar) 5108c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent{ 5118c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent SLuint32 allowedModes = ANDROID_PERFORMANCE_MODE_ALL; 5128c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent assert(ar->mAndroidObjType == AUDIORECORDER_FROM_MIC_TO_PCM_BUFFERQUEUE); 5138c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 5148c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // no need to check the buffer queue size, application side 5158c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // double-buffering (and more) is not a requirement for using fast tracks 5168c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 5178c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // Check a blacklist of interfaces that are incompatible with fast tracks. 5188c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // The alternative, to check a whitelist of compatible interfaces, is 5198c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // more maintainable but is too slow. As a compromise, in a debug build 5208c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // we use both methods and warn if they produce different results. 5218c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // In release builds, we only use the blacklist method. 5228c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // If a blacklisted interface is added after realization using 5238c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // DynamicInterfaceManagement::AddInterface, 5248c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // then this won't be detected but the interface will be ineffective. 5258c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent static const unsigned blacklist[] = { 5268c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent MPH_ANDROIDACOUSTICECHOCANCELLATION, 5278c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent MPH_ANDROIDAUTOMATICGAINCONTROL, 5288c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent MPH_ANDROIDNOISESUPPRESSION, 5298c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent MPH_ANDROIDEFFECT, 5308c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // FIXME The problem with a blacklist is remembering to add new interfaces here 5318c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent }; 532677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent 5338c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent for (unsigned i = 0; i < sizeof(blacklist)/sizeof(blacklist[0]); ++i) { 5348c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent if (IsInterfaceInitialized(&ar->mObject, blacklist[i])) { 535677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent uint32_t flags = 0; 536677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent 537677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent allowedModes &= ~ANDROID_PERFORMANCE_MODE_LATENCY; 538677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent 539677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent // if generic effect interface is used we don't know which effect will be used and 540677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent // disable all low latency performance modes 541677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent if (blacklist[i] != MPH_ANDROIDEFFECT) { 542677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent switch (blacklist[i]) { 543677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent case MPH_ANDROIDACOUSTICECHOCANCELLATION: 544677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent SL_LOGV("checkAndSetPerformanceModePre found AEC name %s", 545677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent ar->mAcousticEchoCancellation.mAECDescriptor.name); 546677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent flags = ar->mAcousticEchoCancellation.mAECDescriptor.flags; 547677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent break; 548677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent case MPH_ANDROIDAUTOMATICGAINCONTROL: 549677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent SL_LOGV("checkAndSetPerformanceModePre found AGC name %s", 550677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent ar->mAutomaticGainControl.mAGCDescriptor.name); 551677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent flags = ar->mAutomaticGainControl.mAGCDescriptor.flags; 552677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent break; 553677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent case MPH_ANDROIDNOISESUPPRESSION: 554677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent SL_LOGV("checkAndSetPerformanceModePre found NS name %s", 555677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent ar->mNoiseSuppression.mNSDescriptor.name); 556677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent flags = ar->mNoiseSuppression.mNSDescriptor.flags; 557677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent break; 558677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent default: 559677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent break; 560677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent } 561677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent } 562677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent if ((flags & EFFECT_FLAG_HW_ACC_TUNNEL) == 0) { 563677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent allowedModes &= ~ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS; 564677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent break; 565677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent } 5668c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 5678c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 5688c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent#if LOG_NDEBUG == 0 5698c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent bool blacklistResult = ( 5708c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent (allowedModes & 5718c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent (ANDROID_PERFORMANCE_MODE_LATENCY|ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS)) != 0); 5728c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent bool whitelistResult = true; 5738c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent static const unsigned whitelist[] = { 5748c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent MPH_BUFFERQUEUE, 5758c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent MPH_DYNAMICINTERFACEMANAGEMENT, 5768c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent MPH_OBJECT, 5778c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent MPH_RECORD, 5788c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent MPH_ANDROIDCONFIGURATION, 5798c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent MPH_ANDROIDSIMPLEBUFFERQUEUE, 5808c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent }; 5818c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent for (unsigned mph = MPH_MIN; mph < MPH_MAX; ++mph) { 5828c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent for (unsigned i = 0; i < sizeof(whitelist)/sizeof(whitelist[0]); ++i) { 5838c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent if (mph == whitelist[i]) { 5848c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent goto compatible; 5858c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 5868c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 5878c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent if (IsInterfaceInitialized(&ar->mObject, mph)) { 5888c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent whitelistResult = false; 5898c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 5908c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 5918c9071f491393fadf767b6164a17b0795eba3fdaEric Laurentcompatible: ; 5928c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 5938c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent if (whitelistResult != blacklistResult) { 5948c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent SL_LOGW("whitelistResult != blacklistResult"); 5958c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 5968c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent#endif 5978c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent if (ar->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY) { 5988c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY) == 0) { 5998c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS; 6008c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 6018c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 6028c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent if (ar->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) { 6038c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) == 0) { 6048c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE; 6058c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 6068c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 6078c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent} 6088c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 6098c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent// Called from android_audioRecorder_realize for a PCM buffer queue recorder after creating the 6108c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent// AudioRecord to adjust performance mode based on actual input flags 6118c9071f491393fadf767b6164a17b0795eba3fdaEric Laurentstatic void checkAndSetPerformanceModePost(CAudioRecorder* ar) 6128c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent{ 6138c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent audio_input_flags_t flags = ar->mAudioRecord->getFlags(); 6148c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent switch (ar->mPerformanceMode) { 6158c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent case ANDROID_PERFORMANCE_MODE_LATENCY: 6168c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent if ((flags & (AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW)) == 6178c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent (AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW)) { 6188c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 6198c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 6208c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS; 6218c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent /* FALL THROUGH */ 6228c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS: 6238c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent if ((flags & AUDIO_INPUT_FLAG_FAST) == 0) { 6248c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE; 6258c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 6268c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 6278c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent case ANDROID_PERFORMANCE_MODE_NONE: 6288c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent default: 6298c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 6308c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 6318c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent} 6323af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi//----------------------------------------------------------------------------- 6333af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel TriviSLresult android_audioRecorder_realize(CAudioRecorder* ar, SLboolean async) { 6343af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi SL_LOGV("android_audioRecorder_realize(%p) entering", ar); 6353af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 6363af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi SLresult result = SL_RESULT_SUCCESS; 6373af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 638274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten // already checked in created and checkSourceSink 639274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten assert(ar->mDataSink.mLocator.mLocatorType == SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE); 640274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten 641274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten const SLDataFormat_PCM *df_pcm = &ar->mDataSink.mFormat.mPCM; 642274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten 643b0cf731f4d81a3d6f8cac31de3cdddbbf555c305Jean-Michel Trivi // the following platform-independent fields have been initialized in CreateAudioRecorder() 644712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi // ar->mNumChannels 645712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi // ar->mSampleRateMilliHz 646712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi 647274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec); 648712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi 6498c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent checkAndSetPerformanceModePre(ar); 6508c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 6518c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent audio_input_flags_t policy; 6528c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent switch (ar->mPerformanceMode) { 6538c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent case ANDROID_PERFORMANCE_MODE_NONE: 6548c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent case ANDROID_PERFORMANCE_MODE_POWER_SAVING: 6558c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent policy = AUDIO_INPUT_FLAG_NONE; 6568c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 6578c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS: 6588c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent policy = AUDIO_INPUT_FLAG_FAST; 6598c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 6608c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent case ANDROID_PERFORMANCE_MODE_LATENCY: 6618c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent default: 6628c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent policy = (audio_input_flags_t)(AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW); 6638c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent break; 6648c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent } 6655e3bcbffacc309fb2d9e002b7bc1ed131fddc6fcGlenn Kasten 6664e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SL_LOGV("Audio Record format: %dch(0x%x), %dbit, %dKHz", 6674e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean df_pcm->numChannels, 6684e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean df_pcm->channelMask, 6694e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean df_pcm->bitsPerSample, 6704e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean df_pcm->samplesPerSec / 1000000); 67133f46b8cd9ece650736a4aa5294318c6b51b2ffdilewis 6724e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // note that df_pcm->channelMask has already been validated during object creation. 6734e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean audio_channel_mask_t channelMask = sles_to_audio_input_channel_mask(df_pcm->channelMask); 67433f46b8cd9ece650736a4aa5294318c6b51b2ffdilewis 67528340d1d9199b789f0db015680b008c98084f0b7ilewis // To maintain backward compatibility with previous releases, ignore 67628340d1d9199b789f0db015680b008c98084f0b7ilewis // channel masks that are not indexed. 67728340d1d9199b789f0db015680b008c98084f0b7ilewis if (channelMask == AUDIO_CHANNEL_INVALID 67828340d1d9199b789f0db015680b008c98084f0b7ilewis || audio_channel_mask_get_representation(channelMask) 67928340d1d9199b789f0db015680b008c98084f0b7ilewis == AUDIO_CHANNEL_REPRESENTATION_POSITION) { 68033f46b8cd9ece650736a4aa5294318c6b51b2ffdilewis channelMask = audio_channel_in_mask_from_count(df_pcm->numChannels); 68128340d1d9199b789f0db015680b008c98084f0b7ilewis SL_LOGI("Emulating old channel mask behavior " 68228340d1d9199b789f0db015680b008c98084f0b7ilewis "(ignoring positional mask %#x, using default mask %#x based on " 68328340d1d9199b789f0db015680b008c98084f0b7ilewis "channel count of %d)", df_pcm->channelMask, channelMask, 68428340d1d9199b789f0db015680b008c98084f0b7ilewis df_pcm->numChannels); 68533f46b8cd9ece650736a4aa5294318c6b51b2ffdilewis } 68628340d1d9199b789f0db015680b008c98084f0b7ilewis SL_LOGV("SLES channel mask %#x converted to Android mask %#x", df_pcm->channelMask, channelMask); 6874e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 688712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi // initialize platform-specific CAudioRecorder fields 689274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten ar->mAudioRecord = new android::AudioRecord( 6902dc0674aba6242c677365b675795773738397ab9Glenn Kasten ar->mRecordSource, // source 691274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten sampleRate, // sample rate in Hertz 692274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten sles_to_android_sampleFormat(df_pcm), // format 6934e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean channelMask, // channel mask 694274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten android::String16(), // app ops 695274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten 0, // frameCount 6963af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi audioRecorder_callback,// callback_t 6973af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi (void*)ar, // user, callback data, here the AudioRecorder 6983af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 0, // notificationFrames 699213c31153b9bda7b5a091f2996da7b655c8ed451Glenn Kasten AUDIO_SESSION_ALLOCATE, 7005e3bcbffacc309fb2d9e002b7bc1ed131fddc6fcGlenn Kasten android::AudioRecord::TRANSFER_CALLBACK, 7015e3bcbffacc309fb2d9e002b7bc1ed131fddc6fcGlenn Kasten // transfer type 7025e3bcbffacc309fb2d9e002b7bc1ed131fddc6fcGlenn Kasten policy); // audio_input_flags_t 7033af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 704274c079467f6ade516771b4c721c67041243cf4bGlenn Kasten android::status_t status = ar->mAudioRecord->initCheck(); 7052dc0674aba6242c677365b675795773738397ab9Glenn Kasten if (android::NO_ERROR != status) { 7062dc0674aba6242c677365b675795773738397ab9Glenn Kasten SL_LOGE("android_audioRecorder_realize(%p) error creating AudioRecord object; status %d", 7072dc0674aba6242c677365b675795773738397ab9Glenn Kasten ar, status); 7082dc0674aba6242c677365b675795773738397ab9Glenn Kasten // FIXME should return a more specific result depending on status 7093af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi result = SL_RESULT_CONTENT_UNSUPPORTED; 7102dc0674aba6242c677365b675795773738397ab9Glenn Kasten ar->mAudioRecord.clear(); 711677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent return result; 7123af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 7133af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 7148c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent // update performance mode according to actual flags granted to AudioRecord 7158c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent checkAndSetPerformanceModePost(ar); 7168c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent 71715f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean // If there is a JavaAudioRoutingProxy associated with this recorder, hook it up... 71815f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean JNIEnv* j_env = NULL; 71915f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean jclass clsAudioRecord = NULL; 72015f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean jmethodID midRoutingProxy_connect = NULL; 72115f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean if (ar->mAndroidConfiguration.mRoutingProxy != NULL && 72215f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean (j_env = android::AndroidRuntime::getJNIEnv()) != NULL && 72315f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean (clsAudioRecord = j_env->FindClass("android/media/AudioRecord")) != NULL && 72415f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean (midRoutingProxy_connect = 72515f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean j_env->GetMethodID(clsAudioRecord, "deferred_connect", "(J)V")) != NULL) { 72615f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean j_env->ExceptionClear(); 72715f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean j_env->CallVoidMethod(ar->mAndroidConfiguration.mRoutingProxy, 72815f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean midRoutingProxy_connect, 72915f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean ar->mAudioRecord.get()); 73015f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean if (j_env->ExceptionCheck()) { 73115f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean SL_LOGE("Java exception releasing recorder routing object."); 73215f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean result = SL_RESULT_INTERNAL_ERROR; 733677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent ar->mAudioRecord.clear(); 734677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent return result; 73515f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean } 73615f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean } 73715f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean 738677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent if (ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY) { 739677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent audio_session_t sessionId = ar->mAudioRecord->getSessionId(); 740677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent // initialize AEC 741677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent effect_descriptor_t *descriptor = &ar->mAcousticEchoCancellation.mAECDescriptor; 742677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent if (memcmp(SL_IID_ANDROIDACOUSTICECHOCANCELLATION, &descriptor->type, 743677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent sizeof(effect_uuid_t)) == 0) { 744677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent if ((ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) || 745677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent (descriptor->flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { 746677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent SL_LOGV("Need to initialize AEC for AudioRecorder=%p", ar); 747677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent android_aec_init(sessionId, &ar->mAcousticEchoCancellation); 748677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent } 749677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent } 750677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent 751677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent // initialize AGC 752677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent descriptor = &ar->mAutomaticGainControl.mAGCDescriptor; 753677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent if (memcmp(SL_IID_ANDROIDAUTOMATICGAINCONTROL, &descriptor->type, 754677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent sizeof(effect_uuid_t)) == 0) { 755677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent if ((ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) || 756677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent (descriptor->flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { 757677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent SL_LOGV("Need to initialize AGC for AudioRecorder=%p", ar); 758677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent android_agc_init(sessionId, &ar->mAutomaticGainControl); 759677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent } 760677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent } 761677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent 762677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent // initialize NS 763677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent descriptor = &ar->mNoiseSuppression.mNSDescriptor; 764677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent if (memcmp(SL_IID_ANDROIDNOISESUPPRESSION, &descriptor->type, 765677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent sizeof(effect_uuid_t)) == 0) { 766677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent if ((ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) || 767677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent (descriptor->flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { 768677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent SL_LOGV("Need to initialize NS for AudioRecorder=%p", ar); 769677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent android_ns_init(sessionId, &ar->mNoiseSuppression); 770677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent } 771677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent } 772677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent } 773677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent 7743af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi return result; 7753af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi} 7763af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 7773af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 7783af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi//----------------------------------------------------------------------------- 779460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten/** 780460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten * Called with a lock on AudioRecorder, and blocks until safe to destroy 781460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten */ 782460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kastenvoid android_audioRecorder_preDestroy(CAudioRecorder* ar) { 783460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten object_unlock_exclusive(&ar->mObject); 784460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten if (ar->mCallbackProtector != 0) { 785460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten ar->mCallbackProtector->requestCbExitAndWait(); 786460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten } 787460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten object_lock_exclusive(&ar->mObject); 788460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten} 789460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten 790460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten 791460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten//----------------------------------------------------------------------------- 7923af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivivoid android_audioRecorder_destroy(CAudioRecorder* ar) { 7933af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi SL_LOGV("android_audioRecorder_destroy(%p) entering", ar); 7943af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 795e5ede1a139fcedbf075675179d919fbe731898f0Glenn Kasten if (ar->mAudioRecord != 0) { 7963af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi ar->mAudioRecord->stop(); 797460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten ar->mAudioRecord.clear(); 7983af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 799e5ede1a139fcedbf075675179d919fbe731898f0Glenn Kasten // explicit destructor 800e5ede1a139fcedbf075675179d919fbe731898f0Glenn Kasten ar->mAudioRecord.~sp(); 801460bdad43aaec3c6ffe7f259719e00807742ad6dGlenn Kasten ar->mCallbackProtector.~sp(); 8023af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi} 8033af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 8043af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 8053af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi//----------------------------------------------------------------------------- 8063af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivivoid android_audioRecorder_setRecordState(CAudioRecorder* ar, SLuint32 state) { 807a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGV("android_audioRecorder_setRecordState(%p, %u) entering", ar, state); 8083af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 809e5ede1a139fcedbf075675179d919fbe731898f0Glenn Kasten if (ar->mAudioRecord == 0) { 8103af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi return; 8113af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 8123af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 8133af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi switch (state) { 8143af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi case SL_RECORDSTATE_STOPPED: 8153af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi ar->mAudioRecord->stop(); 8163af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi break; 8173af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi case SL_RECORDSTATE_PAUSED: 8183af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // Note that pausing is treated like stop as this implementation only records to a buffer 8193af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // queue, so there is no notion of destination being "opened" or "closed" (See description 8203af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // of SL_RECORDSTATE in specification) 8213af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi ar->mAudioRecord->stop(); 8223af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi break; 8233af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi case SL_RECORDSTATE_RECORDING: 8243af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi ar->mAudioRecord->start(); 8253af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi break; 8263af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi default: 8273af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi break; 8283af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 8293af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 8303af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi} 8313b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 8323b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 8333b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi//----------------------------------------------------------------------------- 834bcfe680db1e392f3bb29382c2e15e89c3af783edGlenn Kastenvoid android_audioRecorder_useRecordEventMask(CAudioRecorder *ar) { 8353b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi IRecord *pRecordItf = &ar->mRecord; 8363b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi SLuint32 eventFlags = pRecordItf->mCallbackEventsMask; 8373b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 838e5ede1a139fcedbf075675179d919fbe731898f0Glenn Kasten if (ar->mAudioRecord == 0) { 8393b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi return; 8403b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi } 8413b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 8423b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi if ((eventFlags & SL_RECORDEVENT_HEADATMARKER) && (pRecordItf->mMarkerPosition != 0)) { 8433b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi ar->mAudioRecord->setMarkerPosition((uint32_t)((((int64_t)pRecordItf->mMarkerPosition 8443b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi * sles_to_android_sampleRate(ar->mSampleRateMilliHz)))/1000)); 8453b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi } else { 8463b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi // clear marker 8473b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi ar->mAudioRecord->setMarkerPosition(0); 8483b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi } 8493b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 8503b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi if (eventFlags & SL_RECORDEVENT_HEADATNEWPOS) { 851a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten SL_LOGV("pos update period %d", pRecordItf->mPositionUpdatePeriod); 8523b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi ar->mAudioRecord->setPositionUpdatePeriod( 8533b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi (uint32_t)((((int64_t)pRecordItf->mPositionUpdatePeriod 8543b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi * sles_to_android_sampleRate(ar->mSampleRateMilliHz)))/1000)); 8553b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi } else { 8563b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi // clear periodic update 8573b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi ar->mAudioRecord->setPositionUpdatePeriod(0); 8583b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi } 8593b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 8603b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi if (eventFlags & SL_RECORDEVENT_HEADATLIMIT) { 8613b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi // FIXME support SL_RECORDEVENT_HEADATLIMIT 862a7b79e766ec6d95e9236168c27461c2ebaef4659Glenn Kasten SL_LOGD("[ FIXME: IRecord_SetCallbackEventsMask(SL_RECORDEVENT_HEADATLIMIT) on an " 8633b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi "SL_OBJECTID_AUDIORECORDER to be implemented ]"); 8643b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi } 8653b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 8663b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi if (eventFlags & SL_RECORDEVENT_HEADMOVING) { 8673b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi // FIXME support SL_RECORDEVENT_HEADMOVING 868a7b79e766ec6d95e9236168c27461c2ebaef4659Glenn Kasten SL_LOGD("[ FIXME: IRecord_SetCallbackEventsMask(SL_RECORDEVENT_HEADMOVING) on an " 8693b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi "SL_OBJECTID_AUDIORECORDER to be implemented ]"); 8703b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi } 8713b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 8723b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi if (eventFlags & SL_RECORDEVENT_BUFFER_FULL) { 873f6cca2f731329d101651348d1b7e51ead7b1290aJean-Michel Trivi // nothing to do for SL_RECORDEVENT_BUFFER_FULL since this will not be encountered on 874f6cca2f731329d101651348d1b7e51ead7b1290aJean-Michel Trivi // recording to buffer queues 8753b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi } 8763b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 8773b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi if (eventFlags & SL_RECORDEVENT_HEADSTALLED) { 878f6cca2f731329d101651348d1b7e51ead7b1290aJean-Michel Trivi // nothing to do for SL_RECORDEVENT_HEADSTALLED, callback event will be checked against mask 879f6cca2f731329d101651348d1b7e51ead7b1290aJean-Michel Trivi // when AudioRecord::EVENT_OVERRUN is encountered 880f6cca2f731329d101651348d1b7e51ead7b1290aJean-Michel Trivi 8813b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi } 8823b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi 8833b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi} 884b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivi 885b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivi 886b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivi//----------------------------------------------------------------------------- 887b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivivoid android_audioRecorder_getPosition(CAudioRecorder *ar, SLmillisecond *pPosMsec) { 888e5ede1a139fcedbf075675179d919fbe731898f0Glenn Kasten if ((NULL == ar) || (ar->mAudioRecord == 0)) { 889b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivi *pPosMsec = 0; 890b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivi } else { 891b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivi uint32_t positionInFrames; 892b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivi ar->mAudioRecord->getPosition(&positionInFrames); 8931a9c2615d0933d183fcb1b9e34ec8f0da2a85153Glenn Kasten if (ar->mSampleRateMilliHz == UNKNOWN_SAMPLERATE) { 894b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivi *pPosMsec = 0; 895b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivi } else { 896b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivi *pPosMsec = ((int64_t)positionInFrames * 1000) / 897b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivi sles_to_android_sampleRate(ar->mSampleRateMilliHz); 898b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivi } 899b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivi } 900b5ef0195d7b8fa1fceae5ef8a256ed19eb03cbedJean-Michel Trivi} 901