示例#1
0
文件: test.c 项目: yallawalla/stm32
/**
* @brief  Calculates the remaining file size and new position of the pointer.
* @param  None
* @retval None
*/
void EVAL_AUDIO_TransferComplete_CallBack(uint32_t pBuffer, uint32_t Size)
{
  /* Calculate the remaining audio data in the file and the new size 
  for the DMA transfer. If the Audio files size is less than the DMA max 
  data transfer size, so there is no calculation to be done, just restart 
  from the beginning of the file ... */
  /* Check if the end of file has been reached */
  
#ifdef AUDIO_MAL_MODE_NORMAL  
  
#if defined MEDIA_IntFLASH

#if defined PLAY_REPEAT_OFF
  LED_Toggle = 4;
  RepeatState = 1;
  EVAL_AUDIO_Stop(CODEC_PDWN_HW);
#else
  /* Replay from the beginning */
  AudioFlashPlay((uint16_t*)(AUDIO_SAMPLE + AUIDO_START_ADDRESS),AUDIO_FILE_SZE,AUIDO_START_ADDRESS);
#endif  
  
#elif defined MEDIA_USB_KEY  
  XferCplt = 1;
  if (WaveDataLength) WaveDataLength -= _MAX_SS;
  if (WaveDataLength < _MAX_SS) WaveDataLength = 0;
    
#endif 
    
#else /* #ifdef AUDIO_MAL_MODE_CIRCULAR */
  
  
#endif /* AUDIO_MAL_MODE_CIRCULAR */
}
示例#2
0
/**
  * @brief  EXTI0_IRQHandler
  *         This function handles External line 0 interrupt request.
  * @param  None
  * @retval None
  */
void EXTI0_IRQHandler(void)
{
  /* Checks whether the User Button EXTI line is asserted*/
  if (EXTI_GetITStatus(EXTI_Line0) != RESET) 
  { 
    if (Command_index == 1)
    {
      RepeatState = 0;
      /* Switch to play command */
      Command_index = 0;
    }
    else if (Command_index == 0)
    {
      /* Switch to record command */
      Command_index = 1;
      XferCplt = 1;
      EVAL_AUDIO_Stop(CODEC_PDWN_SW);
    }
    else
    {
      RepeatState = 0;
      /* Switch to play command */
      Command_index = 0; 
    }
  } 
  /* Clears the EXTI's line pending bit.*/ 
  EXTI_ClearITPendingBit(EXTI_Line0);
}
/**
 * @brief  Reset the wave player
 * @param  None
 * @retval None
 */
void WavePlayer_CallBack(void)
{
  /* Reset the wave player variables */
  RepeatState = 0;
  AudioPlayStart =0;
  LED_Toggle = 7;
  PauseResumeStatus = 1;
  WaveDataLength =0;
  Count = 0;

  /* Stops the codec */
  EVAL_AUDIO_Stop(CODEC_PDWN_HW);
  /* LED off */
  STM_EVAL_LEDOff(LED3);
  STM_EVAL_LEDOff(LED4);
  STM_EVAL_LEDOff(LED6);

  /* TIM Interrupts disable */
  TIM_ITConfig(TIM4, TIM_IT_CC1, DISABLE);
  f_mount(0, NULL);
} 
/**
  * @brief  AudioCmd 
  *         Play, Stop, Pause or Resume current file.
  * @param  pbuf: address from which file shoud be played.
  * @param  size: size of the current buffer/file.
  * @param  cmd: command to be executed, can be AUDIO_CMD_PLAY , AUDIO_CMD_PAUSE, 
  *              AUDIO_CMD_RESUME or AUDIO_CMD_STOP.
  * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
  */
