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 { 60 AudioUsbALSA::AudioUsbALSA() 61 { 62 mproxypfdPlayback = -1; 63 musbpfdPlayback = -1; 64 mkillPlayBackThread = false; 65 mkillRecordingThread = false; 66 } 67 68 AudioUsbALSA::~AudioUsbALSA() 69 { 70 mkillPlayBackThread = true; 71 mkillRecordingThread = true; 72 } 73 74 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 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 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 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 273 void AudioUsbALSA::setkillUsbRecordingThread(bool val){ 274 ALOGD("setkillUsbRecordingThread"); 275 mkillRecordingThread = val; 276 } 277 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 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 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 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 580 void *AudioUsbALSA::PlaybackThreadWrapper(void *me) { 581 static_cast<AudioUsbALSA *>(me)->PlaybackThreadEntry(); 582 return NULL; 583 } 584 585 void *AudioUsbALSA::RecordingThreadWrapper(void *me) { 586 static_cast<AudioUsbALSA *>(me)->RecordingThreadEntry(); 587 return NULL; 588 } 589 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 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 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 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 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 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 1049 void AudioUsbALSA::startPlayback() 1050 { 1051 mkillPlayBackThread = false; 1052 ALOGD("Creating USB Playback Thread"); 1053 pthread_create(&mPlaybackUsb, NULL, PlaybackThreadWrapper, this); 1054 } 1055 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