//=========================================================================================== // Function Name: CopyBufferToQueue // // Description: Copy the passed in buffer to the voice render driver queue. // Return the size of bytes has been copied. //==================================================================================== static UInt32 CopyBufferToQueue (VORENDER_Drv_t *audDrv, UInt8 *buf, UInt32 size) { UInt32 copied = 0; AUDQUE_Queue_t *aq = audDrv->audQueue; // write to queue copied = AUDQUE_Write (aq, buf, size); if (copied == size) { // only callback if all data is copied audDrv->bufDoneCb (buf, size, audDrv->drvType); } // if we haven't copied all data, and will copy the left when // we get the next callback. Save the break point. audDrv->srcBuf = buf; audDrv->srcBufSize = size; audDrv->srcBufCopied = copied; Log_DebugPrintf(LOGID_AUDIO, "CopyBufferToQueue :: srcBufCopied = 0x%x, readPtr = 0x%x, writePtr = 0x%x\n", audDrv->srcBufCopied, aq->readPtr, aq->writePtr); // deliver the data to dsp when data is available. if (audDrv->drvType == VORENDER_TYPE_AMRWB) { Log_DebugPrintf(LOGID_AUDIO, "CopyBufferToQueue :: qload=0x%x,writeIndex=0x%x,readIndex=0x%x\n",AUDQUE_GetLoad(aq),arm_writeIndex, dsp_readIndex); ProcessSharedMemRequest (audDrv, arm_writeIndex, dsp_readIndex); } return copied; }
//============================================================================================== // Function Name: AMRWB_Render_TaskEntry // // Description: The main task entry of voice render when using DSP AMRWB decoder //============================================================== static void AMRWB_Render_TaskEntry () { VORENDER_MSG_t msg; OSStatus_t status; VORENDER_Drv_t *audDrv = &sAMRWB_Drv; Log_DebugPrintf(LOGID_AUDIO, "AMRWBRender_TaskEntry: AMRWBRender_TaskEntry is running \r\n"); while(TRUE) { status = OSQUEUE_Pend( audDrv->msgQueue, (QMsg_t *)&msg, TICKS_FOREVER ); if (status == OSSTATUS_SUCCESS) { Log_DebugPrintf(LOGID_AUDIO, " AMRWBRender_TaskEntry::msgID = 0x%x.\n", msg.msgID); switch (msg.msgID) { case VORENDER_MSG_SET_TRANSFER: audDrv->callbackThreshold = (UInt32)msg.parm1; audDrv->interruptInterval = (UInt32)msg.parm2; break; case VORENDER_MSG_CONFIG: ConfigAudDrv (audDrv, (VORENDER_Configure_t *)msg.parm1); break; case VORENDER_MSG_REGISTER_BUFDONE_CB: audDrv->bufDoneCb = (AUDDRV_VoiceRender_BufDoneCB_t)msg.parm1; break; case VORENDER_MSG_START: Log_DebugPrintf(LOGID_AUDIO, " AMRWBRender_TaskEntry::Start render\n"); // Need to reset them, otherwise will use the values from the last play. arm_writeIndex = 0; dsp_readIndex = 0; dspif_AMRWB_play_start ( audDrv->config.playbackMode, audDrv->config.mixMode, audDrv->config.samplingRate, audDrv->config.speechMode, // used by AMRNB and AMRWB audDrv->config.dataRateSelection, // used by AMRNB and AMRWB audDrv->numFramesPerInterrupt); // need to reset sema after start dsp. dsp can send duplicate msgs to us. OSSEMAPHORE_ResetCnt(audDrv->stopDspAmrWbSema); break; case VORENDER_MSG_FINISH: audDrv->isFinishing = TRUE; break; case VORENDER_MSG_STOP: Log_DebugPrintf(LOGID_AUDIO, " AMRWBRender_TaskEntry::Stop render.\n"); dspif_AMRWB_play_init_stop(); //make sure dsp is stopped OSSEMAPHORE_Obtain (audDrv->stopDspAmrWbSema, TICKS_FOREVER); dspif_AMRWB_play_stop(); CheckBufDoneUponStop(audDrv); Log_DebugPrintf(LOGID_AUDIO, " AMRWBRender_TaskEntry::Stop render - done.\n"); OSSEMAPHORE_Release (audDrv->stopSema); break; case VORENDER_MSG_PAUSE: break; case VORENDER_MSG_RESUME: break; case VORENDER_MSG_ADD_BUFFER: CopyBufferToQueue (audDrv, (UInt8 *)msg.parm1, msg.parm2); OSSEMAPHORE_Release (audDrv->addBufSema); break; case VORENDER_MSG_FLUSH_BUFFER: Log_DebugPrintf(LOGID_AUDIO, "AMRWBRender_TaskEntry:: Flushed queue.\n"); // flush the data in the Q AUDQUE_Flush(audDrv->audQueue); // Need to reset them, otherwise will use the values from the last play. arm_writeIndex = 0; dsp_readIndex = 0; // this will make dsp to flush data inside dsp dspif_AMRWB_play_start ( audDrv->config.playbackMode, audDrv->config.mixMode, audDrv->config.samplingRate, audDrv->config.speechMode, // used by AMRNB and AMRWB audDrv->config.dataRateSelection, // used by AMRNB and AMRWB audDrv->numFramesPerInterrupt); // need to reset sema after start dsp. dsp can send duplicate msgs to us. OSSEMAPHORE_ResetCnt(audDrv->stopDspAmrWbSema); break; case VORENDER_MSG_SHM_REQUEST: ProcessSharedMemRequest (audDrv, (UInt16)msg.parm1, (UInt16)msg.parm2); break; default: Log_DebugPrintf(LOGID_AUDIO, "AMRWBRender_TaskEntry: Unsupported msg, msgID = 0x%x \r\n", msg.msgID); break; } } } }
//============================================================================================== // Function Name: ARM2SP_Render_TaskEntry // // Description: The main task entry of voice render when using DSP ARM2SP //============================================================== static void ARM2SP_Render_TaskEntry (void* arg) { VORENDER_MSG_t msg; OSStatus_t status; VORENDER_Drv_t *audDrv = (VORENDER_Drv_t*)arg; /* ARM2SP commands Start: cmd(arg0, arg1=0) Pause: cmd(arg0=0, arg1=1) //ptr not reset Resume w/o fast forward: cmd(arg0, arg1=1) //prt continue Resumd w/ fast forward: cmd(arg0, arg1=0) + arm flush left-over data //same as new play */ Log_DebugPrintf(LOGID_AUDIO, "ARM2SP_Render_TaskEntry: ARM2SP_Render_TaskEntry is running \r\n"); while(TRUE) { status = OSQUEUE_Pend( audDrv->msgQueue, (QMsg_t *)&msg, TICKS_FOREVER ); if (status == OSSTATUS_SUCCESS) { Log_DebugPrintf(LOGID_AUDIO, " ARM2SP_Render_TaskEntry::msgID = 0x%x. parm1 = 0x%x, parm2 = 0x%x\n", msg.msgID, msg.parm1, msg.parm2); switch (msg.msgID) { case VORENDER_MSG_SET_TRANSFER: audDrv->callbackThreshold = (UInt32)msg.parm1; audDrv->interruptInterval = (UInt32)msg.parm2; break; case VORENDER_MSG_CONFIG: ConfigAudDrv (audDrv, (VORENDER_Configure_t *)msg.parm1); break; case VORENDER_MSG_REGISTER_BUFDONE_CB: audDrv->bufDoneCb = (AUDDRV_VoiceRender_BufDoneCB_t)msg.parm1; break; case VORENDER_MSG_START: dspif_ARM2SP_play_start ( AUDDRV_ARM2SP_GetInstanceID(audDrv->drvType), audDrv->config.playbackMode, audDrv->config.mixMode, audDrv->config.samplingRate, audDrv->numFramesPerInterrupt); break; case VORENDER_MSG_FINISH: audDrv->isFinishing = TRUE; break; case VORENDER_MSG_STOP: Log_DebugPrintf(LOGID_AUDIO, " ARM2SP_Render_TaskEntry::Stop render.\n"); dspif_ARM2SP_play_stop(AUDDRV_ARM2SP_GetInstanceID(audDrv->drvType)); CheckBufDoneUponStop(audDrv); OSSEMAPHORE_Release (audDrv->stopSema); break; case VORENDER_MSG_PAUSE: Log_DebugPrintf(LOGID_AUDIO, " ARM2SP_Render_TaskEntry::Pause render.\n"); dspif_ARM2SP_play_pause(AUDDRV_ARM2SP_GetInstanceID(audDrv->drvType)); break; case VORENDER_MSG_RESUME: dspif_ARM2SP_play_resume( AUDDRV_ARM2SP_GetInstanceID(audDrv->drvType), audDrv->config.playbackMode, audDrv->config.mixMode, audDrv->config.samplingRate, audDrv->numFramesPerInterrupt); break; case VORENDER_MSG_ADD_BUFFER: CopyBufferToQueue (audDrv, (UInt8 *)msg.parm1, msg.parm2); OSSEMAPHORE_Release (audDrv->addBufSema); break; case VORENDER_MSG_FLUSH_BUFFER: AUDQUE_Flush(audDrv->audQueue); dspif_ARM2SP_play_flush(AUDDRV_ARM2SP_GetInstanceID(audDrv->drvType)); Log_DebugPrintf(LOGID_AUDIO, "ARM2SP_Render_TaskEntry:: Flushed queue.\n"); break; case VORENDER_MSG_SHM_REQUEST: Log_DebugPrintf(LOGID_AUDIO, "AUDDRV ARM2SP VORENDER_MSG_SHM_REQUEST\n"); ProcessSharedMemRequest (audDrv, (UInt16)msg.parm1, (UInt16)msg.parm2); break; default: Log_DebugPrintf(LOGID_AUDIO, "ARM2SP_Render_TaskEntry: Unsupported msg, msgID = 0x%x \r\n", msg.msgID); break; } } } }
//============================================================================================== // Function Name: VPU_Render_TaskEntry // // Description: The main task entry of voice render when using DSP VPU //============================================================== static void VPU_Render_TaskEntry (void) { VORENDER_MSG_t msg; OSStatus_t status; VORENDER_Drv_t *audDrv = &sVPU_Drv; Log_DebugPrintf(LOGID_AUDIO, "VPU_Render_TaskEntry: VPU_Render_TaskEntry is running \r\n"); while(TRUE) { status = OSQUEUE_Pend( audDrv->msgQueue, (QMsg_t *)&msg, TICKS_FOREVER ); if (status == OSSTATUS_SUCCESS) { Log_DebugPrintf(LOGID_AUDIO, " VPU_Render_TaskEntry::msgID = 0x%x. parm1 = 0x%x, parm2 = 0x%x\n", msg.msgID, msg.parm1, msg.parm2); switch (msg.msgID) { case VORENDER_MSG_SET_TRANSFER: audDrv->callbackThreshold = (UInt32)msg.parm1; audDrv->interruptInterval = (UInt32)msg.parm2; break; case VORENDER_MSG_CONFIG: ConfigAudDrv (audDrv, (VORENDER_Configure_t *)msg.parm1); break; case VORENDER_MSG_REGISTER_BUFDONE_CB: audDrv->bufDoneCb = (AUDDRV_VoiceRender_BufDoneCB_t)msg.parm1; break; case VORENDER_MSG_START: { dspif_VPU_play_start ( audDrv->config.playbackMode, audDrv->config.mixMode, audDrv->config.samplingRate, audDrv->config.speechMode, // used by AMRNB and AMRWB audDrv->config.dataRateSelection, // used by AMRNB and AMRWB audDrv->numFramesPerInterrupt); Log_DebugPrintf(LOGID_AUDIO, " VPU_Render_TaskEntry::Start render, playbackMode = 0x%x, speechMode = 0x%x, dataRate = 0x%x, mixMode = 0x%x\n", audDrv->config.playbackMode, audDrv->config.speechMode, audDrv->config.dataRateSelection, audDrv->config.mixMode); } break; case VORENDER_MSG_FINISH: audDrv->isFinishing = TRUE; break; case VORENDER_MSG_STOP: // stop or cancel, to be consisdered. dspif_VPU_play_stop(); CheckBufDoneUponStop(audDrv); Log_DebugPrintf(LOGID_AUDIO, " VPU_Render_TaskEntry::Stop render.\n"); OSSEMAPHORE_Release (audDrv->stopSema); break; case VORENDER_MSG_PAUSE: break; case VORENDER_MSG_RESUME: break; case VORENDER_MSG_ADD_BUFFER: CopyBufferToQueue (audDrv, (UInt8 *)msg.parm1, msg.parm2); OSSEMAPHORE_Release (audDrv->addBufSema); break; case VORENDER_MSG_FLUSH_BUFFER: AUDQUE_Flush(audDrv->audQueue); Log_DebugPrintf(LOGID_AUDIO, "VPU_Render_TaskEntry:: Flushed queue.\n"); break; case VORENDER_MSG_SHM_REQUEST: ProcessSharedMemRequest (audDrv, (UInt16)msg.parm1, (UInt16)msg.parm2); break; default: Log_DebugPrintf(LOGID_AUDIO, "VPU_Render_TaskEntry: Unsupported msg, msgID = 0x%x \r\n", msg.msgID); break; } } } }
// =================================================================== // // Function Name: AMRWBCapture_TaskEntry // // Description: The main task entry of the voice capture driver when using DSP ARMWB. // // ==================================================================== static void AMRWBCapture_TaskEntry (void) { VOCAPTURE_MSG_t msg; OSStatus_t status; VOCAPTURE_Drv_t *audDrv = &sAMRWB_Drv; Log_DebugPrintf(LOGID_AUDIO, "AMRWBCapture_TaskEntry: AMRWBCapture_TaskEntry is running \r\n"); while(TRUE) { status = OSQUEUE_Pend( audDrv->msgQueue, (QMsg_t *)&msg, TICKS_FOREVER ); if (status == OSSTATUS_SUCCESS) { Log_DebugPrintf(LOGID_AUDIO, " : AMRWBCapture_TaskEntry::msgID = 0x%x.\n", msg.msgID); switch (msg.msgID) { case VOCAPTURE_MSG_SET_TRANSFER: audDrv->callbackThreshold = (UInt32)msg.parm1; audDrv->interruptInterval = (UInt32)msg.parm2; break; case VOCAPTURE_MSG_CONFIG: ConfigAudDrv (audDrv, (VOCAPTURE_Configure_t *)msg.parm1); break; case VOCAPTURE_MSG_REGISTER_BUFDONE_CB: audDrv->bufDoneCb = (AUDDRV_VoiceCapture_BufDoneCB_t)msg.parm1; break; case VOCAPTURE_MSG_START: Log_DebugPrintf(LOGID_AUDIO, " : AMRWBCapture_TaskEntry::Start capture.\n"); dspif_AMRWB_record_start ( audDrv->config.recordMode, audDrv->config.samplingRate, audDrv->config.speechMode, // used by AMRNB and AMRWB audDrv->config.dataRate, // used by AMRNB and AMRWB audDrv->config.procEnable, audDrv->config.dtxEnable, audDrv->numFramesPerInterrupt); break; case VOCAPTURE_MSG_STOP: //which cmd to stop the recording, besides the disable audio cmd (done when disable path)? Log_DebugPrintf(LOGID_AUDIO, " : AMRWBCapture_TaskEntry::Stop capture.\n"); dspif_AMRWB_record_stop(); CheckBufDoneUponStop(audDrv); OSSEMAPHORE_Release (audDrv->stopSema); break; case VOCAPTURE_MSG_PAUSE: break; case VOCAPTURE_MSG_RESUME: break; case VOCAPTURE_MSG_ADD_BUFFER: CopyBufferFromQueue (audDrv, (UInt8 *)msg.parm1, msg.parm2); OSSEMAPHORE_Release (audDrv->addBufSema); break; case VOCAPTURE_MSG_SHM_REQUEST: ProcessSharedMemRequest (audDrv, (UInt16)msg.parm1, (msg.parm2)<<1); break; default: Log_DebugPrintf(LOGID_AUDIO, "AMRWBCapture_TaskEntry: Unsupported msg, msgID = 0x%x \r\n", msg.msgID); break; } } } }