static uint8_t  AudioCmd(uint8_t* pbuf, 
                         uint32_t size,
                         uint8_t cmd)
{
  /* Check the current state */
  if ((AudioState == AUDIO_STATE_INACTIVE) || (AudioState == AUDIO_STATE_ERROR))
  {
    AudioState = AUDIO_STATE_ERROR;
    return AUDIO_FAIL;
  }
  
  switch (cmd)
  {
    /* Process the PLAY command ----------------------------*/
  case AUDIO_CMD_PLAY:
    /* If current state is Active or Stopped */
    if ((AudioState == AUDIO_STATE_ACTIVE) || \
       (AudioState == AUDIO_STATE_STOPPED) || \
       (AudioState == AUDIO_STATE_PLAYING))
    {
      Audio_MAL_Play((uint32_t)pbuf, (size/2));
      AudioState = AUDIO_STATE_PLAYING;
      return AUDIO_OK;
    }
    /* If current state is Paused */
    else if (AudioState == AUDIO_STATE_PAUSED)
    {
      if (EVAL_AUDIO_PauseResume(AUDIO_RESUME /*, (uint32_t)pbuf, (size/2)*/) != 0)
      {
        AudioState = AUDIO_STATE_ERROR;
        return AUDIO_FAIL;
      }
      else
      {
        AudioState = AUDIO_STATE_PLAYING;
        return AUDIO_OK;
      } 
    } 
    else /* Not allowed command */
    {
      return AUDIO_FAIL;
    }
    
    /* Process the STOP command ----------------------------*/
  case AUDIO_CMD_STOP:
    if (AudioState != AUDIO_STATE_PLAYING)
    {
      /* Unsupported command */
      return AUDIO_FAIL;
    }
    else if (EVAL_AUDIO_Stop(CODEC_PDWN_SW) != 0)
    {
      AudioState = AUDIO_STATE_ERROR;
      return AUDIO_FAIL;
    }
    else
    {
      AudioState = AUDIO_STATE_STOPPED;
      return AUDIO_OK;
    }
  
    /* Process the PAUSE command ---------------------------*/
  case AUDIO_CMD_PAUSE:
    if (AudioState != AUDIO_STATE_PLAYING)
    {
      /* Unsupported command */
      return AUDIO_FAIL;
    }
    else if (EVAL_AUDIO_PauseResume(AUDIO_PAUSE /*, (uint32_t)pbuf, (size/2)*/) != 0)
    {
      AudioState = AUDIO_STATE_ERROR;
      return AUDIO_FAIL;
    }
    else
    {
      AudioState = AUDIO_STATE_PAUSED;
      return AUDIO_OK;
    } 
    
    /* Unsupported command ---------------------------------*/
  default:
    return AUDIO_FAIL;
  }  
}
void AudioTask ( void * pvParameters )
{
	struct AAudioCommandMessage CmdMsg;
	uint8_t rc = 0;
	FRESULT res;
	uint8_t pausing = 0;

	xAudioQueue = xQueueCreate ( 8, sizeof ( char ) );

	res = f_mount ( &FatFs, "", 1 ); // mount the drive
	if ( res )
	{
		led_state[0] = LED_STATE_BLINK_FAST;
		while ( 1 );
	}

	while ( 1 )
	{
		if ( xQueueReceive ( xAudioQueue, &CmdMsg, portMAX_DELAY ) )
		{
			switch ( CmdMsg.Command )
			{
			case 'h': // half transfer complete
				break;
			case 't': // transfer complete
				if ( audioContext.lastFrame )
				{
					EVAL_AUDIO_Stop ( CODEC_PDWN_SW );
				}
				else
				{
					AudioProvideSamplesFromFile ( );
				}
				break;
			case 'p': // play file
				rc = AudioStartPlayFile ( CmdMsg.sFilename );
				switch ( rc )
				{
					case 0:
						led_state[1] = LED_STATE_OFF;
						led_state[2] = LED_STATE_OFF;
						break;

					case 1:
						led_state[1] = LED_STATE_BLINK_FAST;
						break;

					case 2:
						led_state[2] = LED_STATE_BLINK_FAST;
						break;
				}
				break;
			case 'r': // pause/resume
				EVAL_AUDIO_PauseResume ( pausing ? AUDIO_RESUME : AUDIO_PAUSE );
				pausing ^= pausing;
				break;
			case 's': // stop playback
				EVAL_AUDIO_Stop ( CODEC_PDWN_SW );
				break;
			case 'v': // set volume
				break;
			case '+': // volume up
				break;
			case '-': // volume down
				break;
			case 'n': // next file
				break;
			case 'l': // last file
				break;
			};
		};
	};
};
/**
 * @brief  Stop playing wave
 * @param  None
 * @retval None
 */
