blob: 3b66c24d865f7d6ed2bc5fa9e00ef20e1b030c0b [file] [log] [blame]
Iliyan Malchev4765c432012-06-11 14:36:16 -07001/* AudioStreamInALSA.cpp
2 **
3 ** Copyright 2008-2009 Wind River Systems
4 ** Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
5 **
6 ** Licensed under the Apache License, Version 2.0 (the "License");
7 ** you may not use this file except in compliance with the License.
8 ** You may obtain a copy of the License at
9 **
10 ** http://www.apache.org/licenses/LICENSE-2.0
11 **
12 ** Unless required by applicable law or agreed to in writing, software
13 ** distributed under the License is distributed on an "AS IS" BASIS,
14 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 ** See the License for the specific language governing permissions and
16 ** limitations under the License.
17 */
18
19#include <errno.h>
20#include <stdarg.h>
21#include <sys/stat.h>
22#include <fcntl.h>
23#include <stdlib.h>
24#include <unistd.h>
25#include <dlfcn.h>
26
Ajay Dudani9746c472012-06-18 16:01:16 -070027#define LOG_TAG "AudioStreamInALSA"
Iliyan Malchev4765c432012-06-11 14:36:16 -070028//#define LOG_NDEBUG 0
Ajay Dudani9746c472012-06-18 16:01:16 -070029#define LOG_NDDEBUG 0
Iliyan Malchev4765c432012-06-11 14:36:16 -070030#include <utils/Log.h>
31#include <utils/String8.h>
32
33#include <cutils/properties.h>
34#include <media/AudioRecord.h>
35#include <hardware_legacy/power.h>
36
37#include "AudioHardwareALSA.h"
38
39extern "C" {
Ajay Dudani9746c472012-06-18 16:01:16 -070040#ifdef QCOM_CSDCLIENT_ENABLED
SathishKumar Mani5ff7a022012-09-14 11:36:35 -070041static int (*csd_start_record)(int);
42static int (*csd_stop_record)(void);
Iliyan Malchev4765c432012-06-11 14:36:16 -070043#endif
SathishKumar Mani5ff7a022012-09-14 11:36:35 -070044
Ajay Dudani9746c472012-06-18 16:01:16 -070045#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -070046#include "surround_filters_interface.h"
47#endif
48}
49
50namespace android_audio_legacy
51{
Ajay Dudani9746c472012-06-18 16:01:16 -070052#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -070053#define SURROUND_FILE_1R "/system/etc/surround_sound/filter1r.pcm"
54#define SURROUND_FILE_2R "/system/etc/surround_sound/filter2r.pcm"
55#define SURROUND_FILE_3R "/system/etc/surround_sound/filter3r.pcm"
56#define SURROUND_FILE_4R "/system/etc/surround_sound/filter4r.pcm"
57
58#define SURROUND_FILE_1I "/system/etc/surround_sound/filter1i.pcm"
59#define SURROUND_FILE_2I "/system/etc/surround_sound/filter2i.pcm"
60#define SURROUND_FILE_3I "/system/etc/surround_sound/filter3i.pcm"
61#define SURROUND_FILE_4I "/system/etc/surround_sound/filter4i.pcm"
62
63// Use AAC/DTS channel mapping as default channel mapping: C,FL,FR,Ls,Rs,LFE
64const int chanMap[] = { 1, 2, 4, 3, 0, 5 };
65#endif
66
67AudioStreamInALSA::AudioStreamInALSA(AudioHardwareALSA *parent,
68 alsa_handle_t *handle,
69 AudioSystem::audio_in_acoustics audio_acoustics) :
70 ALSAStreamOps(parent, handle),
71 mFramesLost(0),
SathishKumar Mani5ff7a022012-09-14 11:36:35 -070072 mAcoustics(audio_acoustics),
73 mParent(parent)
Ajay Dudani9746c472012-06-18 16:01:16 -070074#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -070075 , mFp_4ch(NULL),
76 mFp_6ch(NULL),
77 mRealCoeffs(NULL),
78 mImagCoeffs(NULL),
79 mSurroundObj(NULL),
80 mSurroundOutputBuffer(NULL),
81 mSurroundInputBuffer(NULL),
82 mSurroundOutputBufferIdx(0),
83 mSurroundInputBufferIdx(0)
84#endif
85{
Ajay Dudani9746c472012-06-18 16:01:16 -070086#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -070087 char c_multi_ch_dump[128] = {0};
88 status_t err = NO_ERROR;
89
90 // Call surround sound library init if device is Surround Sound
91 if ( handle->channels == 6) {
92 if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
93 || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
94
95 err = initSurroundSoundLibrary(handle->bufferSize);
96 if ( NO_ERROR != err) {
Iliyan Malchev4113f342012-06-11 14:39:47 -070097 ALOGE("initSurroundSoundLibrary failed: %d handle->bufferSize:%d", err,handle->bufferSize);
Iliyan Malchev4765c432012-06-11 14:36:16 -070098 }
99
100 property_get("ssr.pcmdump",c_multi_ch_dump,"0");
101 if (0 == strncmp("true",c_multi_ch_dump, sizeof("ssr.dump-pcm"))) {
102 //Remember to change file system permission of data(e.g. chmod 777 data/),
103 //otherwise, fopen may fail.
104 if ( !mFp_4ch)
105 mFp_4ch = fopen("/data/4ch_ssr.pcm", "wb");
106 if ( !mFp_6ch)
107 mFp_6ch = fopen("/data/6ch_ssr.pcm", "wb");
108 if ((!mFp_4ch) || (!mFp_6ch))
Iliyan Malchev4113f342012-06-11 14:39:47 -0700109 ALOGE("mfp_4ch or mfp_6ch open failed: mfp_4ch:%p mfp_6ch:%p",mFp_4ch,mFp_6ch);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700110 }
111 }
112 }
113#endif
114}
115
116AudioStreamInALSA::~AudioStreamInALSA()
117{
118 close();
119}
120
121status_t AudioStreamInALSA::setGain(float gain)
122{
123 return 0; //mixer() ? mixer()->setMasterGain(gain) : (status_t)NO_INIT;
124}
125
126ssize_t AudioStreamInALSA::read(void *buffer, ssize_t bytes)
127{
128 int period_size;
129
Iliyan Malchev4113f342012-06-11 14:39:47 -0700130 ALOGV("read:: buffer %p, bytes %d", buffer, bytes);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700131
132 int n;
133 status_t err;
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700134 ssize_t read = 0;
Iliyan Malchev4765c432012-06-11 14:36:16 -0700135 char *use_case;
136 int newMode = mParent->mode();
137
138 if((mHandle->handle == NULL) && (mHandle->rxHandle == NULL) &&
139 (strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) &&
140 (strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
141 mParent->mLock.lock();
142 snd_use_case_get(mHandle->ucMgr, "_verb", (const char **)&use_case);
143 if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
144 if ((mHandle->devices == AudioSystem::DEVICE_IN_VOICE_CALL) &&
145 (newMode == AudioSystem::MODE_IN_CALL)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700146 ALOGD("read:: mParent->mIncallMode=%d", mParent->mIncallMode);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700147 if ((mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_UPLINK) &&
148 (mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700149#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700150 if (mParent->mFusion3Platform) {
151 mParent->mALSADevice->setVocRecMode(INCALL_REC_STEREO);
152 strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
153 sizeof(mHandle->useCase));
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700154 start_csd_record(INCALL_REC_STEREO);
155 } else
Iliyan Malchev4765c432012-06-11 14:36:16 -0700156#endif
157 {
158 strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
159 sizeof(mHandle->useCase));
160 }
161 } else if (mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_DNLINK) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700162#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700163 if (mParent->mFusion3Platform) {
164 mParent->mALSADevice->setVocRecMode(INCALL_REC_MONO);
165 strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
166 sizeof(mHandle->useCase));
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700167 start_csd_record(INCALL_REC_MONO);
168 } else
Iliyan Malchev4765c432012-06-11 14:36:16 -0700169#endif
170 {
171 strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
172 sizeof(mHandle->useCase));
173 }
174 }
Ajay Dudani92919432012-06-28 14:23:11 -0700175#ifdef QCOM_FM_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700176 } else if(mHandle->devices == AudioSystem::DEVICE_IN_FM_RX) {
177 strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_FM, sizeof(mHandle->useCase));
178 } else if (mHandle->devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) {
179 strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM, sizeof(mHandle->useCase));
180#endif
181 } else if(!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP)) {
182 strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, sizeof(mHandle->useCase));
SathishKumar Mani88613382012-08-13 18:40:18 -0700183 } else {
184 char value[128];
185 property_get("persist.audio.lowlatency.rec",value,"0");
186 if (!strcmp("true", value)) {
187 strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC, sizeof(mHandle->useCase));
188 } else {
189 strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, sizeof(mHandle->useCase));
190 }
Iliyan Malchev4765c432012-06-11 14:36:16 -0700191 }
192 } else {
193 if ((mHandle->devices == AudioSystem::DEVICE_IN_VOICE_CALL) &&
194 (newMode == AudioSystem::MODE_IN_CALL)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700195 ALOGD("read:: ---- mParent->mIncallMode=%d", mParent->mIncallMode);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700196 if ((mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_UPLINK) &&
197 (mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700198#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700199 if (mParent->mFusion3Platform) {
200 mParent->mALSADevice->setVocRecMode(INCALL_REC_STEREO);
201 strlcpy(mHandle->useCase, SND_USE_CASE_VERB_INCALL_REC,
202 sizeof(mHandle->useCase));
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700203 start_csd_record(INCALL_REC_STEREO);
204 } else
Iliyan Malchev4765c432012-06-11 14:36:16 -0700205#endif
206 {
207 strlcpy(mHandle->useCase, SND_USE_CASE_VERB_UL_DL_REC,
208 sizeof(mHandle->useCase));
209 }
210 } else if (mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_DNLINK) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700211#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700212 if (mParent->mFusion3Platform) {
213 mParent->mALSADevice->setVocRecMode(INCALL_REC_MONO);
214 strlcpy(mHandle->useCase, SND_USE_CASE_VERB_INCALL_REC,
215 sizeof(mHandle->useCase));
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700216 start_csd_record(INCALL_REC_MONO);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700217 } else
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700218#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700219 {
220 strlcpy(mHandle->useCase, SND_USE_CASE_VERB_DL_REC,
221 sizeof(mHandle->useCase));
222 }
223 }
Ajay Dudani9746c472012-06-18 16:01:16 -0700224#ifdef QCOM_FM_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700225 } else if(mHandle->devices == AudioSystem::DEVICE_IN_FM_RX) {
226 strlcpy(mHandle->useCase, SND_USE_CASE_VERB_FM_REC, sizeof(mHandle->useCase));
227 } else if (mHandle->devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) {
228 strlcpy(mHandle->useCase, SND_USE_CASE_VERB_FM_A2DP_REC, sizeof(mHandle->useCase));
229#endif
230 } else if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)){
231 strlcpy(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, sizeof(mHandle->useCase));
232 } else {
SathishKumar Mani88613382012-08-13 18:40:18 -0700233 char value[128];
234 property_get("persist.audio.lowlatency.rec",value,"0");
235 if (!strcmp("true", value)) {
236 strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC, sizeof(mHandle->useCase));
237 } else {
238 strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI_REC, sizeof(mHandle->useCase));
239 }
Iliyan Malchev4765c432012-06-11 14:36:16 -0700240 }
241 }
242 free(use_case);
243 if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
244 (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700245#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700246 if((mDevices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) ||
247 (mDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)) {
248 mHandle->module->route(mHandle, (mDevices | AudioSystem::DEVICE_IN_PROXY) , AudioSystem::MODE_IN_COMMUNICATION);
249 }else
250#endif
251 {
252 mHandle->module->route(mHandle, mDevices , AudioSystem::MODE_IN_COMMUNICATION);
253 }
254 } else {
Ajay Dudani9746c472012-06-18 16:01:16 -0700255#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700256 if((mHandle->devices == AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET)||
257 (mHandle->devices == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)){
258 mHandle->module->route(mHandle, AudioSystem::DEVICE_IN_PROXY , mParent->mode());
259 } else
260#endif
261 {
262
263 mHandle->module->route(mHandle, mDevices , mParent->mode());
264 }
265 }
266 if (!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_REC) ||
SathishKumar Mani88613382012-08-13 18:40:18 -0700267 !strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC) ||
Iliyan Malchev4765c432012-06-11 14:36:16 -0700268 !strcmp(mHandle->useCase, SND_USE_CASE_VERB_FM_REC) ||
269 !strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL) ||
270 !strcmp(mHandle->useCase, SND_USE_CASE_VERB_FM_A2DP_REC) ||
271 !strcmp(mHandle->useCase, SND_USE_CASE_VERB_UL_DL_REC) ||
272 !strcmp(mHandle->useCase, SND_USE_CASE_VERB_DL_REC) ||
273 !strcmp(mHandle->useCase, SND_USE_CASE_VERB_INCALL_REC)) {
274 snd_use_case_set(mHandle->ucMgr, "_verb", mHandle->useCase);
275 } else {
276 snd_use_case_set(mHandle->ucMgr, "_enamod", mHandle->useCase);
277 }
278 if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
279 (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
280 err = mHandle->module->startVoipCall(mHandle);
281 }
282 else
283 mHandle->module->open(mHandle);
284 if(mHandle->handle == NULL) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700285 ALOGE("read:: PCM device open failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700286 mParent->mLock.unlock();
287
288 return 0;
289 }
Ajay Dudani9746c472012-06-18 16:01:16 -0700290#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700291 if((mHandle->devices == AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET)||
292 (mHandle->devices == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)){
293 if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
294 (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
295 mParent->musbRecordingState |= USBRECBIT_VOIPCALL;
296 } else {
297 mParent->startUsbRecordingIfNotStarted();
298 mParent->musbRecordingState |= USBRECBIT_REC;
299 }
300 }
301#endif
302 mParent->mLock.unlock();
303 }
Ajay Dudani9746c472012-06-18 16:01:16 -0700304#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700305 if(((mDevices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) ||
306 (mDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)) &&
307 (!mParent->musbRecordingState)) {
308 mParent->mLock.lock();
Iliyan Malchev4113f342012-06-11 14:39:47 -0700309 ALOGD("Starting UsbRecording thread");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700310 mParent->startUsbRecordingIfNotStarted();
311 if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL) ||
312 !strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP)) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700313 ALOGD("Enabling voip recording bit");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700314 mParent->musbRecordingState |= USBRECBIT_VOIPCALL;
315 }else{
Iliyan Malchev4113f342012-06-11 14:39:47 -0700316 ALOGD("Enabling HiFi Recording bit");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700317 mParent->musbRecordingState |= USBRECBIT_REC;
318 }
319 mParent->mLock.unlock();
320 }
321#endif
322 period_size = mHandle->periodSize;
323 int read_pending = bytes;
324
Ajay Dudani9746c472012-06-18 16:01:16 -0700325#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700326 if (mSurroundObj) {
327 int processed = 0;
328 int processed_pending;
329 int samples = bytes >> 1;
330 void *buffer_start = buffer;
331 int period_bytes = mHandle->handle->period_size;
332 int period_samples = period_bytes >> 1;
333
334 do {
335 if (mSurroundOutputBufferIdx > 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700336 ALOGV("AudioStreamInALSA::read() - copy processed output "
Iliyan Malchev4765c432012-06-11 14:36:16 -0700337 "to buffer, mSurroundOutputBufferIdx = %d",
338 mSurroundOutputBufferIdx);
339 // Copy processed output to buffer
340 processed_pending = mSurroundOutputBufferIdx;
341 if (processed_pending > (samples - processed)) {
342 processed_pending = (samples - processed);
343 }
344 memcpy(buffer, mSurroundOutputBuffer, processed_pending * sizeof(Word16));
345 buffer += processed_pending * sizeof(Word16);
346 processed += processed_pending;
347 if (mSurroundOutputBufferIdx > processed_pending) {
348 // Shift leftover samples to beginning of the buffer
349 memcpy(&mSurroundOutputBuffer[0],
350 &mSurroundOutputBuffer[processed_pending],
351 (mSurroundOutputBufferIdx - processed_pending) * sizeof(Word16));
352 }
353 mSurroundOutputBufferIdx -= processed_pending;
354 }
355
356 if (processed >= samples) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700357 ALOGV("AudioStreamInALSA::read() - done processing buffer, "
Iliyan Malchev4765c432012-06-11 14:36:16 -0700358 "processed = %d", processed);
359 // Done processing this buffer
360 break;
361 }
362
363 // Fill input buffer until there is enough to process
364 read_pending = SSR_INPUT_FRAME_SIZE - mSurroundInputBufferIdx;
365 read = mSurroundInputBufferIdx;
366 while (mHandle->handle && read_pending > 0) {
367 n = pcm_read(mHandle->handle, &mSurroundInputBuffer[read],
368 period_bytes);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700369 ALOGV("pcm_read() returned n = %d buffer:%p size:%d", n, &mSurroundInputBuffer[read], period_bytes);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700370 if (n && n != -EAGAIN) {
371 //Recovery part of pcm_read. TODO:split recovery.
372 return static_cast<ssize_t>(n);
373 }
374 else if (n < 0) {
375 // Recovery is part of pcm_write. TODO split is later.
376 return static_cast<ssize_t>(n);
377 }
378 else {
379 read_pending -= period_samples;
380 read += period_samples;
381 }
382 }
383
384
385 if (mFp_4ch) {
386 fwrite( mSurroundInputBuffer, 1,
387 SSR_INPUT_FRAME_SIZE * sizeof(Word16), mFp_4ch);
388 }
389
390 //apply ssr libs to conver 4ch to 6ch
391 surround_filters_intl_process(mSurroundObj,
392 &mSurroundOutputBuffer[mSurroundOutputBufferIdx],
393 (Word16 *)mSurroundInputBuffer);
394
395 // Shift leftover samples to beginning of input buffer
396 if (read_pending < 0) {
397 memcpy(&mSurroundInputBuffer[0],
398 &mSurroundInputBuffer[SSR_INPUT_FRAME_SIZE],
399 (-read_pending) * sizeof(Word16));
400 }
401 mSurroundInputBufferIdx = -read_pending;
402
403 if (mFp_6ch) {
404 fwrite( &mSurroundOutputBuffer[mSurroundOutputBufferIdx],
405 1, SSR_OUTPUT_FRAME_SIZE * sizeof(Word16), mFp_6ch);
406 }
407
408 mSurroundOutputBufferIdx += SSR_OUTPUT_FRAME_SIZE;
Iliyan Malchev4113f342012-06-11 14:39:47 -0700409 ALOGV("do_while loop: processed=%d, samples=%d\n", processed, samples);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700410 } while (mHandle->handle && processed < samples);
411 read = processed * sizeof(Word16);
412 buffer = buffer_start;
413 } else
Ajay Dudani9746c472012-06-18 16:01:16 -0700414#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700415 {
416
417 do {
418 if (read_pending < period_size) {
419 read_pending = period_size;
420 }
421
422 n = pcm_read(mHandle->handle, buffer,
423 period_size);
Iliyan Malchev4113f342012-06-11 14:39:47 -0700424 ALOGV("pcm_read() returned n = %d", n);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700425 if (n && (n == -EIO || n == -EAGAIN || n == -EPIPE || n == -EBADFD)) {
426 mParent->mLock.lock();
Iliyan Malchev4113f342012-06-11 14:39:47 -0700427 ALOGW("pcm_read() returned error n %d, Recovering from error\n", n);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700428 pcm_close(mHandle->handle);
429 mHandle->handle = NULL;
430 if((!strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, strlen(SND_USE_CASE_VERB_IP_VOICECALL))) ||
431 (!strncmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) {
432 pcm_close(mHandle->rxHandle);
433 mHandle->rxHandle = NULL;
434 mHandle->module->startVoipCall(mHandle);
435 }
436 else
437 mHandle->module->open(mHandle);
SathishKumar Mani89c224e2012-10-09 16:29:07 -0700438
439 if(mHandle->handle == NULL) {
440 ALOGE("read:: PCM device re-open failed");
441 mParent->mLock.unlock();
442 return 0;
443 }
444
Iliyan Malchev4765c432012-06-11 14:36:16 -0700445 mParent->mLock.unlock();
446 continue;
447 }
448 else if (n < 0) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700449 ALOGD("pcm_read() returned n < 0");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700450 return static_cast<ssize_t>(n);
451 }
452 else {
453 read += static_cast<ssize_t>((period_size));
454 read_pending -= period_size;
SathishKumar Mani6ccde102012-09-26 20:23:34 -0700455 //Set mute by cleanning buffers read
456 if (mParent->mMicMute) {
457 memset(buffer, 0, period_size);
458 }
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700459 buffer = ((uint8_t *)buffer) + period_size;
Iliyan Malchev4765c432012-06-11 14:36:16 -0700460 }
461
462 } while (mHandle->handle && read < bytes);
463 }
464
465 return read;
466}
467
468status_t AudioStreamInALSA::dump(int fd, const Vector<String16>& args)
469{
470 return NO_ERROR;
471}
472
473status_t AudioStreamInALSA::open(int mode)
474{
475 Mutex::Autolock autoLock(mParent->mLock);
476
477 status_t status = ALSAStreamOps::open(mode);
478
479 return status;
480}
481
482status_t AudioStreamInALSA::close()
483{
484 Mutex::Autolock autoLock(mParent->mLock);
485
Iliyan Malchev4113f342012-06-11 14:39:47 -0700486 ALOGD("close");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700487 if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
488 (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
489 if((mParent->mVoipStreamCount)) {
Ajay Dudani9746c472012-06-18 16:01:16 -0700490#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4113f342012-06-11 14:39:47 -0700491 ALOGD("musbRecordingState: %d, mVoipStreamCount:%d",mParent->musbRecordingState,
Iliyan Malchev4765c432012-06-11 14:36:16 -0700492 mParent->mVoipStreamCount );
493 if(mParent->mVoipStreamCount == 1) {
SathishKumar Mani0a019912012-09-11 12:33:11 -0700494 ALOGD("Deregistering VOIP Call bit, musbPlaybackState:%d,"
Iliyan Malchev4765c432012-06-11 14:36:16 -0700495 "musbRecordingState:%d", mParent->musbPlaybackState, mParent->musbRecordingState);
496 mParent->musbPlaybackState &= ~USBPLAYBACKBIT_VOIPCALL;
497 mParent->musbRecordingState &= ~USBRECBIT_VOIPCALL;
498 mParent->closeUsbRecordingIfNothingActive();
499 mParent->closeUsbPlaybackIfNothingActive();
500 }
Ajay Dudani9746c472012-06-18 16:01:16 -0700501#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700502 return NO_ERROR;
503 }
504 mParent->mVoipStreamCount = 0;
Ajay Dudani9746c472012-06-18 16:01:16 -0700505#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700506 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700507 ALOGD("Deregistering REC bit, musbRecordingState:%d", mParent->musbRecordingState);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700508 mParent->musbRecordingState &= ~USBRECBIT_REC;
Ajay Dudani9746c472012-06-18 16:01:16 -0700509#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700510 }
Ajay Dudani9746c472012-06-18 16:01:16 -0700511#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700512 if (mParent->mFusion3Platform) {
513 if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_INCALL_REC)) ||
514 (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE))) {
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700515 stop_csd_record();
Iliyan Malchev4765c432012-06-11 14:36:16 -0700516 }
517 }
518#endif
Iliyan Malchev4113f342012-06-11 14:39:47 -0700519 ALOGD("close");
Ajay Dudani9746c472012-06-18 16:01:16 -0700520#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700521 mParent->closeUsbRecordingIfNothingActive();
Ajay Dudani9746c472012-06-18 16:01:16 -0700522#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700523
524 ALSAStreamOps::close();
525
Ajay Dudani9746c472012-06-18 16:01:16 -0700526#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700527 if (mSurroundObj) {
528 surround_filters_release(mSurroundObj);
529 if (mSurroundObj)
530 free(mSurroundObj);
531 mSurroundObj = NULL;
532 if (mRealCoeffs){
533 for (int i =0; i<COEFF_ARRAY_SIZE; i++ ) {
534 if (mRealCoeffs[i]) {
535 free(mRealCoeffs[i]);
536 mRealCoeffs[i] = NULL;
537 }
538 }
539 free(mRealCoeffs);
540 mRealCoeffs = NULL;
541 }
542 if (mImagCoeffs){
543 for (int i =0; i<COEFF_ARRAY_SIZE; i++ ) {
544 if (mImagCoeffs[i]) {
545 free(mImagCoeffs[i]);
546 mImagCoeffs[i] = NULL;
547 }
548 }
549 free(mImagCoeffs);
550 mImagCoeffs = NULL;
551 }
552 if (mSurroundOutputBuffer){
553 free(mSurroundOutputBuffer);
554 mSurroundOutputBuffer = NULL;
555 }
556 if (mSurroundInputBuffer) {
557 free(mSurroundInputBuffer);
558 mSurroundInputBuffer = NULL;
559 }
560
561 if ( mFp_4ch ) fclose(mFp_4ch);
562 if ( mFp_6ch ) fclose(mFp_6ch);
563
564 }
565#endif
566
567 return NO_ERROR;
568}
569
570status_t AudioStreamInALSA::standby()
571{
572 Mutex::Autolock autoLock(mParent->mLock);
573
Iliyan Malchev4113f342012-06-11 14:39:47 -0700574 ALOGD("standby");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700575
576 if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
577 (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
578 return NO_ERROR;
579 }
580
Ajay Dudani9746c472012-06-18 16:01:16 -0700581#ifdef QCOM_CSDCLIENT_ENABLED
Iliyan Malchev4113f342012-06-11 14:39:47 -0700582 ALOGD("standby");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700583 if (mParent->mFusion3Platform) {
584 if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_INCALL_REC)) ||
585 (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE))) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700586 ALOGD(" into standby, stop record");
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700587 stop_csd_record();
Iliyan Malchev4765c432012-06-11 14:36:16 -0700588 }
589 }
590#endif
591 mHandle->module->standby(mHandle);
592
Ajay Dudani9746c472012-06-18 16:01:16 -0700593#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4113f342012-06-11 14:39:47 -0700594 ALOGD("Checking for musbRecordingState %d", mParent->musbRecordingState);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700595 mParent->musbRecordingState &= ~USBRECBIT_REC;
596 mParent->closeUsbRecordingIfNothingActive();
Ajay Dudani9746c472012-06-18 16:01:16 -0700597#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700598
599 return NO_ERROR;
600}
601
602void AudioStreamInALSA::resetFramesLost()
603{
604 mFramesLost = 0;
605}
606
607unsigned int AudioStreamInALSA::getInputFramesLost() const
608{
609 unsigned int count = mFramesLost;
610 // Stupid interface wants us to have a side effect of clearing the count
611 // but is defined as a const to prevent such a thing.
612 ((AudioStreamInALSA *)this)->resetFramesLost();
613 return count;
614}
615
616status_t AudioStreamInALSA::setAcousticParams(void *params)
617{
618 Mutex::Autolock autoLock(mParent->mLock);
619
620 return (status_t)NO_ERROR;
621}
622
Ajay Dudani9746c472012-06-18 16:01:16 -0700623#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700624status_t AudioStreamInALSA::initSurroundSoundLibrary(unsigned long buffersize)
625{
626 int subwoofer = 0; // subwoofer channel assignment: default as first microphone input channel
627 int low_freq = 4; // frequency upper bound for subwoofer: frequency=(low_freq-1)/FFT_SIZE*samplingRate, default as 4
628 int high_freq = 100; // frequency upper bound for spatial processing: frequency=(high_freq-1)/FFT_SIZE*samplingRate, default as 100
629 int ret = 0;
630
631 mSurroundInputBufferIdx = 0;
632 mSurroundOutputBufferIdx = 0;
633
634 if ( mSurroundObj ) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700635 ALOGE("ola filter library is already initialized");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700636 return ALREADY_EXISTS;
637 }
638
639 // Allocate memory for input buffer
640 mSurroundInputBuffer = (Word16 *) calloc(2 * SSR_INPUT_FRAME_SIZE,
641 sizeof(Word16));
642 if ( !mSurroundInputBuffer ) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700643 ALOGE("Memory allocation failure. Not able to allocate memory for surroundInputBuffer");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700644 goto init_fail;
645 }
646
647 // Allocate memory for output buffer
648 mSurroundOutputBuffer = (Word16 *) calloc(2 * SSR_OUTPUT_FRAME_SIZE,
649 sizeof(Word16));
650 if ( !mSurroundOutputBuffer ) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700651 ALOGE("Memory allocation failure. Not able to allocate memory for surroundOutputBuffer");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700652 goto init_fail;
653 }
654
655 // Allocate memory for real and imag coeffs array
656 mRealCoeffs = (Word16 **) calloc(COEFF_ARRAY_SIZE, sizeof(Word16 *));
657 if ( !mRealCoeffs ) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700658 ALOGE("Memory allocation failure during real Coefficient array");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700659 goto init_fail;
660 }
661
662 mImagCoeffs = (Word16 **) calloc(COEFF_ARRAY_SIZE, sizeof(Word16 *));
663 if ( !mImagCoeffs ) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700664 ALOGE("Memory allocation failure during imaginary Coefficient array");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700665 goto init_fail;
666 }
667
668 if( readCoeffsFromFile() != NO_ERROR) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700669 ALOGE("Error while loading coeffs from file");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700670 goto init_fail;
671 }
672
673 //calculate the size of data to allocate for mSurroundObj
674 ret = surround_filters_init(NULL,
675 6, // Num output channel
676 4, // Num input channel
677 mRealCoeffs, // Coeffs hardcoded in header
678 mImagCoeffs, // Coeffs hardcoded in header
679 subwoofer,
680 low_freq,
681 high_freq,
682 NULL);
683
684 if ( ret > 0 ) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700685 ALOGV("Allocating surroundObj size is %d", ret);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700686 mSurroundObj = (void *)malloc(ret);
687 memset(mSurroundObj,0,ret);
688 if (NULL != mSurroundObj) {
689 //initialize after allocating the memory for mSurroundObj
690 ret = surround_filters_init(mSurroundObj,
691 6,
692 4,
693 mRealCoeffs,
694 mImagCoeffs,
695 subwoofer,
696 low_freq,
697 high_freq,
698 NULL);
699 if (0 != ret) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700700 ALOGE("surround_filters_init failed with ret:%d",ret);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700701 surround_filters_release(mSurroundObj);
702 goto init_fail;
703 }
704 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700705 ALOGE("Allocationg mSurroundObj failed");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700706 goto init_fail;
707 }
708 } else {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700709 ALOGE("surround_filters_init(mSurroundObj=Null) failed with ret: %d",ret);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700710 goto init_fail;
711 }
712
713 (void) surround_filters_set_channel_map(mSurroundObj, chanMap);
714
715 return NO_ERROR;
716
717init_fail:
718 if (mSurroundObj) {
719 free(mSurroundObj);
720 mSurroundObj = NULL;
721 }
722 if (mSurroundOutputBuffer) {
723 free(mSurroundOutputBuffer);
724 mSurroundOutputBuffer = NULL;
725 }
726 if (mSurroundInputBuffer) {
727 free(mSurroundInputBuffer);
728 mSurroundInputBuffer = NULL;
729 }
730 if (mRealCoeffs){
731 for (int i =0; i<COEFF_ARRAY_SIZE; i++ ) {
732 if (mRealCoeffs[i]) {
733 free(mRealCoeffs[i]);
734 mRealCoeffs[i] = NULL;
735 }
736 }
737 free(mRealCoeffs);
738 mRealCoeffs = NULL;
739 }
740 if (mImagCoeffs){
741 for (int i =0; i<COEFF_ARRAY_SIZE; i++ ) {
742 if (mImagCoeffs[i]) {
743 free(mImagCoeffs[i]);
744 mImagCoeffs[i] = NULL;
745 }
746 }
747 free(mImagCoeffs);
748 mImagCoeffs = NULL;
749 }
750
751 return NO_MEMORY;
752
753}
754
755
756// Helper function to read coeffs from File and updates real and imaginary
757// coeff array member variable
758status_t AudioStreamInALSA::readCoeffsFromFile()
759{
760 FILE *flt1r;
761 FILE *flt2r;
762 FILE *flt3r;
763 FILE *flt4r;
764 FILE *flt1i;
765 FILE *flt2i;
766 FILE *flt3i;
767 FILE *flt4i;
768
769 if ( (flt1r = fopen(SURROUND_FILE_1R, "rb")) == NULL ) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700770 ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_1R);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700771 return NAME_NOT_FOUND;
772 }
773
774 if ( (flt2r = fopen(SURROUND_FILE_2R, "rb")) == NULL ) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700775 ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_2R);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700776 return NAME_NOT_FOUND;
777 }
778
779 if ( (flt3r = fopen(SURROUND_FILE_3R, "rb")) == NULL ) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700780 ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_3R);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700781 return NAME_NOT_FOUND;
782 }
783
784 if ( (flt4r = fopen(SURROUND_FILE_4R, "rb")) == NULL ) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700785 ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_4R);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700786 return NAME_NOT_FOUND;
787 }
788
789 if ( (flt1i = fopen(SURROUND_FILE_1I, "rb")) == NULL ) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700790 ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_1I);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700791 return NAME_NOT_FOUND;
792 }
793
794 if ( (flt2i = fopen(SURROUND_FILE_2I, "rb")) == NULL ) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700795 ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_2I);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700796 return NAME_NOT_FOUND;
797 }
798
799 if ( (flt3i = fopen(SURROUND_FILE_3I, "rb")) == NULL ) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700800 ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_3I);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700801 return NAME_NOT_FOUND;
802 }
803
804 if ( (flt4i = fopen(SURROUND_FILE_4I, "rb")) == NULL ) {
Iliyan Malchev4113f342012-06-11 14:39:47 -0700805 ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_4I);
Iliyan Malchev4765c432012-06-11 14:36:16 -0700806 return NAME_NOT_FOUND;
807 }
Iliyan Malchev4113f342012-06-11 14:39:47 -0700808 ALOGV("readCoeffsFromFile all filter files opened");
Iliyan Malchev4765c432012-06-11 14:36:16 -0700809
810 for (int i=0; i<COEFF_ARRAY_SIZE; i++) {
811 mRealCoeffs[i] = (Word16 *)calloc(FILT_SIZE, sizeof(Word16));
812 }
813 for (int i=0; i<COEFF_ARRAY_SIZE; i++) {
814 mImagCoeffs[i] = (Word16 *)calloc(FILT_SIZE, sizeof(Word16));
815 }
816
817 // Read real co-efficients
818 if (NULL != mRealCoeffs[0]) {
819 fread(mRealCoeffs[0], sizeof(int16), FILT_SIZE, flt1r);
820 }
821 if (NULL != mRealCoeffs[0]) {
822 fread(mRealCoeffs[1], sizeof(int16), FILT_SIZE, flt2r);
823 }
824 if (NULL != mRealCoeffs[0]) {
825 fread(mRealCoeffs[2], sizeof(int16), FILT_SIZE, flt3r);
826 }
827 if (NULL != mRealCoeffs[0]) {
828 fread(mRealCoeffs[3], sizeof(int16), FILT_SIZE, flt4r);
829 }
830
831 // read imaginary co-efficients
832 if (NULL != mImagCoeffs[0]) {
833 fread(mImagCoeffs[0], sizeof(int16), FILT_SIZE, flt1i);
834 }
835 if (NULL != mImagCoeffs[0]) {
836 fread(mImagCoeffs[1], sizeof(int16), FILT_SIZE, flt2i);
837 }
838 if (NULL != mImagCoeffs[0]) {
839 fread(mImagCoeffs[2], sizeof(int16), FILT_SIZE, flt3i);
840 }
841 if (NULL != mImagCoeffs[0]) {
842 fread(mImagCoeffs[3], sizeof(int16), FILT_SIZE, flt4i);
843 }
844
845 fclose(flt1r);
846 fclose(flt2r);
847 fclose(flt3r);
848 fclose(flt4r);
849 fclose(flt1i);
850 fclose(flt2i);
851 fclose(flt3i);
852 fclose(flt4i);
853
854 return NO_ERROR;
855}
856#endif
857
SathishKumar Mani5ff7a022012-09-14 11:36:35 -0700858#ifdef QCOM_CSDCLIENT_ENABLED
859int AudioStreamInALSA::start_csd_record(int param)
860{
861 int err = NO_ERROR;
862
863 if (mParent->mCsdHandle != NULL) {
864 csd_start_record = (int (*)(int))::dlsym(mParent->mCsdHandle,"csd_client_start_record");
865 if (csd_start_record == NULL) {
866 ALOGE("dlsym:Error:%s Loading csd_client_start_record", dlerror());
867 } else {
868 err = csd_start_record(param);
869 }
870 }
871 return err;
872}
873
874int AudioStreamInALSA::stop_csd_record()
875{
876 int err = NO_ERROR;
877 if (mParent->mCsdHandle != NULL) {
878 csd_stop_record = (int (*)())::dlsym(mParent->mCsdHandle,"csd_client_stop_record");
879 if (csd_start_record == NULL) {
880 ALOGE("dlsym:Error:%s Loading csd_client_start_record", dlerror());
881 } else {
882 csd_stop_record();
883 }
884 }
885 return err;
886}
887#endif
888
Iliyan Malchev4765c432012-06-11 14:36:16 -0700889} // namespace android_audio_legacy