/***************************************************************************** * FUNCTION * gmiTerminate * DESCRIPTION * This function is to handle the terminating state of GMI. *****************************************************************************/ static void gmiTerminate( void *data ) { QTMF_CONTROL = 0; AM_MelodyOff(); gmi.state = GMI_STATE_IDLE; L1Audio_SetEvent( gmi.aud_id, (void*)GMI_END ); }
void wavRecordData( kal_uint32 msgData ) { if(wav.state != WAV_STATE_RECORDING) return; if( wav.ctrl->end_status == MEDIA_TERMINATED) { if( (wav.ctrl->format==MEDIA_FORMAT_WAV_DVI_ADPCM || wav.ctrl->format==MEDIA_FORMAT_WAV_DVI_ADPCM_16K ) && wav.BlockCount != 128 && wav.state == WAV_STATE_IDLE){ L1Audio_SetEvent( wav.aud_id, (void *)0 ); /* zero padding */ } return; } if( (uint8)(wav.tmp_w - wav.tmp_r) < FRAME_BUF_NO ) { wavReadFromFC((int16 *)wav.tmp_buf[wav.tmp_w&FRAME_BUF_MASK], msgData ); wav.tmp_w++; L1Audio_SetEvent( wav.aud_id, (void *)0 ); /* Activate the encoder runing in l1audio task */ } }
static void AVB_HISR(void *data) { kal_brief_trace( TRACE_GROUP_SCO, L1AUDIO_AVB_HISR, AVB.uState, AVB.uSegment_W, AVB.uSegment_R); AVB.uHisrRunning = KAL_TRUE; if(AVB.uState == AVB_STATE_ENDING || AVB.uState == AVB_STATE_IDLE ) { return; } if( *DSP_TONE_CTRL1 != 0 || *DSP_TONE_CTRL2 != 0 ) //playing speech tone, drop one frame { if(AVB.uSegment_W > AVB.uSegment_R) { AVB.uSegment_R++; } } else { kal_uint16 uDSPAddr; kal_int32 i; kal_int16 *pDst, *pSrc; uDSPAddr = *DSP_DM_ADDR(BT_AUDIO_PLAYBACK_SD_PAGE_NUM, BT_AUDIO_PLAYBACK_SD_PTR_ADDR); pDst = (volatile kal_uint16 *)DSP_DM_ADDR(BT_AUDIO_PLAYBACK_SD_PAGE_NUM, uDSPAddr); if(AVB.uSegment_W == AVB.uSegment_R || AVB.fSilence) { //fill silence for(i=AVB_FRAME_SAMPLE-1;i>=0;i--) { *pDst++ = 0; } if(AVB_STATE_FLUSH_PING == AVB.uState) { AVB.uState = AVB_STATE_FLUSH_PONG; } else if(AVB_STATE_FLUSH_PONG == AVB.uState) { AVB.uState = AVB_STATE_ENDING; } } else { //fill data pSrc = AVB.pBuffer + (AVB.uSegment_R & AVB_SEGMENT_MASK) * AVB_FRAME_SAMPLE; for(i=AVB_FRAME_SAMPLE-1;i>=0;i--) { *pDst++ = *pSrc++; } } if(AVB.uSegment_W > AVB.uSegment_R) { AVB.uSegment_R++; } } L1Audio_SetEvent( AVB.uAudID, NULL ); }
void L1Audio_HISR( void ) { uint32 savedMask; L1Audio_Disable_DSPSlowIdle(); if( l1audio.hisrMagicFlag ) { int32 I; kal_uint16 temp; temp = *AUDIO_DBG_SHERIF; for( I = 0; I < MAX_HISR_HANDLER; I++ ) { if( l1audio.hisrMagicFlag & (1<<I) ) { savedMask = SaveAndSetIRQMask(); l1audio.hisrMagicFlag &= ~(1<<I); RestoreIRQMask( savedMask ); kal_brief_trace( TRACE_GROUP_DSPDEBUG, DSPDEBUG_CTRLFLOW, temp, I); l1audio.hisrHandler[I]( l1audio.hisrUserData[I] ); if( l1audio.postHisrHandler != (L1Audio_EventHandler)0 ) l1audio.postHisrHandler( (void*)l1audio.hisrMagicNo[I] ); } } } #if !defined( MED_MODEM ) //special case when MED_MODEM( of MED_PROFILE ) is defined, all Media_Play, Media_record //do not exist, then mediaHisr could be removed to reduce memory size. //In the future, when old interface are not used, mediaHisr should be removed officially. if( l1audio.media_flag != 0 ) { /* Audio File Playback/Recording */ #ifndef __L1_STANDALONE__ // avoid link error mediaHisr( l1audio.media_flag ); #endif if( l1audio.postHisrHandler != (L1Audio_EventHandler)0 ) l1audio.postHisrHandler( (void*)l1audio.media_flag ); l1audio.media_flag = 0; } #endif if( l1audio.event_flag ) { int16 I; for( I = 0; I < MAX_AUDIO_FUNCTIONS; I++ ) { if( l1audio.event_flag & (1<<I) ) { savedMask = SaveAndSetIRQMask(); l1audio.event_flag &= ~(1<<I); RestoreIRQMask( savedMask ); L1Audio_SetEvent( I, l1audio.evData[I] ); } } } // To restore slow idle ctrl for DSP L1Audio_Enable_DSPSlowIdle(); }
static void toneStop( void *data ) { if (tone.state == TONE_STATE_NONE) return; if( !L1Audio_CheckFlag( tone.aud_id ) ) return; if (tone.isReentrance) return; else tone.isReentrance = true; tone.bQTMF = false; if (tone.state == TONE_STATE_INIT) { int I; for (I = 0; ; I++) { if (tone.state != TONE_STATE_INIT) break; ASSERT_REBOOT( I < 20 ); kal_sleep_task( 2 ); } } if (tone.state == TONE_STATE_PLAY) { tone.state = TONE_STATE_STOP; tone.isWait = true; L1Audio_FC_TonePlaybackOff(tone.fc_aud_id); tone.isWait = false; tone.state = TONE_STATE_IDLE; } if (tone.state == TONE_STATE_IDLE) { tone.state = TONE_STATE_NONE; L1Audio_FC_UnHookHandler(tone.fc_aud_id, 0); tone.fc_aud_id = 0xFFFF; } AM_ToneOff(); AFE_TurnOffSpeaker( L1SP_TONE ); L1Audio_ClearFlag( tone.aud_id ); tone.seqNum++; L1Audio_SetEvent( tone.aud_id, 0 ); }
/* * Description * --------- * The function stops the background sound playback of the media handle. * * Syntax * --------- * void BGSND_Stop(); * * where * hdl The media handle * * Return Value * --------- * None */ void BGSND_Stop(void) { kal_trace( TRACE_FUNC, L1SND_ENTER_BGSND_STOP ); /* if ( !L1Audio_CheckFlag( bgSnd.aud_id ) ) return; */ // unregister service // L1SP_UnRegister_BgsService(); bgSnd.state = BGSND_STATE_STOP; // set event to trigger close process L1Audio_SetEvent(bgSnd.aud_id, NULL); }
static void toneLoopBackRecHisr( void ) { #ifndef __L1_STANDALONE__ // avoid link error if(ToneLBR.uState == TLBR_STATE_IDLE) return; if(ToneLBR.uState == TLBR_STATE_INIT){ // skip 1'st frame ToneLBR.uState = TLBR_STATE_REC; return; } if(ToneLBR.uDataCnt < ToneLBR.uSize) { // fill data PCM2WAY_GetFromMic((kal_uint16 *)(ToneLBR.pBuf + ToneLBR.uDataCnt)); ToneLBR.uDataCnt += BYTES_PER_FRAME; }else { // buffer is full L1Audio_SetEvent( ToneLBR.aud_id, (void *)0 ); } #endif // #ifndef __L1_STANDALONE__ }
static void spe_custom_hisr_hdlr(void) { if(spe_custom == NULL) return; if(spe_custom->state != SPE_STATE_WORKING) return; if(spe_custom->buf_read != spe_custom->buf_to_process){ PCM4WAY_PutToSpk((const uint16 *)spe_custom->dl_pcm[spe_custom->buf_read]); PCM4WAY_PutToSE((const uint16 *)spe_custom->ul_pcm[spe_custom->buf_read]); spe_custom->buf_read++; if( spe_custom->buf_read == PCM_BUFFER_NUM ) spe_custom->buf_read = 0; } else { PCM4WAY_FillSpk(0); PCM4WAY_FillSE(0); } PCM4WAY_GetFromSD((uint16 *)spe_custom->dl_pcm[spe_custom->buf_write]); PCM4WAY_GetFromMic((uint16 *)spe_custom->ul_pcm[spe_custom->buf_write]); spe_custom->buf_write++; if( spe_custom->buf_write == PCM_BUFFER_NUM ) spe_custom->buf_write = 0; L1Audio_SetEvent(spe_custom->aud_id, 0); }
void bgsndTimerCallback(void) { L1Audio_SetEvent(bgSnd.aud_id, NULL); }
/***************************************************************************** * FUNCTION * gmiWriteToDSP * DESCRIPTION * This function is the call-back function of GPT for playing notes. *****************************************************************************/ static void gmiWriteToDSP( void *data ) { GMI_Note *note; uint16 I; uint32 curtime; uint32 note_time; uint32 next_time; uint16 rb_count_org; rb_count_org = RB_Count(); curtime = (uint32)(QTMF_COUNTER - gmi.start_time); next_time = curtime; while( !RB_Empty() ) { note = RB_Peek(); note_time = gmi.note_time + note->delta_time; if( note_time > next_time ) { next_time = note_time; } else if( note_time < curtime ) { RB_Consume(); gmi.note_time = note_time; continue; } /* search for the first available DSP tone */ for( I = 0; I < MAX_DPRAM_BUFFER; I++ ) { #if defined(MT6205) if( QTMF_DURA(I) == 0 && gmi.dsp_time[I] <= note_time ) { #else if( QTMF_DURA(I) == 0 ) { #endif QTMF_FREQ(I) = Pitch2Frequency[ note->pitch ]; QTMF_AMP(I) = (uint16)note->amplitude; QTMF_DURA(I) = note->duration << 4; /* QTMF_DURA(I) = (note->duration << 4) + ((note->timbre >> 3) & 0x0F ); */ QTMF_TIME(I) = (uint16)note_time + gmi.start_time; gmi.dsp_time[I] = note_time + note->duration; if( gmi.end_time < gmi.dsp_time[I] ) gmi.end_time = gmi.dsp_time[I]; RB_Consume(); gmi.note_time = note_time; break; } } if( I == MAX_DPRAM_BUFFER ) break; } switch( gmi.state ) { case GMI_STATE_INIT: QTMF_CONTROL = 3; gmi.state = GMI_STATE_PLAY; break; case GMI_STATE_PLAY: if( rb_count_org >= GMI_RB_SIZE/2 && RB_Count() < GMI_RB_SIZE/2 ) L1Audio_SetEvent( gmi.aud_id, (void*)GMI_NOTE_REQUEST ); if( gmi.eof_flag ) gmi.state = GMI_STATE_DATA_COMPLETE; break; case GMI_STATE_DATA_COMPLETE: if( RB_Empty() ) { GPTI_StartItem( gmi.gpt, (gmi.end_time - curtime + 5) * 2, gmiTerminate, 0 ); return; } break; } if( next_time > curtime ) next_time = next_time - curtime; else next_time = 1; GPTI_StartItem( gmi.gpt, next_time, gmiWriteToDSP, 0 ); } /***************************************************************************** * FUNCTION * GMI_Play * DESCRIPTION * This function is used to start melody playing. * * PARAMETERS * gmi_handler - a call back function used to be notified an event that * the end of a song is reached. *****************************************************************************/ void GMI_Play( void (*gmi_handler)( GMI_Event event ) ) { int16 I; if( L1Audio_CheckFlag( gmi.aud_id ) ) return; if( gmi_handler == 0 ) return; if( gmi.state != GMI_STATE_IDLE ) return; L1Audio_SetFlag( gmi.aud_id ); GPTI_StopItem( gmi.gpt ); for( I = 0; I < MAX_DPRAM_BUFFER; I++ ) { gmi.dsp_time[I] = 0; QTMF_DURA(I) = 0; } gmi.rb_head = 0; gmi.rb_tail = 0; gmi.mmi_time = 0; gmi.start_time = QTMF_COUNTER; gmi.end_time = 0; gmi.state = GMI_STATE_INIT; gmi.note_time = 0; gmi.eof_flag = false; gmi.gmi_handler = gmi_handler; gmi.gmi_handler( GMI_NOTE_REQUEST ); AM_MelodyOn(); gmiWriteToDSP( 0 ); } /* end of gmiPlay */