void WavePlayerStop(void)
{ 
  EVAL_AUDIO_Stop(CODEC_PDWN_SW);
}
示例#7
0
文件: main.c 项目: ADTL/ARMWork
int Mp3Decode(const char* pszFile)
{
  int nResult = 0;
  BYTE* pInData = g_Mp3InBuffer;
  UINT unInDataLeft = 0;
  FIL fIn;
  UINT bEof = FALSE;
  UINT bOutOfData = FALSE;
  MP3FrameInfo mp3FrameInfo;
  uint32_t unDmaBufMode = 0;
  g_pMp3DmaBufferPtr = g_pMp3DmaBuffer;
  g_pMp3DecoderThread = chThdSelf();

  FRESULT errFS = f_open(&fIn, pszFile, FA_READ);
  if(errFS != FR_OK)
  {
    chprintf((BaseChannel*)&SD2, "Mp3Decode: Failed to open file \"%s\" for reading, err=%d\r\n", pszFile, errFS);
    return -1;
  }

  HMP3Decoder hMP3Decoder = MP3InitDecoder();
  if(hMP3Decoder == NULL)
  {
    chprintf((BaseChannel*)&SD2, "Mp3Decode: Failed to initialize mp3 decoder engine\r\n");
    return -2;
  }

  chprintf((BaseChannel*)&SD2, "Mp3Decode: Start decoding \"%s\"\r\n", pszFile);

  char szArtist[80];
  char szTitle[80];
  palSetPad(GPIOD, 12); // green LED
  Mp3ReadId3V2Tag(&fIn, szArtist, sizeof(szArtist), szTitle, sizeof(szTitle));
  palClearPad(GPIOD, 12); // green LED
  if(szArtist[0] != 0 || szTitle[0] != 0)
  {
    chprintf((BaseChannel*)&SD2, "Mp3Decode: Now playing (ID3v2): %s - %s\r\n", szArtist, szTitle);
  }
  int nDecodeRes = ERR_MP3_NONE;
  UINT unFramesDecoded = 0;
  do
  {
    if(unInDataLeft < (2 * MAINBUF_SIZE) && (!bEof))
    {
      UINT unRead = Mp3FillReadBuffer(pInData, unInDataLeft, &fIn);
      unInDataLeft += unRead;
      pInData = g_Mp3InBuffer;
      if(unRead == 0)
      {
        bEof = 1;
      }
    }

    // find start of next MP3 frame - assume EOF if no sync found
    int nOffset = MP3FindSyncWord(pInData, unInDataLeft);
    if(nOffset < 0)
    {
      bOutOfData = TRUE;
      break;
    }
    pInData += nOffset;
    unInDataLeft -= nOffset;

    // decode one MP3 frame - if offset < 0 then bytesLeft was less than a full frame
    nDecodeRes = MP3Decode(hMP3Decoder, &pInData, (int*)&unInDataLeft, (short*)g_pMp3OutBuffer, 0);
    switch(nDecodeRes)
    {
      case ERR_MP3_NONE:
      {
        MP3GetLastFrameInfo(hMP3Decoder, &mp3FrameInfo);
        if(unFramesDecoded == 0)
        {
          chprintf((BaseChannel*)&SD2, "Mp3Decode: %d Hz %d Bit %d Channels\r\n",
                   mp3FrameInfo.samprate, mp3FrameInfo.bitsPerSample, mp3FrameInfo.nChans);
          if((mp3FrameInfo.samprate > 48000) || (mp3FrameInfo.bitsPerSample != 16) || (mp3FrameInfo.nChans != 2))
          {
            chprintf((BaseChannel*)&SD2, "Mp3Decode: incompatible MP3 file.\r\n");
            nResult = -5;
            break;
          }
        }
        if((unFramesDecoded) % 100 == 0)
        {
          chprintf((BaseChannel*)&SD2, "Mp3Decode: frame %u, bitrate=%d\r\n", unFramesDecoded, mp3FrameInfo.bitrate);
        }
        unFramesDecoded++;
        g_pMp3OutBufferPtr = g_pMp3OutBuffer;

        uint32_t unOutBufferAvail= mp3FrameInfo.outputSamps;
        while(unOutBufferAvail > 0)
        {
          // fill up the whole dma buffer
          uint32_t unDmaBufferSpace = 0;
          if(unDmaBufMode == 0)
          {
            // fill the whole buffer
            // dma buf ptr was reset to beginning of the buffer
            unDmaBufferSpace = g_pMp3DmaBuffer + MP3_DMA_BUFFER_SIZE - g_pMp3DmaBufferPtr;
          }
          else if(unDmaBufMode == 1)
          {
            // fill the first half of the buffer
            // dma buf ptr was reset to beginning of the buffer
            unDmaBufferSpace = g_pMp3DmaBuffer + (MP3_DMA_BUFFER_SIZE / 2) - g_pMp3DmaBufferPtr;
          }
          else
          {
            // fill the last half of the buffer
            // dma buf ptr was reset to middle of the buffer
            unDmaBufferSpace = g_pMp3DmaBuffer + MP3_DMA_BUFFER_SIZE - g_pMp3DmaBufferPtr;
          }
          uint32_t unCopy = unDmaBufferSpace > unOutBufferAvail ? unOutBufferAvail : unDmaBufferSpace;
          if(unCopy > 0)
          {
            memcpy(g_pMp3DmaBufferPtr, g_pMp3OutBufferPtr, unCopy * sizeof(uint16_t));
            unOutBufferAvail -= unCopy;
            g_pMp3OutBufferPtr += unCopy;
            unDmaBufferSpace -= unCopy;
            g_pMp3DmaBufferPtr += unCopy;
          }
          if(unDmaBufferSpace == 0)
          {
            // dma buffer full
            // see if this was the first run
            if(unDmaBufMode == 0)
            {
              // on the first buffer fill up,
              // start the dma transfer
              if(EVAL_AUDIO_Init(OUTPUT_DEVICE_HEADPHONE, 80, (uint32_t)mp3FrameInfo.samprate))
              {
                chprintf((BaseChannel *) &SD2, "Mp3Decode: audio init failed\r\n");
                nResult = -4;
                break;
              }
              EVAL_AUDIO_Play(g_pMp3DmaBuffer, MP3_DMA_BUFFER_SIZE * sizeof(uint16_t));
            }
            // we must wait for the dma stream tx interrupt here
            eventmask_t em = chEvtWaitAny((eventmask_t)2 | 4 | 8);
            if(em & 8)
            {
              // stop requested
              chprintf((BaseChannel*)&SD2, "Mp3Decode: Stop requested\r\n");
              nResult = 1;
              break;
            }
            if((em & 2) && (em & 4))
            {
              chprintf((BaseChannel*)&SD2, "Mp3Decode: DMA out of sync (HT and TC both set)\r\n");
              nResult = -3;
              break;
            }
            if(unDmaBufMode == 0 || unDmaBufMode == 2)
            {
              // the dma event we expect is "half transfer" (=2)
              if(em & 2)
              {
                // set up first half mode
                unDmaBufMode = 1;
                g_pMp3DmaBufferPtr = g_pMp3DmaBuffer;
              }
              else
              {
                chprintf((BaseChannel*)&SD2, "Mp3Decode: DMA out of sync (expected HT, got TC)\r\n");
                nResult = -3;
                break;
              }
            }
            else
            {
              // the dma event we expect is "transfer complete" (=4)
              if(em & 4)
              {
                // set up last half mode
                unDmaBufMode = 2;
                g_pMp3DmaBufferPtr = g_pMp3DmaBuffer + (MP3_DMA_BUFFER_SIZE / 2);
              }
              else
              {
                chprintf((BaseChannel*)&SD2, "Mp3Decode: DMA out of sync (expected TC, got HT)\r\n");
                nResult = -3;
              }
            }
          }
        }
        break;
      }
      case ERR_MP3_MAINDATA_UNDERFLOW:
      {
        // do nothing - next call to decode will provide more mainData
        break;
      }
      case ERR_MP3_FREE_BITRATE_SYNC:
      {
        break;
      }
      case ERR_MP3_INDATA_UNDERFLOW:
      {
        chprintf((BaseChannel*)&SD2, "Mp3Decode: Decoding error ERR_MP3_INDATA_UNDERFLOW\r\n");
        bOutOfData = TRUE;
        break;
      }
      default:
      {
        chprintf((BaseChannel*)&SD2, "Mp3Decode: Decoding error %d\r\n", nDecodeRes);
        bOutOfData = TRUE;
        break;
      }
    }
  }
  while((!bOutOfData) && (nResult == 0));

  chprintf((BaseChannel*)&SD2, "Mp3Decode: Finished decoding\r\n");

  MP3FreeDecoder(hMP3Decoder);
  if(EVAL_AUDIO_Stop(CODEC_PDWN_HW))
  {
    chprintf((BaseChannel*)&SD2, "Mp3Decode: Failed to stop audio\r\n");
  }
  EVAL_AUDIO_DeInit();
  f_close(&fIn);
  // this is the only legit way I know
  // to remvove still pending event flags
  // from the thread
  chEvtWaitOneTimeout(2, 50);
  chEvtWaitOneTimeout(4, 50);

  return nResult;
}
示例#8
0
/**
  * @brief  Main program.
  * @param  None
  * @retval None
*/
int main(void)
{
  /* Initialize LEDS */
  /* Red Led On: buffer overflow */
  STM_EVAL_LEDInit(LED3);
  /* Green Led On: fdmdv+codec2 enabled */
  STM_EVAL_LEDInit(LED4);
  STM_EVAL_LEDInit(LED5);
  /* Blue Led On: start of application */
  STM_EVAL_LEDInit(LED6);

  STM_EVAL_LEDOn(LED6);

  /* transparent mode switcher */
  STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI);

  if(Transparent_mode)
	  STM_EVAL_LEDOff(LED4);
  else
	  STM_EVAL_LEDOn(LED4);

  /* SysTick end of count event each 10ms */
  RCC_GetClocksFreq(&RCC_Clocks);
  SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);

  USART_InitTypeDef USART_InitStructure;
  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  STM_EVAL_USART2Init(&USART_InitStructure);

  // turn off buffers, so IO occurs immediately
  setvbuf(stdin, NULL, _IONBF, 0);
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);

  /* Output a message on Hyperterminal using printf function */
  printf("\r\nFloating-Point Based Codec2 encoder for Cortex-M4F\r\n");
  /* Configure TIM4 Peripheral to manage LEDs lighting */

  unsigned int idx = 0;
  Time_Rec_Base=0;
  int i, buffId;

  codec2_initialize_all(SPEAKER_FREQ == 48000 ? 1 : 0);

  /* fill output fifo */
  fifoBufferFullness=0;
  fifoBufferCurrent=0;
  Switch = 0;

  /* modulate silence once for padding if happens */
  memset(padBuffer, 0x00, (320*(SPEAKER_FREQ/MIC_FREQ)*2)*sizeof(short));
  memset(fifoBuffer, 0x00, MODULATOR_QUEUE_SIZE * (SPEAKER_FREQ/MIC_FREQ)*320*2*sizeof(short));
  //codec2_modulate((short *) padBuffer, (short *) padBuffer, Transparent_mode);

  /* Initialize I2S interface */
  EVAL_AUDIO_SetAudioInterface(AUDIO_INTERFACE_I2S);
  /* Initialize the Audio codec and all related peripherals (I2S, I2C, IOExpander, IOs...) */
  //EVAL_AUDIO_Init(OUTPUT_DEVICE_AUTO, 0, SPEAKER_FREQ);
  EVAL_AUDIO_Init(OUTPUT_DEVICE_AUTO, 0, SPEAKER_FREQ);
  EVAL_AUDIO_PauseResume(AUDIO_PAUSE);
  Audio_MAL_Play((uint32_t) padBuffer, (320*(SPEAKER_FREQ/MIC_FREQ))*2*sizeof(short));
  EVAL_AUDIO_PauseResume(AUDIO_RESUME);

  /* Start the record */
  MicListenerInit(32000,16, 1);
  MicListenerStart(RecBuf_8Khz, PCM_OUT_SIZE);

  /* GLOBAL SCHEDULER
   * DO NOT USE LOOPS INSIDE IT!
   * */
  while(1) {
	  /* we have frame from mike */
	  if(Data_Status == 0)
		  continue;

	  /* Switch the buffers*/
	  if (Switch ==1) {
		pAudioRecBuf_8Khz = RecBuf_8Khz;
		writebuffer = RecBuf1_8Khz;
		Switch = 0;
	  } else {
		pAudioRecBuf_8Khz = RecBuf1_8Khz;
		writebuffer = RecBuf_8Khz;
		Switch = 1;
	  }

#ifdef USE_ST_FILTER
	  //Downsampling 16Khz => 8Khz (this is input for codec, it sampled with 8KHz)
	  for(i=0; i<320; i++)
	      writebuffer[i] = writebuffer[2*i];
#endif

	  //TODO: modulate, even if no data from mike!
	  if(fifoBufferFullness < MODULATOR_QUEUE_SIZE-1) {
		  /* get the next free buffer */
		  buffId = fifoBufferCurrent + fifoBufferFullness;
		  if(buffId >= MODULATOR_QUEUE_SIZE) buffId -= MODULATOR_QUEUE_SIZE;
		  assert(buffId >= 0 && buffId < MODULATOR_QUEUE_SIZE);
		  codec2_modulate((short *) writebuffer, (short *) fifoBuffer[buffId], Transparent_mode);
		  fifoBufferFullness++;
		  if(idx % 32 == 0) printf(".");
		  if(idx % (32*32) == 0) printf("\r\n");

		  /* this is hack to remove loud noise at startup */
		  if(volume_set==1) {
			  STM_EVAL_LEDOff(LED3);
			  EVAL_AUDIO_VolumeCtl(90);
			  volume_set=2;
		  }
	  } else {
		  STM_EVAL_LEDToggle(LED3);
		  printf("x");
		  if(idx % (32) == 0) printf("\r\n");
	  }

	  idx++;
      Data_Status = 0;
  }

  EVAL_AUDIO_Mute(AUDIO_MUTE_ON);
  EVAL_AUDIO_Stop(CODEC_PDWN_HW);
  MicListenerStop();

  //float samples_time = idx*samplesPerFrame/((float) WAVE_Format.NumChannels*WAVE_Format.SampleRate);
#if 0
  float samples_time = idx*mod->samplesPerFrame/((float) 1*MIC_FREQ);
  float cpu_time = Time_Rec_Base/((float ) 100);
  printf("\r\n%8.3f s audio file encoded in %8.3f s\r\n", (double) samples_time, (double) cpu_time);
#endif
  while(1) {
	STM_EVAL_LEDToggle(LED5);
    Delay(10);
  }
}