ssize_t AudioALSAStreamOut::write(const void *buffer, size_t bytes) { ALOGV("%s(), buffer = %p, bytes = %d", __FUNCTION__, buffer, bytes); size_t outputSize = 0; if (mSuspendCount > 0 || (mStreamOutType == STREAM_OUT_HDMI_STEREO && mSuspendStreamOutHDMIStereoCount > 0) || (mStreamManager->isModeInPhoneCall() == true && mStreamOutType != STREAM_OUT_PRIMARY)) { // here to sleep a buffer size latency and return. ALOGV("%s(), mStreamOutType = %d, mSuspendCount = %u, mSuspendStreamOutHDMIStereoCount = %d", __FUNCTION__, mStreamOutType, mSuspendCount, mSuspendStreamOutHDMIStereoCount); usleep(latency() * 1000); mPresentedBytes += bytes; return bytes; } AudioAutoTimeoutLock _l(mLock); status_t status = NO_ERROR; /// check open if (mStandby == true) { status = open(); mStreamManager->setMasterVolume(mStreamManager->getMasterVolume()); //#ifdef MTK_DYNAMIC_CHANGE_HAL_BUFFER_SIZE setLowLatencyMode(mLowLatencyMode); //#endif mPlaybackHandler->setFirstDataWriteFlag(true); } else { ASSERT(mPlaybackHandler != NULL); mPlaybackHandler->setFirstDataWriteFlag(false); } WritePcmDumpData(buffer, bytes); /// write pcm data ASSERT(mPlaybackHandler != NULL); outputSize = mPlaybackHandler->write(buffer, bytes); mPresentedBytes += outputSize; //ALOGD("%s(), outputSize = %d, bytes = %d,mPresentedBytes=%d", __FUNCTION__, outputSize, bytes, mPresentedBytes); return outputSize; }
ssize_t AudioALSAPlaybackHandlerBTSCO::write(const void *buffer, size_t bytes) { ALOGV("%s(), buffer = %p, bytes = %d", __FUNCTION__, buffer, bytes); if (mPcm == NULL) { ALOGE("%s(), mPcm == NULL, return", __FUNCTION__); return bytes; } // const -> to non const void *pBuffer = const_cast<void *>(buffer); ASSERT(pBuffer != NULL); // SRC void *pBufferAfterBliSrc = NULL; uint32_t bytesAfterBliSrc = 0; doBliSrc(pBuffer, bytes, &pBufferAfterBliSrc, &bytesAfterBliSrc); // bit conversion void *pBufferAfterBitConvertion = NULL; uint32_t bytesAfterBitConvertion = 0; doBitConversion(pBufferAfterBliSrc, bytesAfterBliSrc, &pBufferAfterBitConvertion, &bytesAfterBitConvertion); // write data to pcm driver WritePcmDumpData(pBufferAfterBitConvertion, bytesAfterBitConvertion); int retval = pcm_write(mPcm, pBufferAfterBitConvertion, bytesAfterBitConvertion); if (retval != 0) { ALOGE("%s(), pcm_write() error, retval = %d", __FUNCTION__, retval); } return bytes; }
//echoref+++ void AudioALSACaptureDataProviderBase::provideEchoRefCaptureDataToAllClients(const uint32_t open_index) { ALOGV("+%s()", __FUNCTION__); AudioAutoTimeoutLock _l(mClientLock); if (open_index != mOpenIndex) { ALOGD("%s(), open_index(%d) != mOpenIndex(%d), return", __FUNCTION__, open_index, mOpenIndex); return; } AudioALSACaptureDataClient *pCaptureDataClient = NULL; WritePcmDumpData(); for (size_t i = 0; i < mCaptureDataClientVector.size(); i++) { pCaptureDataClient = mCaptureDataClientVector[i]; pCaptureDataClient->copyEchoRefCaptureDataToClient(mPcmReadBuf); } ALOGV("-%s()", __FUNCTION__); }
ssize_t AudioALSAPlaybackHandlerNormal::write(const void *buffer, size_t bytes) { ALOGV("%s(), buffer = %p, bytes = %d", __FUNCTION__, buffer, bytes); if (mPcm == NULL) { ALOGE("%s(), mPcm == NULL, return", __FUNCTION__); return bytes; } // const -> to non const void *pBuffer = const_cast<void *>(buffer); ASSERT(pBuffer != NULL); #ifdef DEBUG_LATENCY clock_gettime(CLOCK_REALTIME, &mNewtime); latencyTime[0] = calc_time_diff(mNewtime, mOldtime); mOldtime = mNewtime; #endif // stereo to mono for speaker if (mStreamAttributeSource->audio_format == AUDIO_FORMAT_PCM_16_BIT) // AudioMixer will perform stereo to mono when 32-bit { doStereoToMonoConversionIfNeed(pBuffer, bytes); } // post processing (can handle both Q1P16 and Q1P31 by audio_format_t) void *pBufferAfterPostProcessing = NULL; uint32_t bytesAfterPostProcessing = 0; doPostProcessing(pBuffer, bytes, &pBufferAfterPostProcessing, &bytesAfterPostProcessing); // SRC void *pBufferAfterBliSrc = NULL; uint32_t bytesAfterBliSrc = 0; doBliSrc(pBufferAfterPostProcessing, bytesAfterPostProcessing, &pBufferAfterBliSrc, &bytesAfterBliSrc); // bit conversion void *pBufferAfterBitConvertion = NULL; uint32_t bytesAfterBitConvertion = 0; doBitConversion(pBufferAfterBliSrc, bytesAfterBliSrc, &pBufferAfterBitConvertion, &bytesAfterBitConvertion); // data pending void *pBufferAfterPending = NULL; uint32_t bytesAfterpending = 0; dodataPending(pBufferAfterBitConvertion, bytesAfterBitConvertion, &pBufferAfterPending, &bytesAfterpending); // pcm dump WritePcmDumpData(pBufferAfterPending, bytesAfterpending); #ifdef DEBUG_LATENCY clock_gettime(CLOCK_REALTIME, &mNewtime); latencyTime[1] = calc_time_diff(mNewtime, mOldtime); mOldtime = mNewtime; #endif // write data to pcm driver int retval = pcm_write(mPcm, pBufferAfterPending, bytesAfterpending); #ifdef DEBUG_LATENCY clock_gettime(CLOCK_REALTIME, &mNewtime); latencyTime[2] = calc_time_diff(mNewtime, mOldtime); mOldtime = mNewtime; #endif #if 1 // TODO(Harvey, Wendy), temporary disable Voice Unlock until 24bit ready //============Voice UI&Unlock REFERECE============= AudioVUnlockDL *VUnlockhdl = AudioVUnlockDL::getInstance(); if (VUnlockhdl != NULL) { // get remain time //VUnlockhdl->SetDownlinkStartTime(ret_ms); VUnlockhdl->GetFirstDLTime(); //VUnlockhdl->SetInputStandBy(false); if (mStreamAttributeSource->output_devices & AUDIO_DEVICE_OUT_WIRED_HEADSET || mStreamAttributeSource->output_devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) { memset((void *)pBufferAfterBitConvertion, 0, bytesAfterBitConvertion); } VUnlockhdl->WriteStreamOutToRing(pBufferAfterBitConvertion, bytesAfterBitConvertion); } //=========================================== #endif if (retval != 0) { ALOGE("%s(), pcm_write() error, retval = %d", __FUNCTION__, retval); } #ifdef DEBUG_LATENCY ALOGD("AudioALSAPlaybackHandlerNormal::write (-) latency_in_us,%1.6lf,%1.6lf,%1.6lf", latencyTime[0], latencyTime[1], latencyTime[2]); #endif return bytes; }
ssize_t AudioALSAStreamIn::read(void *buffer, ssize_t bytes) { ALOGV("%s(), bytes= %d", __FUNCTION__, bytes); ssize_t ret_size = bytes; if (mSuspendCount > 0) { // here to sleep a buffer size latency and return. ALOGD("%s(), mSuspendCount = %u", __FUNCTION__, mSuspendCount); memset(buffer, 0, bytes); size_t wordSize = 0; switch (mStreamAttributeTarget.audio_format) { case AUDIO_FORMAT_PCM_8_BIT: { wordSize = sizeof(int8_t); break; } case AUDIO_FORMAT_PCM_16_BIT: { wordSize = sizeof(int16_t); break; } case AUDIO_FORMAT_PCM_8_24_BIT: case AUDIO_FORMAT_PCM_32_BIT: { wordSize = sizeof(int32_t); break; } default: { ALOGW("%s(), wrong format(0x%x), default use wordSize = %d", __FUNCTION__, mStreamAttributeTarget.audio_format, sizeof(int16_t)); wordSize = sizeof(int16_t); break; } } int sleepus = ((bytes * 1000) / ((mStreamAttributeTarget.sample_rate / 1000) * mStreamAttributeTarget.num_channels * wordSize)); ALOGD("%s(), sleepus = %d", __FUNCTION__, sleepus); usleep(sleepus); return bytes; } AudioAutoTimeoutLock _l(mLock); status_t status = NO_ERROR; /// check open if (mStandby == true) { status = open(); } /// write pcm data ASSERT(mCaptureHandler != NULL); ret_size = mCaptureHandler->read(buffer, bytes); WritePcmDumpData(buffer, bytes); return ret_size; }
ssize_t AudioALSAPlaybackHandlerSphDL::write(const void *buffer, size_t bytes) { ALOGV("%s(), buffer = %p, bytes = %d", __FUNCTION__, buffer, bytes); if (mPcm == NULL) { ALOGE("%s(), mPcm == NULL, return", __FUNCTION__); return bytes; } // const -> to non const void *pBuffer = const_cast<void *>(buffer); ASSERT(pBuffer != NULL); #ifdef DEBUG_LATENCY clock_gettime(CLOCK_REALTIME, &mNewtime); latencyTime[0] = calc_time_diff(mNewtime, mOldtime); mOldtime = mNewtime; #endif // stereo to mono for speaker if (mStreamAttributeSource->audio_format == AUDIO_FORMAT_PCM_16_BIT) // AudioMixer will perform stereo to mono when 32-bit { doStereoToMonoConversionIfNeed(pBuffer, bytes); } // post processing (can handle both Q1P16 and Q1P31 by audio_format_t) void *pBufferAfterPostProcessing = NULL; uint32_t bytesAfterPostProcessing = 0; doPostProcessing(pBuffer, bytes, &pBufferAfterPostProcessing, &bytesAfterPostProcessing); // SRC void *pBufferAfterBliSrc = NULL; uint32_t bytesAfterBliSrc = 0; doBliSrc(pBufferAfterPostProcessing, bytesAfterPostProcessing, &pBufferAfterBliSrc, &bytesAfterBliSrc); // bit conversion void *pBufferAfterBitConvertion = NULL; uint32_t bytesAfterBitConvertion = 0; doBitConversion(pBufferAfterBliSrc, bytesAfterBliSrc, &pBufferAfterBitConvertion, &bytesAfterBitConvertion); // pcm dump WritePcmDumpData(pBufferAfterBitConvertion, bytesAfterBitConvertion); #ifdef DEBUG_LATENCY clock_gettime(CLOCK_REALTIME, &mNewtime); latencyTime[1] = calc_time_diff(mNewtime, mOldtime); mOldtime = mNewtime; #endif // write data to pcm driver int retval = pcm_write(mPcm, pBufferAfterBitConvertion, bytesAfterBitConvertion); #ifdef DEBUG_LATENCY clock_gettime(CLOCK_REALTIME, &mNewtime); latencyTime[2] = calc_time_diff(mNewtime, mOldtime); mOldtime = mNewtime; #endif if (retval != 0) { ALOGE("%s(), pcm_write() error, retval = %d", __FUNCTION__, retval); } #ifdef DEBUG_LATENCY ALOGD("AudioALSAPlaybackHandlerSphDL::write (-) latency_in_us,%1.6lf,%1.6lf,%1.6lf", latencyTime[0], latencyTime[1], latencyTime[2]); #endif return bytes; }
int AudioALSAPlaybackHandlerOffload::process_write() { while(1) { int32_t consumed; if(mDecBsbufRemain < mDecHandler->BsbufferSize() && mDecPcmbufRemain < mWritebytes) return OFFLOAD_WRITE_EMPTY; if(mDecPcmbufRemain >= mWritebytes) { memcpy(offload_stream.tmpBuffer, mDecPcmbuf, mWritebytes); mDecPcmbufRemain -= mWritebytes; memmove(mDecPcmbuf, mDecPcmbuf+mWritebytes, mDecPcmbufRemain); // stereo to mono for speaker if (mStreamAttributeSource->audio_format == AUDIO_FORMAT_PCM_16_BIT) // AudioMixer will perform stereo to mono when 32-bit { doStereoToMonoConversionIfNeed(offload_stream.tmpBuffer, mWritebytes); } // post processing (can handle both Q1P16 and Q1P31 by audio_format_t) void *pBufferAfterPostProcessing = NULL; uint32_t bytesAfterPostProcessing = 0; doPostProcessing(offload_stream.tmpBuffer, mWritebytes, &pBufferAfterPostProcessing, &bytesAfterPostProcessing); // SRC void *pBufferAfterBliSrc = NULL; uint32_t bytesAfterBliSrc = 0; doBliSrc(pBufferAfterPostProcessing, bytesAfterPostProcessing, &pBufferAfterBliSrc, &bytesAfterBliSrc); // bit conversion void *pBufferAfterBitConvertion = NULL; uint32_t bytesAfterBitConvertion = 0; doBitConversion(pBufferAfterBliSrc, bytesAfterBliSrc, &pBufferAfterBitConvertion, &bytesAfterBitConvertion); int *ptr32; int ptr32_temp, ptr32_cnt; ptr32 = (int*)pBufferAfterBitConvertion; #if 0 for(ptr32_cnt = 0; ptr32_cnt<(bytesAfterBitConvertion>>2); ptr32_cnt++) { ptr32_temp = *ptr32; *ptr32 = ptr32_temp<<8; *ptr32++; } #endif // data pending void *pBufferAfterPending = NULL; uint32_t bytesAfterpending = 0; dodataPending(pBufferAfterBitConvertion, bytesAfterBitConvertion, &pBufferAfterPending, &bytesAfterpending); // pcm dump WritePcmDumpData(pBufferAfterPending, bytesAfterpending); //int retval = compress_write(mComprStream, offload_stream.tmpBuffer, mWritebytes); int retval = compress_write(mComprStream, pBufferAfterPending, bytesAfterpending); if (retval < 0) { ALOGE("%s(), compress_write() error, retval = %d, %s", __FUNCTION__, retval, compress_get_error(mComprStream)); } else { if(!mReady) { mReady = true; if( offload_stream.offload_state == OFFLOAD_STATE_IDLE) offload_stream.offload_state = OFFLOAD_STATE_PLAYING; compress_nonblock(mComprStream, 1); compress_start(mComprStream); } } #if 0 if( compress_blockwrite(mComprStream) != 0) ALOGE("%s(), compress_blockwrite() error= %s", __FUNCTION__, compress_get_error(mComprStream)); #endif return OFFLOAD_WRITE_REMAIN; } ALOGV("%s(),Decode+ %x, %x ", __FUNCTION__, mDecBsbufRemain, mDecPcmbufRemain); if(mDecBsbufRemain >= mDecHandler->BsbufferSize()) consumed = mDecHandler->DecodeAudio( mDecBsbuf, mDecPcmbuf+mDecPcmbufRemain, mDecBsbufRemain); if(consumed < 0) { ALOGD("%s(), Decoder return error:%x", __FUNCTION__, consumed); } else { mDecBsbufRemain -= consumed; memmove(mDecBsbuf, mDecBsbuf + consumed, mDecBsbufRemain); mDecPcmbufRemain += mDecHandler->PcmbufferSize(); } ALOGD("%s(),Decode- %x, %x", __FUNCTION__, mDecBsbufRemain, mDecPcmbufRemain); }