示例#1
0
status_t AudioTrackCenter::init() {
	audio_stream_type_t streamType;
	if (!mAfFrameCount || !mAfSampleRate) {
	    if (AudioSystem::getOutputFrameCount(&mAfFrameCount, streamType) != NO_ERROR) {
	        SXLOGE("AudioSystem::getOutputFrameCount Fail!!!");
			return NO_INIT;
	    }
	    if (AudioSystem::getOutputSamplingRate(&mAfSampleRate, streamType) != NO_ERROR) {
	        SXLOGE("AudioSystem::getOutputSamplingRate Fail!!!");
			return NO_INIT;
	    }
		SXLOGD("init, mAfFrameCount = %d, mAfSampleRate = %d",mAfFrameCount, mAfSampleRate);
	}

	return OK;
}
AudioVUnlockDL::AudioVUnlockDL()
{
    int32_t ret;
    ret = pthread_mutex_init(&mVUnlockReadMutex, NULL);
    if (ret != 0)
    {
        SXLOGE("Failed to initialize AudioVUnlockDL mMutex!");
    }

    ret = pthread_mutex_init(&mSRCMutex, NULL);
    if (ret != 0)
    {
        SXLOGE("Failed to initialize AudioVUnlockDL mSRCMutex!");
    }

    mState = VPWStreamIn_CREATED;
    mReadThreadExit = true;
    mReadThreadActive = false;
    mOutputSampleRate = VPW_OUTPUT_SAMPLERATE;
    mInputSampleRate = 44100;
    mInChannel = 2;
    mOutChannel = 0;
    mpSrcHdl = NULL;
    mSrcBufLen = 0;
    mOutFile = 0;
    mSampleCount_Dump = 0;
    mInputStandby = true;
    mStreamOutLatency = 92;
    mULtime.tv_sec = 0;
    mULtime.tv_nsec = 0;
    mDLtime.tv_sec = 0;
    mNewDLtime.tv_nsec = 0;
    mNewDLtime.tv_sec = 0;
    mDLtime.tv_nsec = 0;
    mStandbyTime.tv_sec = 0;
    mStandbyTime.tv_nsec = 0;
    mNeedBlock = false;
    mGetTime = true;
    mOutRemaining = 0;
    mInRemaining = 0;
    mTempBuf = NULL;
    mTempBufsz = 0;
}
示例#3
0
文件: ATVCtrl.cpp 项目: LuckJC/pro-mk
const sp<IATVCtrlService>& ATVCtrl::get_ATVCtrlService_FM()
{
    SXLOGD("get_ATVCtrlService_FM()");
    Mutex::Autolock _l(mLock);

    if (spATVCtrlService.get() == 0 || spATVCtrlClient_FM == NULL)
    {
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;

        do
        {
            binder = sm->getService(String16("media.ATVCtrlService"));

            if (binder != 0)
            {
                break;
            }

            SXLOGW("ATVCtrlService not published, waiting...");
            usleep(500000); // 0.5 s
        }
        while (true);

        if (spATVCtrlClient_FM == NULL)
        {
            spATVCtrlClient_FM = new ATVCtrlClient();
        }
        else
        {
            /*
                     if (gATVErrorCallback){
                            gATVErrorCallback(NO_ERROR);
                     }
            */
            SXLOGD(" spATVCtrlClient_FM exist ");
        }

        binder->linkToDeath(spATVCtrlClient_FM);
        spATVCtrlService = interface_cast<IATVCtrlService>(binder);
        spATVCtrlService->registerClient_FM(spATVCtrlClient_FM);
        SXLOGD(" ATVCtrlService is published, or new spATVCtrlClient_FM ");
    }

    if (spATVCtrlService == 0)
    {
        SXLOGE("no ATVCtrlService!?");
    }

    return spATVCtrlService;
}
//#define WRITEOVER
void *ReadRoutine(void *hdl)
{
    AudioVUnlockRingBuf *ringBuf_in;
    AudioVUnlockRingBuf *ringBuf_out;
    int32_t readAmount;
    int32_t rwfailcount = 0;
    AudioVUnlockDL *VInstance = AudioVUnlockDL::getInstance();
    char *tempbuffer  = new char[VOICE_UNLOCK_RING_BUFFER_SIZE];
    char *tempSRCbuffer = new char[6000];
    uint32_t dataread = 0;
    int32_t datawritten = 0;
    SXLOGD(" [ReadRoutine] start");
    // defaut setting of thread init
    pthread_mutex_lock(&mVUnlockReadMutex);
    VInstance->mReadThreadExit = false;
    VInstance->mReadThreadActive = true;
    pthread_mutex_unlock(&mVUnlockReadMutex);

    ringBuf_in = (AudioVUnlockRingBuf *) & (VInstance->mRingBufIn);
    ringBuf_out = (AudioVUnlockRingBuf *) & (VInstance->mRingBufOut);

    if (VInstance == NULL || ringBuf_in == NULL || ringBuf_out == NULL)
    {
        SXLOGD(" [ReadRoutine] Buffer NULL,  Exit");
        pthread_mutex_lock(&mVUnlockReadMutex);
        VInstance->mReadThreadExit = true;
        VInstance->mReadThreadActive = false;
        pthread_mutex_unlock(&mVUnlockReadMutex);
    }

#ifdef MTK_AUDIO_ADJUST_PRIORITY
    int result = -1;
    // if set priority false , force to set priority
    if (result == -1)
    {
        struct sched_param sched_p;
        sched_getparam(0, &sched_p);
        sched_p.sched_priority = RTPM_PRIO_AUDIO_I2S;
        if (0 != sched_setscheduler(0, SCHED_RR, &sched_p))
        {
            SXLOGE("[%s] failed, errno: %d", __func__, errno);
        }
        else
        {
            sched_p.sched_priority = RTPM_PRIO_AUDIO_I2S;
            sched_getparam(0, &sched_p);
            SXLOGD("sched_setscheduler ok, priority: %d", sched_p.sched_priority);
        }
    }
#endif

    while (!VInstance->mReadThreadExit)
    {
        // Clear DL time if remaining data is pushed.
        if (VInstance->mDLtime.tv_nsec != 0 && VInstance->mNewDLtime.tv_sec  != 0)
        {
            if (VInstance->mInRemaining == 0 && VInstance->mOutRemaining == 0)
            {
                VInstance->mDLtime.tv_sec  = 0;
                VInstance->mDLtime.tv_nsec = 0;
                //SXLOGV("[ReadRoutine] All Data from last playback pushed");
            }
        }
        // switch DL time to new DL time
        if (VInstance->mDLtime.tv_sec == 0 && VInstance->mNewDLtime.tv_sec  != 0)
        {
            VInstance->mDLtime.tv_sec = VInstance->mNewDLtime.tv_sec ;
            VInstance->mDLtime.tv_nsec = VInstance->mNewDLtime.tv_nsec;
            VInstance->mNewDLtime.tv_sec  = 0;
            VInstance->mNewDLtime.tv_nsec = 0;
            SXLOGV("[ReadRoutine] switch to new DL time %d %d", VInstance->mDLtime.tv_sec, VInstance->mDLtime.tv_nsec);
        }

        uint32_t readsz = ringBuf_in->GetBufDataSz();
        dataread = ringBuf_in->ReadWithoutAdvance(tempbuffer, readsz);
        if (VInstance->mInRemaining != 0)
        {
            dataread = dataread > VInstance->mInRemaining ? VInstance->mInRemaining : dataread;
        }
        if (dataread <= 0 || VInstance->mDLtime.tv_sec == 0) // do not read data if mDLtime is ready.
        {
            if (VInstance->StreamOutStandBy() && ringBuf_out->GetBufDataSz() == 0)
            {
                //SXLOGV("[ReadRoutine]  Standby, and all data from last playback is pushed");
                VInstance->mDLtime.tv_sec = 0;
                VInstance->mDLtime.tv_nsec = 0;
            }
            //SXLOGV("[ReadRoutine] No data from stream out, sleep");
            usleep(30 * 1000);
        }
        else
        {
            //do SRC
            uint32_t dataproduced = ringBuf_out->GetBufSpace();
            dataproduced = dataproduced > 6000 ? 6000 : dataproduced;
            int32_t dataConsumed = VInstance->DoSRC((uint8_t *) tempbuffer, &dataread , (uint8_t *) tempSRCbuffer, &dataproduced);

#ifdef DUMP_VPW_StreamIn_DATA
            //VInstance->DumpData(tempSRCbuffer, dataproduced);
            if (VInstance->mOutFile_1 != NULL)
            {
               VInstance->mOutFile_1 = fopen("/sdcard/audio_dump/VPW_SRC.pcm", "ab+");
                fwrite(tempSRCbuffer, sizeof(char), dataproduced, VInstance->mOutFile_1);
                fclose(VInstance->mOutFile_1);
            }
#endif
            if (dataConsumed > 0)
            {
                datawritten = ringBuf_out->Write(tempSRCbuffer, dataproduced);
                SXLOGV("[ReadRoutine] write to ring out, datawritten %d", datawritten);
            }
            else
            {
                datawritten = 0;
            }
            if (datawritten <= 0) //  write fail
            {
                rwfailcount++;
                if (rwfailcount > 100)
                {
                    SXLOGD("[ReadRoutine] Fail, write fail");
                    break;
                }
                SXLOGD("[ReadRoutine] No space to write, sleep");
                usleep(10 * 1000); //10ms
            }
            else//advance read pointer according to data actually write to output buffer
            {
                ringBuf_in->AdvanceReadPointer((uint32_t)dataConsumed);
                if (VInstance->mInRemaining != 0)
                {
                    SXLOGV("[ReadRoutine] last playback in buffer remaining %d", VInstance->mInRemaining);
                    VInstance->mInRemaining -= dataConsumed;
                    VInstance->mOutRemaining +=  datawritten;
                }
                ringBuf_out->SignalBufData();
                SXLOGV("[ReadRoutine] advance Read poniter %d " , (uint32_t)dataConsumed);
                rwfailcount = 0;
            }
        }
    }
    delete tempbuffer;
    delete tempSRCbuffer;
    SXLOGD("[ReadRoutine] exit ");

    VInstance->ClearState(VPWStreamIn_READ_START);

    SXLOGD("stop and signal ReadRefFromRing to stop");
    ringBuf_out->SignalBufData();

    int cnt_val = 50;
    while ((VInstance->mReadFunctionActive == true) && (cnt_val > 0))
    {
        SXLOGD("[ReadRoutine]Signal ReadRefFromRing to stop and wait (%d) ", cnt_val);
        cnt_val--;
        ringBuf_out->SignalBufData();
        usleep(1000 * 10);
    }

    pthread_mutex_lock(&mVUnlockReadMutex);
    VInstance->mReadThreadExit = true;
    VInstance->mReadThreadActive = false;
    pthread_mutex_unlock(&mVUnlockReadMutex);
    return 0;
}
示例#5
0
void MyVorbisExtractor::buildTableOfContents() {
    off64_t offset = mFirstDataOffset;
    Page page;
    ssize_t pageSize;
#ifndef MTK_AOSP_ENHANCEMENT
    while ((pageSize = readPage(offset, &page)) > 0) {
#else
	struct timeval tb,te;
	gettimeofday(&tb,NULL);
    while (mTocStarted && ((pageSize = readPage(offset, &page)) > 0)) {
        if(page.mGranulePosition < 0xFFFFFFFFFFFF)
        {
#endif
        mTableOfContents.push();

        TOCEntry &entry =
            mTableOfContents.editItemAt(mTableOfContents.size() - 1);

        entry.mPageOffset = offset;
        entry.mTimeUs = page.mGranulePosition * 1000000ll / mVi.rate;
#ifdef MTK_AOSP_ENHANCEMENT
        //sleep 100ms for consumes over 2s
        gettimeofday(&te,NULL);
        if((te.tv_sec - tb.tv_sec) > 2)
         {
        	  gettimeofday(&tb,NULL);
	          usleep(100000);	  
         }
        }
#endif
        offset += (size_t)pageSize;
    }

    // Limit the maximum amount of RAM we spend on the table of contents,
    // if necessary thin out the table evenly to trim it down to maximum
    // size.

    static const size_t kMaxTOCSize = 8192;
    static const size_t kMaxNumTOCEntries = kMaxTOCSize / sizeof(TOCEntry);

    size_t numerator = mTableOfContents.size();

    if (numerator > kMaxNumTOCEntries) {
        size_t denom = numerator - kMaxNumTOCEntries;

        size_t accum = 0;
        for (ssize_t i = mTableOfContents.size() - 1; i >= 0; --i) {
            accum += denom;
            if (accum >= numerator) {
                mTableOfContents.removeAt(i);
                accum -= numerator;
            }
        }
    }
#ifdef MTK_AOSP_ENHANCEMENT
    mTocDone = true;
#endif
}

status_t MyVorbisExtractor::verifyHeader(
        MediaBuffer *buffer, uint8_t type) {
    const uint8_t *data =
        (const uint8_t *)buffer->data() + buffer->range_offset();

    size_t size = buffer->range_length();

    if (size < 7 || data[0] != type || memcmp(&data[1], "vorbis", 6)) {
        return ERROR_MALFORMED;
    }

    ogg_buffer buf;
    buf.data = (uint8_t *)data;
    buf.size = size;
    buf.refcount = 1;
    buf.ptr.owner = NULL;

    ogg_reference ref;
    ref.buffer = &buf;
    ref.begin = 0;
    ref.length = size;
    ref.next = NULL;

    oggpack_buffer bits;
    oggpack_readinit(&bits, &ref);

    CHECK_EQ(oggpack_read(&bits, 8), type);
    for (size_t i = 0; i < 6; ++i) {
        oggpack_read(&bits, 8);  // skip 'vorbis'
    }

    switch (type) {
        case 1:
        {
#ifndef MTK_AOSP_ENHANCEMENT    	
            CHECK_EQ(0, _vorbis_unpack_info(&mVi, &bits));
#else
            _vorbis_unpack_info(&mVi, &bits);//skip the CHECK
#endif
            mMeta->setData(kKeyVorbisInfo, 0, data, size);
            mMeta->setInt32(kKeySampleRate, mVi.rate);
            mMeta->setInt32(kKeyChannelCount, mVi.channels);
            
#ifdef MTK_AOSP_ENHANCEMENT
            if(mVi.channels > 2)
            {
#ifndef MTK_SWIP_VORBIS
                SXLOGE("Tremolo does not support multi channel");
                return ERROR_UNSUPPORTED;
#endif
            }
#endif 

            ALOGV("lower-bitrate = %ld", mVi.bitrate_lower);
            ALOGV("upper-bitrate = %ld", mVi.bitrate_upper);
            ALOGV("nominal-bitrate = %ld", mVi.bitrate_nominal);
            ALOGV("window-bitrate = %ld", mVi.bitrate_window);

            off64_t size;
            if (mSource->getSize(&size) == OK) {
                uint64_t bps = approxBitrate();
                if (bps != 0) {
                    mMeta->setInt64(kKeyDuration, size * 8000000ll / bps);
                }
            }
            break;
        }

        case 3:
        {
            if (0 != _vorbis_unpack_comment(&mVc, &bits)) {
                return ERROR_MALFORMED;
            }

            parseFileMetaData();
            break;
        }

        case 5:
        {
            if (0 != _vorbis_unpack_books(&mVi, &bits)) {
                return ERROR_MALFORMED;
            }

            mMeta->setData(kKeyVorbisBooks, 0, data, size);
            break;
        }
    }

    return OK;
}

uint64_t MyVorbisExtractor::approxBitrate() {
    if (mVi.bitrate_nominal != 0) {
        return mVi.bitrate_nominal;
    }

    return (mVi.bitrate_lower + mVi.bitrate_upper) / 2;
}

void MyVorbisExtractor::parseFileMetaData() {
    mFileMeta = new MetaData;
#ifdef MTK_AOSP_ENHANCEMENT
    if(mFileMeta.get() == NULL)  return;
#endif
    mFileMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_OGG);

    for (int i = 0; i < mVc.comments; ++i) {
        const char *comment = mVc.user_comments[i];
        size_t commentLength = mVc.comment_lengths[i];
        parseVorbisComment(mFileMeta, comment, commentLength);
        //ALOGI("comment #%d: '%s'", i + 1, mVc.user_comments[i]);
    }
}