AudioRecorder_to_android.cpp revision a4b4d478171631eaa97e933eb46c1ff01bd04daa
11a9c27c312ba20b2ceafcde18ce451724782d2a5Ficus Kirkpatrick/* 21a9c27c312ba20b2ceafcde18ce451724782d2a5Ficus Kirkpatrick * Copyright (C) 2010 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 48451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 6e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy * You may obtain a copy of the License at 78872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger * 8e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy * http://www.apache.org/licenses/LICENSE-2.0 9e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy * 1046cb9bdbf56b27cbf2ab878b41d21e30896a4feaLeon Scroggins * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1669a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "sles_allinclusive.h" 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_prompts.h" 208451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// use this flag to dump all recorded audio into a file 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#define MONITOR_RECORDING 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef MONITOR_RECORDING 2469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes#define MONITOR_TARGET "/sdcard/monitor.raw" 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic FILE* gMonitorFp = NULL; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 288451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define KEY_RECORDING_SOURCE_PARAMSIZE sizeof(SLuint32) 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define KEY_RECORDING_PRESET_PARAMSIZE sizeof(SLuint32) 328451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//----------------------------------------------------------------------------- 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Internal utility functions 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//---------------------------- 368451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSLresult audioRecorder_setPreset(CAudioRecorder* ar, SLuint32 recordPreset) { 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SLresult result = SL_RESULT_SUCCESS; 39f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen 408451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes int newRecordSource = android::AUDIO_SOURCE_DEFAULT; 41f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen switch (recordPreset) { 42f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen case SL_ANDROID_RECORDING_PRESET_GENERIC: 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newRecordSource = android::AUDIO_SOURCE_DEFAULT; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 453762c311729fe9f3af085c14c5c1fb471d994c03Steve Block case SL_ANDROID_RECORDING_PRESET_CAMCORDER: 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newRecordSource = android::AUDIO_SOURCE_CAMCORDER; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION: 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newRecordSource = android::AUDIO_SOURCE_VOICE_RECOGNITION; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION: 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newRecordSource = android::AUDIO_SOURCE_VOICE_COMMUNICATION; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SL_ANDROID_RECORDING_PRESET_NONE: 55c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed // it is an error to set preset "none" 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SL_LOGE(ERROR_RECORDERPRESET_SET_UNKNOWN_PRESET); 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = SL_RESULT_PARAMETER_INVALID; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // recording preset needs to be set before the object is realized 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (ap->mAudioRecord is supposed to be NULL until then) 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SL_OBJECT_STATE_UNREALIZED != ar->mObject.mState) { 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SL_LOGE(ERROR_RECORDERPRESET_REALIZED); 65c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed result = SL_RESULT_PRECONDITIONS_VIOLATED; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ar->mRecordSource = newRecordSource; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 70c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed return result; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSLresult audioRecorder_getPreset(CAudioRecorder* ar, SLuint32* pPreset) { 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SLresult result = SL_RESULT_SUCCESS; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (ar->mRecordSource) { 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case android::AUDIO_SOURCE_DEFAULT: 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case android::AUDIO_SOURCE_MIC: 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pPreset = SL_ANDROID_RECORDING_PRESET_GENERIC; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case android::AUDIO_SOURCE_VOICE_UPLINK: 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case android::AUDIO_SOURCE_VOICE_DOWNLINK: 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case android::AUDIO_SOURCE_VOICE_CALL: 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pPreset = SL_ANDROID_RECORDING_PRESET_NONE; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case android::AUDIO_SOURCE_VOICE_RECOGNITION: 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pPreset = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case android::AUDIO_SOURCE_CAMCORDER: 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pPreset = SL_ANDROID_RECORDING_PRESET_CAMCORDER; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case android::AUDIO_SOURCE_VOICE_COMMUNICATION: 94c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed *pPreset = SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pPreset = SL_ANDROID_RECORDING_PRESET_NONE; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = SL_RESULT_INTERNAL_ERROR; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 104c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid audioRecorder_handleNewPos_lockRecord(CAudioRecorder* ar) { 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //SL_LOGV("received event EVENT_NEW_POS from AudioRecord"); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project slRecordCallback callback = NULL; 109c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed void* callbackPContext = NULL; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interface_lock_shared(&ar->mRecord); 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project callback = ar->mRecord.mCallback; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project callbackPContext = ar->mRecord.mContext; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interface_unlock_shared(&ar->mRecord); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL != callback) { 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // getting this event implies SL_RECORDEVENT_HEADATNEWPOS was set in the event mask 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (*callback)(&ar->mRecord.mItf, callbackPContext, SL_RECORDEVENT_HEADATNEWPOS); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid audioRecorder_handleMarker_lockRecord(CAudioRecorder* ar) { 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //SL_LOGV("received event EVENT_MARKER from AudioRecord"); 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project slRecordCallback callback = NULL; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* callbackPContext = NULL; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interface_lock_shared(&ar->mRecord); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project callback = ar->mRecord.mCallback; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project callbackPContext = ar->mRecord.mContext; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interface_unlock_shared(&ar->mRecord); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL != callback) { 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // getting this event implies SL_RECORDEVENT_HEADATMARKER was set in the event mask 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (*callback)(&ar->mRecord.mItf, callbackPContext, SL_RECORDEVENT_HEADATMARKER); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid audioRecorder_handleOverrun_lockRecord(CAudioRecorder* ar) { 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //SL_LOGV("received event EVENT_OVERRUN from AudioRecord"); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project slRecordCallback callback = NULL; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* callbackPContext = NULL; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interface_lock_shared(&ar->mRecord); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ar->mRecord.mCallbackEventsMask & SL_RECORDEVENT_HEADSTALLED) { 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project callback = ar->mRecord.mCallback; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project callbackPContext = ar->mRecord.mContext; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interface_unlock_shared(&ar->mRecord); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL != callback) { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (*callback)(&ar->mRecord.mItf, callbackPContext, SL_RECORDEVENT_HEADSTALLED); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1579f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik//----------------------------------------------------------------------------- 1589f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris CraikSLresult android_audioRecorder_checkSourceSinkSupport(CAudioRecorder* ar) { 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SLDataSource *pAudioSrc = &ar->mDataSource.u.mSource; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SLDataSink *pAudioSnk = &ar->mDataSink.u.mSink; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1636b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // Sink check: 1646b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // only buffer queue sinks are supported, regardless of the data source 165f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen if (SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE != *(SLuint32 *)pAudioSnk->pLocator) { 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SL_LOGE(ERROR_RECORDER_SINK_MUST_BE_ANDROIDSIMPLEBUFFERQUEUE); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SL_RESULT_PARAMETER_INVALID; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // only PCM buffer queues are supported 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SLuint32 formatType = *(SLuint32 *)pAudioSnk->pFormat; 1711a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien if (SL_DATAFORMAT_PCM == formatType) { 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *)ar->mDataSink.u.mSink.pFormat; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ar->mSampleRateMilliHz = df_pcm->samplesPerSec; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ar->mNumChannels = df_pcm->numChannels; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SL_LOGV("AudioRecorder requested sample rate = %lumHz, %u channel(s)", 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ar->mSampleRateMilliHz, ar->mNumChannels); 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SL_LOGE(ERROR_RECORDER_SINK_FORMAT_MUST_BE_PCM); 1807384b428c445f07540fd6a80a21727d03be65d96Mathieu Chartier return SL_RESULT_PARAMETER_INVALID; 1817384b428c445f07540fd6a80a21727d03be65d96Mathieu Chartier } 1827384b428c445f07540fd6a80a21727d03be65d96Mathieu Chartier } 1837384b428c445f07540fd6a80a21727d03be65d96Mathieu Chartier 1847384b428c445f07540fd6a80a21727d03be65d96Mathieu Chartier // Source check: 1857384b428c445f07540fd6a80a21727d03be65d96Mathieu Chartier // only input device sources are supported 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // check it's an IO device 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SL_DATALOCATOR_IODEVICE != *(SLuint32 *)pAudioSrc->pLocator) { 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SL_LOGE(ERROR_RECORDER_SOURCE_MUST_BE_IODEVICE); 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SL_RESULT_PARAMETER_INVALID; 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // check it's an input device 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SLDataLocator_IODevice *dl_iod = (SLDataLocator_IODevice *) pAudioSrc->pLocator; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SL_IODEVICE_AUDIOINPUT != dl_iod->deviceType) { 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SL_LOGE(ERROR_RECORDER_IODEVICE_MUST_BE_AUDIOINPUT); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SL_RESULT_PARAMETER_INVALID; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // check it's the default input device, others aren't supported here 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SL_DEFAULTDEVICEID_AUDIOINPUT != dl_iod->deviceID) { 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SL_LOGE(ERROR_RECORDER_INPUT_ID_MUST_BE_DEFAULT); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SL_RESULT_PARAMETER_INVALID; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SL_RESULT_SUCCESS; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//----------------------------------------------------------------------------- 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void audioRecorder_callback(int event, void* user, void *info) { 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //SL_LOGV("audioRecorder_callback(%d, %p, %p) entering", event, user, info); 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CAudioRecorder *ar = (CAudioRecorder *)user; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void * callbackPContext = NULL; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch(event) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case android::AudioRecord::EVENT_MORE_DATA: { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project slBufferQueueCallback callback = NULL; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android::AudioRecord::Buffer* pBuff = (android::AudioRecord::Buffer*)info; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // push data to the buffer queue 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interface_lock_exclusive(&ar->mBufferQueue); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ar->mBufferQueue.mState.count != 0) { 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(ar->mBufferQueue.mFront != ar->mBufferQueue.mRear); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BufferHeader *oldFront = ar->mBufferQueue.mFront; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BufferHeader *newFront = &oldFront[1]; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // FIXME handle 8bit based on buffer format 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project short *pDest = (short*)((char *)oldFront->mBuffer + ar->mBufferQueue.mSizeConsumed); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ar->mBufferQueue.mSizeConsumed + pBuff->size < oldFront->mSize) { 2328451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes // can't consume the whole or rest of the buffer in one shot 2332e0103eb340822f9d580c1aa8492bae8394b8243Leon Scroggins III ar->mBufferQueue.mSizeConsumed += pBuff->size; 2342e0103eb340822f9d580c1aa8492bae8394b8243Leon Scroggins III // leave pBuff->size untouched 2352e0103eb340822f9d580c1aa8492bae8394b8243Leon Scroggins III // consume data 2362e0103eb340822f9d580c1aa8492bae8394b8243Leon Scroggins III // FIXME can we avoid holding the lock during the copy? 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy (pDest, pBuff->i16, pBuff->size); 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef MONITOR_RECORDING 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL != gMonitorFp) { fwrite(pBuff->i16, pBuff->size, 1, gMonitorFp); } 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // finish pushing the buffer or push the buffer in one shot 2438451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes pBuff->size = oldFront->mSize - ar->mBufferQueue.mSizeConsumed; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ar->mBufferQueue.mSizeConsumed = 0; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newFront == &ar->mBufferQueue.mArray[ar->mBufferQueue.mNumBuffers + 1]) { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newFront = ar->mBufferQueue.mArray; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ar->mBufferQueue.mFront = newFront; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ar->mBufferQueue.mState.count--; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ar->mBufferQueue.mState.playIndex++; 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // consume data 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // FIXME can we avoid holding the lock during the copy? 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy (pDest, pBuff->i16, pBuff->size); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef MONITOR_RECORDING 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL != gMonitorFp) { fwrite(pBuff->i16, pBuff->size, 1, gMonitorFp); } 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // data has been copied to the buffer, and the buffer queue state has been updated 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we will notify the client if applicable 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project callback = ar->mBufferQueue.mCallback; 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // save callback data 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project callbackPContext = ar->mBufferQueue.mContext; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2648451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes } else { 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // no destination to push the data 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pBuff->size = 0; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interface_unlock_exclusive(&ar->mBufferQueue); 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // notify client 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL != callback) { 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (*callback)(&ar->mBufferQueue.mItf, callbackPContext); 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case android::AudioRecord::EVENT_OVERRUN: 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project audioRecorder_handleOverrun_lockRecord(ar); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2818451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes case android::AudioRecord::EVENT_MARKER: 2822e0103eb340822f9d580c1aa8492bae8394b8243Leon Scroggins III audioRecorder_handleMarker_lockRecord(ar); 2832e0103eb340822f9d580c1aa8492bae8394b8243Leon Scroggins III break; 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case android::AudioRecord::EVENT_NEW_POS: 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project audioRecorder_handleNewPos_lockRecord(ar); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//----------------------------------------------------------------------------- 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSLresult android_audioRecorder_create(CAudioRecorder* ar) { 2951103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SL_LOGV("android_audioRecorder_create(%p) entering", ar); 2961103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed 2971103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SLresult result = SL_RESULT_SUCCESS; 2981103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed 2991103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed // the following platform-independent fields have been initialized in CreateAudioRecorder() 3001103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed // ar->mNumChannels 3011103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed // ar->mSampleRateMilliHz 3021103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed 3031103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed ar->mAudioRecord = NULL; 3041103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed ar->mRecordSource = android::AUDIO_SOURCE_DEFAULT; 3051103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed 3061103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed return result; 3071103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed} 3081103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed 3091103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed 3101103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed//----------------------------------------------------------------------------- 3111103b3255945d2eb2fa9c191e84e2270b343cca9Mike ReedSLresult android_audioRecorder_setConfig(CAudioRecorder* ar, const SLchar *configKey, 3121103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed const void *pConfigValue, SLuint32 valueSize) { 3131103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed 3141103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SLresult result = SL_RESULT_SUCCESS; 3151103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed 3161103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed if (NULL == ar) { 3171103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed result = SL_RESULT_INTERNAL_ERROR; 3181103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed } else if (NULL == pConfigValue) { 3191103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SL_LOGE(ERROR_CONFIG_NULL_PARAM); 3201103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed result = SL_RESULT_PARAMETER_INVALID; 3211103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed 3221103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed } else if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_RECORDING_PRESET) == 0) { 3231103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed 3241103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed // recording preset 3251103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed if (KEY_RECORDING_PRESET_PARAMSIZE > valueSize) { 3261103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 3271103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed result = SL_RESULT_PARAMETER_INVALID; 3281103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed } else { 3291103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed result = audioRecorder_setPreset(ar, *(SLuint32*)pConfigValue); 3301103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed } 3311103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed 3321103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed } else { 3331103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY); 3341103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed result = SL_RESULT_PARAMETER_INVALID; 3351103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed } 3361103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed 3371103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed return result; 3381103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed} 3391103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed 3401103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed 3411103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed//----------------------------------------------------------------------------- 3421103b3255945d2eb2fa9c191e84e2270b343cca9Mike ReedSLresult android_audioRecorder_getConfig(CAudioRecorder* ar, const SLchar *configKey, 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SLuint32* pValueSize, void *pConfigValue) { 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SLresult result = SL_RESULT_SUCCESS; 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat if (NULL == ar) { 34836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat return SL_RESULT_INTERNAL_ERROR; 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (NULL == pValueSize) { 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SL_LOGE(ERROR_CONFIG_NULL_PARAM); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = SL_RESULT_PARAMETER_INVALID; 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35342a1d08df7d417fd4e67eabc91ff05ee77fd9995Mike Reed } else if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_RECORDING_PRESET) == 0) { 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // recording preset 35642a1d08df7d417fd4e67eabc91ff05ee77fd9995Mike Reed if (KEY_RECORDING_PRESET_PARAMSIZE > *pValueSize) { 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = SL_RESULT_PARAMETER_INVALID; 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3601103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed *pValueSize = KEY_RECORDING_PRESET_PARAMSIZE; 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL != pConfigValue) { 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = audioRecorder_getPreset(ar, (SLuint32*)pConfigValue); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 36736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY); 368de92f4c72be8537d2efff6024390b9ab706286e1Bo Liu result = SL_RESULT_PARAMETER_INVALID; 369de92f4c72be8537d2efff6024390b9ab706286e1Bo Liu } 370de92f4c72be8537d2efff6024390b9ab706286e1Bo Liu 3718872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger return result; 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//----------------------------------------------------------------------------- 3766ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad EsfahbodSLresult android_audioRecorder_realize(CAudioRecorder* ar, SLboolean async) { 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SL_LOGV("android_audioRecorder_realize(%p) entering", ar); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SLresult result = SL_RESULT_SUCCESS; 38036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat 3816ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod // initialize platform-independent CAudioRecorder fields 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE != ar->mDataSink.mLocator.mLocatorType) { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SL_LOGE(ERROR_RECORDER_SINK_MUST_BE_ANDROIDSIMPLEBUFFERQUEUE); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SL_RESULT_CONTENT_UNSUPPORTED; 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3861a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien // the following platform-independent fields have been initialized in CreateAudioRecorder() 3871a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien // ar->mNumChannels 3881a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien // ar->mSampleRateMilliHz 3891a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 3901a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien SL_LOGV("new AudioRecord %u channels, %lu mHz", ar->mNumChannels, ar->mSampleRateMilliHz); 3911a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 3921a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien // initialize platform-specific CAudioRecorder fields 3931a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien ar->mAudioRecord = new android::AudioRecord(); 3941a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien ar->mAudioRecord->set(ar->mRecordSource, // source 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sles_to_android_sampleRate(ar->mSampleRateMilliHz), // sample rate in Hertz 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android::AudioSystem::PCM_16_BIT, //FIXME use format from buffer queue sink 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sles_to_android_channelMask(ar->mNumChannels, 0 /*no channel mask*/), // channel config 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0, //frameCount min 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0, // flags 40036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat audioRecorder_callback,// callback_t 40136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat (void*)ar, // user, callback data, here the AudioRecorder 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0, // notificationFrames 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project false); // threadCanCallJava, note: this will prevent direct Java 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // callbacks, but we don't want them in the recording loop 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (android::NO_ERROR != ar->mAudioRecord->initCheck()) { 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SL_LOGE("android_audioRecorder_realize(%p) error creating AudioRecord object", ar); 4088790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III result = SL_RESULT_CONTENT_UNSUPPORTED; 4098790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III } 4108790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III 4118790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III#ifdef MONITOR_RECORDING 4128790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III gMonitorFp = fopen(MONITOR_TARGET, "w"); 4138790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III if (NULL == gMonitorFp) { SL_LOGE("error opening %s", MONITOR_TARGET); } 4148790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III else { SL_LOGE("recording to %s", MONITOR_TARGET); } // SL_LOGE so it's always displayed 4158790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III#endif 4168790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III 4178790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III return result; 4188790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III} 4198790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III 420e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy 42147cd8e921db73e894f94ec4729ade90da50996f5Chris Craik//----------------------------------------------------------------------------- 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid android_audioRecorder_destroy(CAudioRecorder* ar) { 423e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy SL_LOGV("android_audioRecorder_destroy(%p) entering", ar); 424e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy 425a08d10fa7051668b629d561bb8411e34d28fdabfMathieu Chartier if (NULL != ar->mAudioRecord) { 4261abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik ar->mAudioRecord->stop(); 4271abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik delete ar->mAudioRecord; 4281abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik ar->mAudioRecord = NULL; 4298790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III } 4308790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III 4318790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III#ifdef MONITOR_RECORDING 4328790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III if (NULL != gMonitorFp) { 433cf6f7a0f006c0fcf59bb634cbe79f2a8500fd92aElliott Hughes fclose(gMonitorFp); 43436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat gMonitorFp = NULL; 4351abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik } 43647cd8e921db73e894f94ec4729ade90da50996f5Chris Craik#endif 437cf6f7a0f006c0fcf59bb634cbe79f2a8500fd92aElliott Hughes} 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4406b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen//----------------------------------------------------------------------------- 4411abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craikvoid android_audioRecorder_setRecordState(CAudioRecorder* ar, SLuint32 state) { 4421abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik SL_LOGV("android_audioRecorder_setRecordState(%p, %lu) entering", ar, state); 4439f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik 4448790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III if (NULL == ar->mAudioRecord) { 4458790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III return; 4468790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III } 4478790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III 4481abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik switch (state) { 4491abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik case SL_RECORDSTATE_STOPPED: 4509f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik ar->mAudioRecord->stop(); 4519f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik break; 4529f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik case SL_RECORDSTATE_PAUSED: 4539f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik // Note that pausing is treated like stop as this implementation only records to a buffer 4549f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik // queue, so there is no notion of destination being "opened" or "closed" (See description 4559f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik // of SL_RECORDSTATE in specification) 456e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy ar->mAudioRecord->stop(); 4576b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen break; 458f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen case SL_RECORDSTATE_RECORDING: 459f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen ar->mAudioRecord->start(); 460f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen break; 461cf6f7a0f006c0fcf59bb634cbe79f2a8500fd92aElliott Hughes default: 462cf6f7a0f006c0fcf59bb634cbe79f2a8500fd92aElliott Hughes break; 463b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat } 464cf6f7a0f006c0fcf59bb634cbe79f2a8500fd92aElliott Hughes 465f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen} 466f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//----------------------------------------------------------------------------- 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid android_audioRecorder_useEventMask(CAudioRecorder *ar) { 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IRecord *pRecordItf = &ar->mRecord; 471cf6f7a0f006c0fcf59bb634cbe79f2a8500fd92aElliott Hughes SLuint32 eventFlags = pRecordItf->mCallbackEventsMask; 47236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat 473cf6f7a0f006c0fcf59bb634cbe79f2a8500fd92aElliott Hughes if (NULL == ar->mAudioRecord) { 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((eventFlags & SL_RECORDEVENT_HEADATMARKER) && (pRecordItf->mMarkerPosition != 0)) { 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ar->mAudioRecord->setMarkerPosition((uint32_t)((((int64_t)pRecordItf->mMarkerPosition 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sles_to_android_sampleRate(ar->mSampleRateMilliHz)))/1000)); 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // clear marker 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ar->mAudioRecord->setMarkerPosition(0); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (eventFlags & SL_RECORDEVENT_HEADATNEWPOS) { 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SL_LOGV("pos update period %ld", pRecordItf->mPositionUpdatePeriod); 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ar->mAudioRecord->setPositionUpdatePeriod( 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (uint32_t)((((int64_t)pRecordItf->mPositionUpdatePeriod 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sles_to_android_sampleRate(ar->mSampleRateMilliHz)))/1000)); 490b644a3b84521e2155a5af985a4d4ed305474e567Derek Sollenberger } else { 491b644a3b84521e2155a5af985a4d4ed305474e567Derek Sollenberger // clear periodic update 492b644a3b84521e2155a5af985a4d4ed305474e567Derek Sollenberger ar->mAudioRecord->setPositionUpdatePeriod(0); 493cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craik } 494e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy 495e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy if (eventFlags & SL_RECORDEVENT_HEADATLIMIT) { 496e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy // FIXME support SL_RECORDEVENT_HEADATLIMIT 497e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy SL_LOGD("[ FIXME: IRecord_SetCallbackEventsMask(SL_RECORDEVENT_HEADATLIMIT) on an " 498e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy "SL_OBJECTID_AUDIORECORDER to be implemented ]"); 499e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy } 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 501e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy if (eventFlags & SL_RECORDEVENT_HEADMOVING) { 502e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy // FIXME support SL_RECORDEVENT_HEADMOVING 503e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy SL_LOGD("[ FIXME: IRecord_SetCallbackEventsMask(SL_RECORDEVENT_HEADMOVING) on an " 504e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy "SL_OBJECTID_AUDIORECORDER to be implemented ]"); 505e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy } 506e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy 5078451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes if (eventFlags & SL_RECORDEVENT_BUFFER_FULL) { 508e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy // nothing to do for SL_RECORDEVENT_BUFFER_FULL since this will not be encountered on 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // recording to buffer queues 510b644a3b84521e2155a5af985a4d4ed305474e567Derek Sollenberger } 511b644a3b84521e2155a5af985a4d4ed305474e567Derek Sollenberger 512b644a3b84521e2155a5af985a4d4ed305474e567Derek Sollenberger if (eventFlags & SL_RECORDEVENT_HEADSTALLED) { 513cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craik // nothing to do for SL_RECORDEVENT_HEADSTALLED, callback event will be checked against mask 514b644a3b84521e2155a5af985a4d4ed305474e567Derek Sollenberger // when AudioRecord::EVENT_OVERRUN is encountered 515cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craik 516cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craik } 517cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craik 518cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craik} 519cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craik 520cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craik 521cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craik//----------------------------------------------------------------------------- 522cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craikvoid android_audioRecorder_getPosition(CAudioRecorder *ar, SLmillisecond *pPosMsec) { 523cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craik if ((NULL == ar) || (NULL == ar->mAudioRecord)) { 524cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craik *pPosMsec = 0; 525cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craik } else { 526e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy uint32_t positionInFrames; 527cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craik ar->mAudioRecord->getPosition(&positionInFrames); 528cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craik if (ar->mSampleRateMilliHz == 0) { 529cd0ba71aa942f35fcdb26808b86f20073b8aff92Chris Craik *pPosMsec = 0; 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 531e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy *pPosMsec = ((int64_t)positionInFrames * 1000) / 532e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy sles_to_android_sampleRate(ar->mSampleRateMilliHz); 533e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy } 534e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy } 535e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy} 536e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy