예제 #1
0
파일: gmi.c 프로젝트: 12019/mtktest
/*****************************************************************************
* 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 */
   }
}
예제 #3
0
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 );
}
예제 #4
0
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 );
}
예제 #6
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__
}
예제 #8
0
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);
}
예제 #9
0
void bgsndTimerCallback(void)
{
	L1Audio_SetEvent(bgSnd.aud_id, NULL);
}
예제 #10
0
파일: gmi.c 프로젝트: 12019/mtktest
/*****************************************************************************
* 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 */