1 /* AudioUsbALSA.cpp
2 Copyright (c) 2012, Code Aurora Forum. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10 copyright notice, this list of conditions and the following
11 disclaimer in the documentation and/or other materials provided
12 with the distribution.
13 * Neither the name of Code Aurora Forum, Inc. nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
28
29 #define LOG_TAG "AudioUsbALSA"
30 #define LOG_NDEBUG 0
31 #define LOG_NDDEBUG 0
32 #include <utils/Log.h>
33 #include <utils/String8.h>
34
35 #include <cutils/properties.h>
36 #include <media/AudioRecord.h>
37 #include <hardware_legacy/power.h>
38 #include <sys/poll.h>
39 #include <sys/ioctl.h>
40 #include <fcntl.h>
41 #include <string.h>
42 #include <sys/stat.h>
43 #include <errno.h>
44 #include <jni.h>
45 #include <stdio.h>
46 #include <sys/eventfd.h>
47
48
49 #include "AudioUsbALSA.h"
50 struct pollfd pfdProxyPlayback[2];
51 struct pollfd pfdUsbPlayback[2];
52 struct pollfd pfdProxyRecording[1];
53 struct pollfd pfdUsbRecording[1];
54
55 #define USB_PERIOD_SIZE 2048
56 #define PROXY_PERIOD_SIZE 3072
57
58 namespace android_audio_legacy
59 {
AudioUsbALSA()60 AudioUsbALSA::AudioUsbALSA()
61 {
62 mproxypfdPlayback = -1;
63 musbpfdPlayback = -1;
64 mkillPlayBackThread = false;
65 mkillRecordingThread = false;
66 }
67
~AudioUsbALSA()68 AudioUsbALSA::~AudioUsbALSA()
69 {
70 mkillPlayBackThread = true;
71 mkillRecordingThread = true;
72 }
73
74
getnumOfRates(char * ratesStr)75 int AudioUsbALSA::getnumOfRates(char *ratesStr){
76 int i, size = 0;
77 char *nextSRString, *temp_ptr;
78 nextSRString = strtok_r(ratesStr, " ,", &temp_ptr);
79 if (nextSRString == NULL) {
80 ALOGE("ERROR: getnumOfRates: could not find rates string");
81 return NULL;
82 }
83 for (i = 1; nextSRString != NULL; i++) {
84 size ++;
85 nextSRString = strtok_r(NULL, " ,.-", &temp_ptr);
86 }
87 return size;
88 }
89
90
getCap(char * type,int & channels,int & sampleRate)91 status_t AudioUsbALSA::getCap(char * type, int &channels, int &sampleRate)
92 {
93 ALOGD("getCap for %s",type);
94 long unsigned fileSize;
95 FILE *fp;
96 char *buffer;
97 int err = 1;
98 int size = 0;
99 int fd, i, lchannelsPlayback;
100 char *read_buf, *str_start, *channel_start, *ratesStr, *ratesStrForVal,
101 *ratesStrStart, *chString, *nextSRStr, *test, *nextSRString, *temp_ptr;
102 struct stat st;
103 memset(&st, 0x0, sizeof(struct stat));
104 sampleRate = 0;
105 fd = open(PATH, O_RDONLY);
106 if (fd <0) {
107 ALOGE("ERROR: failed to open config file %s error: %d\n", PATH, errno);
108 close(fd);
109 return UNKNOWN_ERROR;
110 }
111
112 if (fstat(fd, &st) < 0) {
113 ALOGE("ERROR: failed to stat %s error %d\n", PATH, errno);
114 close(fd);
115 return UNKNOWN_ERROR;
116 }
117
118 fileSize = st.st_size;
119
120 read_buf = (char *)malloc(BUFFSIZE);
121 memset(read_buf, 0x0, BUFFSIZE);
122 err = read(fd, read_buf, BUFFSIZE);
123 str_start = strstr(read_buf, type);
124 if (str_start == NULL) {
125 ALOGE("ERROR:%s section not found in usb config file", type);
126 close(fd);
127 free(read_buf);
128 return UNKNOWN_ERROR;
129 }
130
131 channel_start = strstr(str_start, "Channels:");
132 if (channel_start == NULL) {
133 ALOGE("ERROR: Could not find Channels information");
134 close(fd);
135 free(read_buf);
136 return UNKNOWN_ERROR;
137 }
138 channel_start = strstr(channel_start, " ");
139 if (channel_start == NULL) {
140 ALOGE("ERROR: Channel section not found in usb config file");
141 close(fd);
142 free(read_buf);
143 return UNKNOWN_ERROR;
144 }
145
146 lchannelsPlayback = atoi(channel_start);
147 if (lchannelsPlayback == 1) {
148 channels = 1;
149 } else {
150 channels = 2;
151 }
152 ALOGD("channels supported by device: %d", lchannelsPlayback);
153 ratesStrStart = strstr(str_start, "Rates:");
154 if (ratesStrStart == NULL) {
155 ALOGE("ERROR: Cant find rates information");
156 close(fd);
157 free(read_buf);
158 return UNKNOWN_ERROR;
159 }
160
161 ratesStrStart = strstr(ratesStrStart, " ");
162 if (ratesStrStart == NULL) {
163 ALOGE("ERROR: Channel section not found in usb config file");
164 close(fd);
165 free(read_buf);
166 return UNKNOWN_ERROR;
167 }
168
169 //copy to ratesStr, current line.
170 char *target = strchr(ratesStrStart, '\n');
171 if (target == NULL) {
172 ALOGE("ERROR: end of line not found");
173 close(fd);
174 free(read_buf);
175 return UNKNOWN_ERROR;
176 }
177 size = target - ratesStrStart;
178 ratesStr = (char *)malloc(size + 1) ;
179 ratesStrForVal = (char *)malloc(size + 1) ;
180 memcpy(ratesStr, ratesStrStart, size);
181 memcpy(ratesStrForVal, ratesStrStart, size);
182 ratesStr[size] = '\0';
183 ratesStrForVal[size] = '\0';
184
185 size = getnumOfRates(ratesStr);
186 if (!size) {
187 ALOGE("ERROR: Could not get rate size, returning");
188 close(fd);
189 free(ratesStrForVal);
190 free(ratesStr);
191 free(read_buf);
192 return UNKNOWN_ERROR;
193 }
194
195 //populate playback rates array
196 int ratesSupported[size];
197 nextSRString = strtok_r(ratesStrForVal, " ,", &temp_ptr);
198 if (nextSRString == NULL) {
199 ALOGE("ERROR: Could not get first rate val");
200 close(fd);
201 free(ratesStrForVal);
202 free(ratesStr);
203 free(read_buf);
204 return UNKNOWN_ERROR;
205 }
206
207 ratesSupported[0] = atoi(nextSRString);
208 for (i = 1; i<size; i++) {
209 nextSRString = strtok_r(NULL, " ,.-", &temp_ptr);
210 ratesSupported[i] = atoi(nextSRString);
211 ALOGV("ratesSupported[%d] for playback: %d",i, ratesSupported[i]);
212 }
213
214 for (i = 0; i<=size; i++) {
215 if (ratesSupported[i] <= 48000) {
216 sampleRate = ratesSupported[i];
217 break;
218 }
219 }
220 ALOGD("sampleRate: %d", sampleRate);
221
222 close(fd);
223 free(ratesStrForVal);
224 free(ratesStr);
225 free(read_buf);
226 ratesStrForVal = NULL;
227 ratesStr = NULL;
228 read_buf = NULL;
229 return NO_ERROR;
230 }
231
exitPlaybackThread(uint64_t writeVal)232 void AudioUsbALSA::exitPlaybackThread(uint64_t writeVal)
233 {
234 ALOGD("exitPlaybackThread, mproxypfdPlayback: %d", mproxypfdPlayback);
235 if (writeVal == SIGNAL_EVENT_KILLTHREAD) {
236 int err;
237
238 err = closeDevice(mproxyPlaybackHandle);
239 if (err) {
240 ALOGE("Info: Could not close proxy %p", mproxyPlaybackHandle);
241 }
242 err = closeDevice(musbPlaybackHandle);
243 if (err) {
244 ALOGE("Info: Could not close USB device %p", musbPlaybackHandle);
245 }
246 }
247 if ((mproxypfdPlayback != -1) && (musbpfdPlayback != -1)) {
248 write(mproxypfdPlayback, &writeVal, sizeof(uint64_t));
249 write(musbpfdPlayback, &writeVal, sizeof(uint64_t));
250 mkillPlayBackThread = true;
251 pthread_join(mPlaybackUsb,NULL);
252 }
253 }
254
exitRecordingThread(uint64_t writeVal)255 void AudioUsbALSA::exitRecordingThread(uint64_t writeVal)
256 {
257 ALOGD("exitRecordingThread");
258 if (writeVal == SIGNAL_EVENT_KILLTHREAD) {
259 int err;
260
261 err = closeDevice(mproxyRecordingHandle);
262 if (err) {
263 ALOGE("Info: Could not close proxy for recording %p", mproxyRecordingHandle);
264 }
265 err = closeDevice(musbRecordingHandle);
266 if (err) {
267 ALOGE("Info: Could not close USB recording device %p", musbRecordingHandle);
268 }
269 }
270 mkillRecordingThread = true;
271 }
272
setkillUsbRecordingThread(bool val)273 void AudioUsbALSA::setkillUsbRecordingThread(bool val){
274 ALOGD("setkillUsbRecordingThread");
275 mkillRecordingThread = val;
276 }
277
setHardwareParams(pcm * txHandle,uint32_t sampleRate,uint32_t channels,int periodBytes)278 status_t AudioUsbALSA::setHardwareParams(pcm *txHandle, uint32_t sampleRate, uint32_t channels, int periodBytes)
279 {
280 ALOGD("setHardwareParams");
281 struct snd_pcm_hw_params *params;
282 unsigned long bufferSize, reqBuffSize;
283 unsigned int periodTime, bufferTime;
284 unsigned int requestedRate = sampleRate;
285 int status = 0;
286
287 params = (snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params));
288 if (!params) {
289 return NO_INIT;
290 }
291
292 param_init(params);
293 param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
294 SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
295 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
296 SNDRV_PCM_FORMAT_S16_LE);
297 param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
298 SNDRV_PCM_SUBFORMAT_STD);
299 ALOGV("Setting period size:%d samplerate:%d, channels: %d",periodBytes,sampleRate, channels);
300 param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, periodBytes);
301 param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16);
302 param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
303 channels - 1 ? 32 : 16);
304 param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS,
305 channels);
306 param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, sampleRate);
307 param_set_hw_refine(txHandle, params);
308
309 if (param_set_hw_params(txHandle, params)) {
310 ALOGE("ERROR: cannot set hw params");
311 return NO_INIT;
312 }
313
314 param_dump(params);
315
316 txHandle->period_size = pcm_period_size(params);
317 txHandle->buffer_size = pcm_buffer_size(params);
318 txHandle->period_cnt = txHandle->buffer_size/txHandle->period_size;
319
320 ALOGD("setHardwareParams: buffer_size %d, period_size %d, period_cnt %d",
321 txHandle->buffer_size, txHandle->period_size,
322 txHandle->period_cnt);
323
324 return NO_ERROR;
325 }
326
setSoftwareParams(pcm * pcm,bool playback)327 status_t AudioUsbALSA::setSoftwareParams(pcm *pcm, bool playback)
328 {
329 ALOGD("setSoftwareParams");
330 struct snd_pcm_sw_params* params;
331
332 params = (snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params));
333 if (!params) {
334 LOG_ALWAYS_FATAL("Failed to allocate ALSA software parameters!");
335 return NO_INIT;
336 }
337
338 params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
339 params->period_step = 1;
340
341 params->avail_min = (pcm->flags & PCM_MONO) ? pcm->period_size/2 : pcm->period_size/4;
342
343 if (playback) {
344 params->start_threshold = (pcm->flags & PCM_MONO) ? pcm->period_size*8 : pcm->period_size*4;
345 params->xfer_align = (pcm->flags & PCM_MONO) ? pcm->period_size*8 : pcm->period_size*4;
346 } else {
347 params->start_threshold = (pcm->flags & PCM_MONO) ? pcm->period_size/2 : pcm->period_size/4;
348 params->xfer_align = (pcm->flags & PCM_MONO) ? pcm->period_size/2 : pcm->period_size/4;
349 }
350 params->stop_threshold = pcm->buffer_size;
351
352 params->xfer_align = (pcm->flags & PCM_MONO) ? pcm->period_size/2 : pcm->period_size/4;
353 params->silence_size = 0;
354 params->silence_threshold = 0;
355
356 if (param_set_sw_params(pcm, params)) {
357 ALOGE("ERROR: cannot set sw params");
358 return NO_INIT;
359 }
360
361 return NO_ERROR;
362 }
363
closeDevice(pcm * handle)364 status_t AudioUsbALSA::closeDevice(pcm *handle)
365 {
366 ALOGD("closeDevice handle %p", handle);
367 status_t err = NO_ERROR;
368 if (handle) {
369 err = pcm_close(handle);
370 if (err != NO_ERROR) {
371 ALOGE("INFO: closeDevice: pcm_close failed with err %d", err);
372 }
373 }
374 handle = NULL;
375 return err;
376 }
377
RecordingThreadEntry()378 void AudioUsbALSA::RecordingThreadEntry() {
379 ALOGD("Inside RecordingThreadEntry");
380 int nfds = 1;
381 mtimeOutRecording = TIMEOUT_INFINITE;
382 int fd;
383 long frames;
384 static int start = 0;
385 struct snd_xferi x;
386 int filed;
387 unsigned avail, bufsize;
388 int bytes_written;
389 uint32_t sampleRate;
390 uint32_t channels;
391 u_int8_t *srcUsb_addr = NULL;
392 u_int8_t *dstProxy_addr = NULL;
393 int err;
394 const char *fn = "/data/RecordPcm.pcm";
395 filed = open(fn, O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, 0664);
396
397 err = getCap((char *)"Capture:", mchannelsCapture, msampleRateCapture);
398 if (err) {
399 ALOGE("ERROR: Could not get capture capabilities from usb device");
400 return;
401 }
402 int channelFlag = PCM_MONO;
403 if (mchannelsCapture >= 2) {
404 channelFlag = PCM_STEREO;
405 }
406
407 musbRecordingHandle = configureDevice(PCM_IN|channelFlag|PCM_MMAP, (char *)"hw:1,0",
408 msampleRateCapture, mchannelsCapture,768,false);
409 if (!musbRecordingHandle) {
410 ALOGE("ERROR: Could not configure USB device for recording");
411 return;
412 } else {
413 ALOGD("USB device Configured for recording");
414 }
415
416 pfdUsbRecording[0].fd = musbRecordingHandle->fd; //DEBUG
417 pfdUsbRecording[0].events = POLLIN;
418
419 mproxyRecordingHandle = configureDevice(PCM_OUT|channelFlag|PCM_MMAP, (char *)"hw:0,7",
420 msampleRateCapture, mchannelsCapture,768,false);
421 if (!mproxyRecordingHandle) {
422 ALOGE("ERROR: Could not configure Proxy for recording");
423 closeDevice(musbRecordingHandle);
424 return;
425 } else {
426 ALOGD("Proxy Configured for recording");
427 }
428
429 bufsize = musbRecordingHandle->period_size;
430 pfdProxyRecording[0].fd = mproxyRecordingHandle->fd;
431 pfdProxyRecording[0].events = POLLOUT;
432 frames = (musbRecordingHandle->flags & PCM_MONO) ? (bufsize / 2) : (bufsize / 4);
433 x.frames = (musbRecordingHandle->flags & PCM_MONO) ? (bufsize / 2) : (bufsize / 4);
434
435 /***********************keep reading from usb and writing to proxy******************************************/
436 while (mkillRecordingThread != true) {
437 if (!musbRecordingHandle->running) {
438 if (pcm_prepare(musbRecordingHandle)) {
439 ALOGE("ERROR: pcm_prepare failed for usb device for recording");
440 mkillRecordingThread = true;
441 break;;
442 }
443 }
444 if (!mproxyRecordingHandle->running) {
445 if (pcm_prepare(mproxyRecordingHandle)) {
446 ALOGE("ERROR: pcm_prepare failed for proxy device for recording");
447 mkillRecordingThread = true;
448 break;;
449 }
450 }
451
452 /********** USB syncing before write **************/
453 if (!musbRecordingHandle->start && !mkillRecordingThread) {
454 err = startDevice(musbRecordingHandle, &mkillRecordingThread);
455 if (err == EPIPE) {
456 continue;
457 } else if (err != NO_ERROR) {
458 mkillRecordingThread = true;
459 break;
460 }
461 }
462 for (;;) {
463 if (!musbRecordingHandle->running) {
464 if (pcm_prepare(musbRecordingHandle)) {
465 ALOGE("ERROR: pcm_prepare failed for proxy device for recording");
466 mkillRecordingThread = true;
467 break;
468 }
469 }
470 /* Sync the current Application pointer from the kernel */
471 musbRecordingHandle->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL |
472 SNDRV_PCM_SYNC_PTR_AVAIL_MIN;
473
474 err = syncPtr(musbRecordingHandle, &mkillRecordingThread);
475 if (err == EPIPE) {
476 continue;
477 } else if (err != NO_ERROR) {
478 break;
479 }
480
481 avail = pcm_avail(musbRecordingHandle);
482 if (avail < musbRecordingHandle->sw_p->avail_min) {
483 poll(pfdUsbRecording, nfds, TIMEOUT_INFINITE);
484 continue;
485 } else {
486 break;
487 }
488 }
489 if (mkillRecordingThread) {
490 break;
491 }
492 if (x.frames > avail)
493 frames = avail;
494
495 srcUsb_addr = dst_address(musbRecordingHandle);
496 /**********End USB syncing before write**************/
497
498 /*************Proxy syncing before write ******************/
499
500 for (;;) {
501 if (!mproxyRecordingHandle->running) {
502 if (pcm_prepare(mproxyRecordingHandle)) {
503 ALOGE("ERROR: pcm_prepare failed for proxy device for recording");
504 mkillRecordingThread = true;
505 break;
506 }
507 }
508 mproxyRecordingHandle->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL |
509 SNDRV_PCM_SYNC_PTR_AVAIL_MIN;
510
511 err = syncPtr(mproxyRecordingHandle, &mkillRecordingThread);
512 if (err == EPIPE) {
513 continue;
514 } else if (err != NO_ERROR) {
515 break;
516 }
517 avail = pcm_avail(mproxyRecordingHandle);
518 if (avail < mproxyRecordingHandle->sw_p->avail_min) {
519 poll(pfdProxyRecording, nfds, TIMEOUT_INFINITE);
520 continue;
521 } else {
522 break;
523 }
524 }
525 if (mkillRecordingThread) {
526 break;
527 }
528
529 dstProxy_addr = dst_address(mproxyRecordingHandle);
530 memset(dstProxy_addr, 0x0, bufsize);
531
532 /**************End Proxy syncing before write *************/
533
534 memcpy(dstProxy_addr, srcUsb_addr, bufsize );
535
536 /************* sync up after write -- USB *********************/
537 musbRecordingHandle->sync_ptr->c.control.appl_ptr += frames;
538 musbRecordingHandle->sync_ptr->flags = 0;
539 err = syncPtr(musbRecordingHandle, &mkillRecordingThread);
540 if (err == EPIPE) {
541 continue;
542 } else if (err != NO_ERROR) {
543 break;
544 }
545
546 /************* end sync up after write -- USB *********************/
547
548 /**************** sync up after write -- Proxy ************************/
549 mproxyRecordingHandle->sync_ptr->c.control.appl_ptr += frames;
550 mproxyRecordingHandle->sync_ptr->flags = 0;
551
552 err = syncPtr(mproxyRecordingHandle, &mkillRecordingThread);
553 if (err == EPIPE) {
554 continue;
555 } else if (err != NO_ERROR) {
556 break;
557 }
558
559 bytes_written = mproxyRecordingHandle->sync_ptr->c.control.appl_ptr - mproxyRecordingHandle->sync_ptr->s.status.hw_ptr;
560 if ((bytes_written >= mproxyRecordingHandle->sw_p->start_threshold) && (!mproxyRecordingHandle->start)) {
561 if (!mkillPlayBackThread) {
562 err = startDevice(mproxyRecordingHandle, &mkillRecordingThread);
563 if (err == EPIPE) {
564 continue;
565 } else if (err != NO_ERROR) {
566 mkillRecordingThread = true;
567 break;
568 }
569 }
570 }
571 }
572 /*************** End sync up after write -- Proxy *********************/
573 if (mkillRecordingThread) {
574 closeDevice(mproxyRecordingHandle);
575 closeDevice(musbRecordingHandle);
576 }
577 ALOGD("Exiting USB Recording thread");
578 }
579
PlaybackThreadWrapper(void * me)580 void *AudioUsbALSA::PlaybackThreadWrapper(void *me) {
581 static_cast<AudioUsbALSA *>(me)->PlaybackThreadEntry();
582 return NULL;
583 }
584
RecordingThreadWrapper(void * me)585 void *AudioUsbALSA::RecordingThreadWrapper(void *me) {
586 static_cast<AudioUsbALSA *>(me)->RecordingThreadEntry();
587 return NULL;
588 }
589
configureDevice(unsigned flags,char * hw,int sampleRate,int channelCount,int periodSize,bool playback)590 struct pcm * AudioUsbALSA::configureDevice(unsigned flags, char* hw, int sampleRate, int channelCount, int periodSize, bool playback){
591 int err = NO_ERROR;
592 struct pcm * handle = NULL;
593 handle = pcm_open(flags, hw);
594 if (!handle || handle->fd < 0) {
595 ALOGE("ERROR: pcm_open failed");
596 return NULL;
597 }
598
599 if (!pcm_ready(handle)) {
600 ALOGE("ERROR: pcm_ready failed");
601 closeDevice(handle);
602 return NULL;
603 }
604
605 ALOGD("Setting hardware params: sampleRate:%d, channels: %d",sampleRate, channelCount);
606 err = setHardwareParams(handle, sampleRate, channelCount,periodSize);
607 if (err != NO_ERROR) {
608 ALOGE("ERROR: setHardwareParams failed");
609 closeDevice(handle);
610 return NULL;
611 }
612
613 err = setSoftwareParams(handle, playback);
614 if (err != NO_ERROR) {
615 ALOGE("ERROR: setSoftwareParams failed");
616 closeDevice(handle);
617 return NULL;
618 }
619
620 err = mmap_buffer(handle);
621 if (err) {
622 ALOGE("ERROR: mmap_buffer failed");
623 closeDevice(handle);
624 return NULL;
625 }
626
627 err = pcm_prepare(handle);
628 if (err) {
629 ALOGE("ERROR: pcm_prepare failed");
630 closeDevice(handle);
631 return NULL;
632 }
633
634 return handle;
635 }
636
startDevice(pcm * handle,bool * killThread)637 status_t AudioUsbALSA::startDevice(pcm *handle, bool *killThread) {
638 int err = NO_ERROR;;
639 if (ioctl(handle->fd, SNDRV_PCM_IOCTL_START)) {
640 err = -errno;
641 if (errno == EPIPE) {
642 ALOGE("ERROR: SNDRV_PCM_IOCTL_START returned EPIPE for usb recording case");
643 handle->underruns++;
644 handle->running = 0;
645 handle->start = 0;
646 return errno;
647 } else {
648 ALOGE("ERROR: SNDRV_PCM_IOCTL_START failed for usb recording case errno:%d", errno);
649 *killThread = true;
650 return errno;
651 }
652 }
653 handle->start = 1;
654 if (handle == musbRecordingHandle) {
655 ALOGD("Usb Driver started for recording");
656 } else if (handle == mproxyRecordingHandle) {
657 ALOGD("Proxy Driver started for recording");
658 } else if (handle == musbPlaybackHandle) {
659 ALOGD("Usb Driver started for playback");
660 } else if (handle == mproxyPlaybackHandle) {
661 ALOGD("proxy Driver started for playback");
662 }
663 return NO_ERROR;
664 }
665
syncPtr(struct pcm * handle,bool * killThread)666 status_t AudioUsbALSA::syncPtr(struct pcm *handle, bool *killThread) {
667 int err;
668 err = sync_ptr(handle);
669 if (err == EPIPE) {
670 ALOGE("ERROR: Failed in sync_ptr \n");
671 handle->running = 0;
672 handle->underruns++;
673 handle->start = 0;
674 } else if (err == ENODEV) {
675 ALOGE("Info: Device not available");
676 } else if (err != NO_ERROR) {
677 ALOGE("ERROR: Sync ptr returned %d", err);
678 *killThread = true;
679 }
680 return err;
681 }
682
pollForProxyData()683 void AudioUsbALSA::pollForProxyData(){
684 int err_poll = poll(pfdProxyPlayback, mnfdsPlayback, mtimeOut);
685 if (err_poll == 0 ) {
686 ALOGD("POLL timedout");
687 mkillPlayBackThread = true;
688 pfdProxyPlayback[0].revents = 0;
689 pfdProxyPlayback[1].revents = 0;
690 return;
691 }
692
693 if (pfdProxyPlayback[1].revents & POLLIN) {
694 ALOGD("Signalled from HAL about timeout");
695 uint64_t u;
696 read(mproxypfdPlayback, &u, sizeof(uint64_t));
697 pfdProxyPlayback[1].revents = 0;
698 if (u == SIGNAL_EVENT_KILLTHREAD) {
699 ALOGD("kill thread event");
700 mkillPlayBackThread = true;
701 pfdProxyPlayback[0].revents = 0;
702 pfdProxyPlayback[1].revents = 0;
703 return;
704 } else if (u == SIGNAL_EVENT_TIMEOUT) {
705 ALOGD("Setting timeout for 3 sec");
706 mtimeOut = POLL_TIMEOUT;
707 }
708 } else if (pfdProxyPlayback[1].revents & POLLERR || pfdProxyPlayback[1].revents & POLLHUP ||
709 pfdProxyPlayback[1].revents & POLLNVAL) {
710 ALOGE("Info: proxy throwing error from location 1");
711 mkillPlayBackThread = true;
712 pfdProxyPlayback[0].revents = 0;
713 pfdProxyPlayback[1].revents = 0;
714 return;
715 }
716
717 if (pfdProxyPlayback[0].revents & POLLERR || pfdProxyPlayback[0].revents & POLLHUP ||
718 pfdProxyPlayback[0].revents & POLLNVAL) {
719 ALOGE("Info: proxy throwing error");
720 mkillPlayBackThread = true;
721 pfdProxyPlayback[0].revents = 0;
722 pfdProxyPlayback[1].revents = 0;
723 }
724 }
725
pollForUsbData()726 void AudioUsbALSA::pollForUsbData(){
727 int err_poll = poll(pfdUsbPlayback, mnfdsPlayback, mtimeOut);
728 if (err_poll == 0 ) {
729 ALOGD("POLL timedout");
730 mkillPlayBackThread = true;
731 pfdUsbPlayback[0].revents = 0;
732 pfdUsbPlayback[1].revents = 0;
733 return;
734 }
735
736 if (pfdUsbPlayback[1].revents & POLLIN) {
737 ALOGD("Info: Signalled from HAL about an event");
738 uint64_t u;
739 read(musbpfdPlayback, &u, sizeof(uint64_t));
740 pfdUsbPlayback[0].revents = 0;
741 pfdUsbPlayback[1].revents = 0;
742 if (u == SIGNAL_EVENT_KILLTHREAD) {
743 ALOGD("kill thread");
744 mkillPlayBackThread = true;
745 return;
746 } else if (u == SIGNAL_EVENT_TIMEOUT) {
747 ALOGD("Setting timeout for 3 sec");
748 mtimeOut = POLL_TIMEOUT;
749 }
750 } else if (pfdUsbPlayback[1].revents & POLLERR || pfdUsbPlayback[1].revents & POLLHUP ||
751 pfdUsbPlayback[1].revents & POLLNVAL) {
752 ALOGE("Info: usb throwing error from location 1");
753 mkillPlayBackThread = true;
754 pfdUsbPlayback[0].revents = 0;
755 pfdUsbPlayback[1].revents = 0;
756 return;
757 }
758
759 if (pfdUsbPlayback[0].revents & POLLERR || pfdProxyPlayback[0].revents & POLLHUP ||
760 pfdUsbPlayback[0].revents & POLLNVAL) {
761 ALOGE("Info: usb throwing error");
762 mkillPlayBackThread = true;
763 pfdUsbPlayback[0].revents = 0;
764 return;
765 }
766 }
767
PlaybackThreadEntry()768 void AudioUsbALSA::PlaybackThreadEntry() {
769 ALOGD("PlaybackThreadEntry");
770 mnfdsPlayback = 2;
771 mtimeOut = TIMEOUT_INFINITE;
772 long frames;
773 static int fd;
774 struct snd_xferi x;
775 int bytes_written;
776 unsigned avail, xfer, bufsize;
777 unsigned proxyPeriod, usbPeriod;
778 uint32_t sampleRate;
779 uint32_t channels;
780 unsigned int tmp;
781 int numOfBytesWritten;
782 int err;
783 int filed;
784 const char *fn = "/data/test.pcm";
785 mdstUsb_addr = NULL;
786 msrcProxy_addr = NULL;
787
788 int proxySizeRemaining = 0;
789 int usbSizeFilled = 0;
790
791 pid_t tid = gettid();
792 androidSetThreadPriority(tid, ANDROID_PRIORITY_URGENT_AUDIO);
793
794 err = getCap((char *)"Playback:", mchannelsPlayback, msampleRatePlayback);
795 if (err) {
796 ALOGE("ERROR: Could not get playback capabilities from usb device");
797 return;
798 }
799
800 musbPlaybackHandle = configureDevice(PCM_OUT|PCM_STEREO|PCM_MMAP, (char *)"hw:1,0",
801 msampleRatePlayback, mchannelsPlayback, USB_PERIOD_SIZE, true);
802 if (!musbPlaybackHandle) {
803 ALOGE("ERROR: configureUsbDevice failed, returning");
804 closeDevice(musbPlaybackHandle);
805 return;
806 } else {
807 ALOGD("USB Configured for playback");
808 }
809
810 if (!mkillPlayBackThread) {
811 pfdUsbPlayback[0].fd = musbPlaybackHandle->timer_fd;
812 pfdUsbPlayback[0].events = POLLIN;
813 musbpfdPlayback = eventfd(0,0);
814 pfdUsbPlayback[1].fd = musbpfdPlayback;
815 pfdUsbPlayback[1].events = (POLLIN | POLLOUT | POLLERR | POLLNVAL | POLLHUP);
816 }
817
818 mproxyPlaybackHandle = configureDevice(PCM_IN|PCM_STEREO|PCM_MMAP, (char *)"hw:0,8",
819 msampleRatePlayback, mchannelsPlayback, PROXY_PERIOD_SIZE, false);
820 if (!mproxyPlaybackHandle) {
821 ALOGE("ERROR: Could not configure Proxy, returning");
822 closeDevice(musbPlaybackHandle);
823 return;
824 } else {
825 ALOGD("Proxy Configured for playback");
826 }
827
828 proxyPeriod = mproxyPlaybackHandle->period_size;
829 usbPeriod = musbPlaybackHandle->period_size;
830
831 if (!mkillPlayBackThread) {
832 pfdProxyPlayback[0].fd = mproxyPlaybackHandle->fd;
833 pfdProxyPlayback[0].events = (POLLIN); // | POLLERR | POLLNVAL);
834 mproxypfdPlayback = eventfd(0,0);
835 pfdProxyPlayback[1].fd = mproxypfdPlayback;
836 pfdProxyPlayback[1].events = (POLLIN | POLLOUT| POLLERR | POLLNVAL);
837 }
838
839 frames = (mproxyPlaybackHandle->flags & PCM_MONO) ? (proxyPeriod / 2) : (proxyPeriod / 4);
840 x.frames = (mproxyPlaybackHandle->flags & PCM_MONO) ? (proxyPeriod / 2) : (proxyPeriod / 4);
841 int usbframes = (musbPlaybackHandle->flags & PCM_MONO) ? (usbPeriod / 2) : (usbPeriod / 4);
842
843 u_int8_t *proxybuf = ( u_int8_t *) malloc(PROXY_PERIOD_SIZE);
844 u_int8_t *usbbuf = ( u_int8_t *) malloc(USB_PERIOD_SIZE);
845 memset(proxybuf, 0x0, PROXY_PERIOD_SIZE);
846 memset(usbbuf, 0x0, USB_PERIOD_SIZE);
847
848
849 /***********************keep reading from proxy and writing to USB******************************************/
850 while (mkillPlayBackThread != true) {
851 if (!mproxyPlaybackHandle->running) {
852 if (pcm_prepare(mproxyPlaybackHandle)) {
853 ALOGE("ERROR: pcm_prepare failed for proxy");
854 mkillPlayBackThread = true;
855 break;
856 }
857 }
858 if (!musbPlaybackHandle->running) {
859 if (pcm_prepare(musbPlaybackHandle)) {
860 ALOGE("ERROR: pcm_prepare failed for usb");
861 mkillPlayBackThread = true;
862 break;
863 }
864 }
865
866 /********** Proxy syncing before write **************/
867 if (!mkillPlayBackThread && (!mproxyPlaybackHandle->start)) {
868 err = startDevice(mproxyPlaybackHandle, &mkillPlayBackThread);
869 if (err == EPIPE) {
870 continue;
871 } else if (err != NO_ERROR) {
872 mkillPlayBackThread = true;
873 break;
874 }
875 }
876 if (proxySizeRemaining == 0) {
877 for (;;) {
878 if (!mproxyPlaybackHandle->running) {
879 if (pcm_prepare(mproxyPlaybackHandle)) {
880 ALOGE("ERROR: pcm_prepare failed for proxy");
881 mkillPlayBackThread = true;
882 break;
883 }
884 }
885 /* Sync the current Application pointer from the kernel */
886 mproxyPlaybackHandle->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL |
887 SNDRV_PCM_SYNC_PTR_AVAIL_MIN;
888
889 if (mtimeOut == TIMEOUT_INFINITE && !mkillPlayBackThread) {
890 err = syncPtr(mproxyPlaybackHandle, &mkillPlayBackThread);
891 if (err == EPIPE) {
892 continue;
893 } else if (err != NO_ERROR) {
894 break;
895 }
896 avail = pcm_avail(mproxyPlaybackHandle);
897 }
898 if (avail < mproxyPlaybackHandle->sw_p->avail_min && !mkillPlayBackThread) {
899 pollForProxyData();
900 //if polling returned some error
901 if (!mkillPlayBackThread) {
902 continue;
903 } else {
904 break;
905 }
906 } else { //Got some data or mkillPlayBackThread is true
907 break;
908 }
909 }
910 if (mkillPlayBackThread) {
911 break;
912 }
913
914 if (x.frames > avail)
915 frames = avail;
916
917 if (!mkillPlayBackThread) {
918 msrcProxy_addr = dst_address(mproxyPlaybackHandle);
919 memcpy(proxybuf, msrcProxy_addr, proxyPeriod );
920
921 x.frames -= frames;
922 mproxyPlaybackHandle->sync_ptr->c.control.appl_ptr += frames;
923 mproxyPlaybackHandle->sync_ptr->flags = 0;
924 proxySizeRemaining = proxyPeriod;
925 }
926
927 if (!mkillPlayBackThread) {
928 err = syncPtr(mproxyPlaybackHandle, &mkillPlayBackThread);
929 if (err == EPIPE) {
930 continue;
931 } else if (err != NO_ERROR) {
932 break;
933 }
934 }
935 }
936 //ALOGE("usbSizeFilled %d, proxySizeRemaining %d ",usbSizeFilled,proxySizeRemaining);
937 if (usbPeriod - usbSizeFilled <= proxySizeRemaining) {
938 memcpy(usbbuf + usbSizeFilled, proxybuf + proxyPeriod - proxySizeRemaining, usbPeriod - usbSizeFilled);
939 proxySizeRemaining -= (usbPeriod - usbSizeFilled);
940 usbSizeFilled = usbPeriod;
941 }
942 else {
943 memcpy(usbbuf + usbSizeFilled, proxybuf + proxyPeriod - proxySizeRemaining,proxySizeRemaining);
944 usbSizeFilled += proxySizeRemaining;
945 proxySizeRemaining = 0;
946 }
947
948 if (usbSizeFilled == usbPeriod) {
949 for (;;) {
950 if (!musbPlaybackHandle->running) {
951 if (pcm_prepare(musbPlaybackHandle)) {
952 ALOGE("ERROR: pcm_prepare failed for usb");
953 mkillPlayBackThread = true;
954 break;
955 }
956 }
957 /*************USB syncing before write ******************/
958 musbPlaybackHandle->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL |
959 SNDRV_PCM_SYNC_PTR_AVAIL_MIN;
960 if (mtimeOut == TIMEOUT_INFINITE && !mkillPlayBackThread) {
961 err = syncPtr(musbPlaybackHandle, &mkillPlayBackThread);
962 if (err == EPIPE) {
963 continue;
964 } else if (err != NO_ERROR) {
965 break;
966 }
967 avail = pcm_avail(musbPlaybackHandle);
968 //ALOGV("Avail USB is: %d", avail);
969 }
970
971 if (avail < musbPlaybackHandle->sw_p->avail_min && !mkillPlayBackThread) {
972 pollForUsbData();
973 if (!mkillPlayBackThread) {
974 continue;
975 } else {
976 break;
977 }
978 } else {
979 break;
980 }
981 }
982 if (mkillPlayBackThread) {
983 break;
984 }
985
986 if (!mkillPlayBackThread) {
987 mdstUsb_addr = dst_address(musbPlaybackHandle);
988
989 /**************End USB syncing before write *************/
990
991 memcpy(mdstUsb_addr, usbbuf, usbPeriod );
992 usbSizeFilled = 0;
993 memset(usbbuf, 0x0, usbPeriod);
994 }
995
996 /**************** sync up after write -- USB ************************/
997 musbPlaybackHandle->sync_ptr->c.control.appl_ptr += usbframes;
998 musbPlaybackHandle->sync_ptr->flags = 0;
999 if (!mkillPlayBackThread) {
1000 err = syncPtr(musbPlaybackHandle, &mkillPlayBackThread);
1001 if (err == EPIPE) {
1002 continue;
1003 } else if (err != NO_ERROR) {
1004 break;
1005 }
1006 }
1007
1008 bytes_written = musbPlaybackHandle->sync_ptr->c.control.appl_ptr - musbPlaybackHandle->sync_ptr->s.status.hw_ptr;
1009 ALOGE("Appl ptr %d , hw_ptr %d, difference %d",musbPlaybackHandle->sync_ptr->c.control.appl_ptr, musbPlaybackHandle->sync_ptr->s.status.hw_ptr, bytes_written);
1010
1011 /*
1012 Following is the check to prevent USB from going to bad state.
1013 This happens in case of an underrun where there is not enough
1014 data from the proxy
1015 */
1016 if (bytes_written <= usbPeriod && musbPlaybackHandle->start) {
1017 ioctl(musbPlaybackHandle->fd, SNDRV_PCM_IOCTL_PAUSE,1);
1018 pcm_prepare(musbPlaybackHandle);
1019 musbPlaybackHandle->start = false;
1020 continue;
1021 }
1022 if ((bytes_written >= musbPlaybackHandle->sw_p->start_threshold) && (!musbPlaybackHandle->start)) {
1023 if (!mkillPlayBackThread) {
1024 err = startDevice(musbPlaybackHandle, &mkillPlayBackThread);
1025 if (err == EPIPE) {
1026 continue;
1027 } else if (err != NO_ERROR) {
1028 mkillPlayBackThread = true;
1029 break;
1030 }
1031 }
1032 }
1033 /*************** End sync up after write -- USB *********************/
1034 }
1035 }
1036 if (mkillPlayBackThread) {
1037 if (proxybuf)
1038 free(proxybuf);
1039 if (usbbuf)
1040 free(usbbuf);
1041 mproxypfdPlayback = -1;
1042 musbpfdPlayback = -1;
1043 closeDevice(mproxyPlaybackHandle);
1044 closeDevice(musbPlaybackHandle);
1045 }
1046 ALOGD("Exiting USB Playback Thread");
1047 }
1048
startPlayback()1049 void AudioUsbALSA::startPlayback()
1050 {
1051 mkillPlayBackThread = false;
1052 ALOGD("Creating USB Playback Thread");
1053 pthread_create(&mPlaybackUsb, NULL, PlaybackThreadWrapper, this);
1054 }
1055
startRecording()1056 void AudioUsbALSA::startRecording()
1057 {
1058 //create Thread
1059 mkillRecordingThread = false;
1060 ALOGV("Creating USB recording Thread");
1061 pthread_create(&mRecordingUsb, NULL, RecordingThreadWrapper, this);
1062 }
1063 }
1064