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;
}
Пример #3
0
//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;
}
Пример #5
0
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);
    }