⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio_44b0x.c

📁 基于s3c44b0x(ARM7)的实现mp3播放功能的MP3DECODETEST.rar
💻 C
字号:
#include "44b.h"
#include "def.h"
#include "iis.h"
#include "isr.h"

enum audio_command {
  AUDIO_COMMAND_INIT,
  AUDIO_COMMAND_CONFIG,
  AUDIO_COMMAND_PLAY,
  AUDIO_COMMAND_STOP,
  AUDIO_COMMAND_FINISH
};

struct audio_config {
    enum audio_command command;
    unsigned int channels;
    unsigned int speed;
  } ;
  
enum audio_mode {
  AUDIO_MODE_ROUND,
  AUDIO_MODE_DITHER
};  
  
struct audio_play 
  {
    enum audio_command command;
    unsigned int nsamples;
    signed int const *samples[2];
    enum audio_mode mode;
    struct audio_stats *stats;
  };  

# define MAX_NSAMPLES	(1152 * 3)	/* allow for resampled frame */

static int opened;

# define NSLOTS		25	/* 大约2秒钟数据 (44.1 kHz) */
# define NBUFFERS	 3	/* 3个缓冲区 */

static struct buffer {
  int speed;
  volatile int playing;
  unsigned int pcm_length;
  unsigned char pcm_data[NSLOTS * MAX_NSAMPLES * 2 * 2];
} output[NBUFFERS];

static int bindex;         //要填入数据的缓冲数据索引 0->1->2->0->1....
static int playing_index;  //正在播放的缓冲数据索引0->1->2->0->1....

static c_speed=44100;

int save_intmsk;

//BDMA0中断服务程序
void mp3BDMA0_Done(void)
{
     rI_ISPC=BIT_BDMA0;	//clear pending bit

     output[playing_index].pcm_length=0;	//本缓冲区长度设为0
     output[playing_index].playing=0;		//清除本缓冲区播放标志,以便装放新的数据
     playing_index=(playing_index + 1) % NBUFFERS;	//指到下一个缓冲区
     
     if(output[playing_index].playing==0){rBDICNT0 |= (0<<20);opened=0;return;} //如果没有数据,输出'B'

	 rBDICNT0=(1<<30)+(1<<26)+(3<<22)+(1<<21)+(0<<20)+output[playing_index].pcm_length;   //要播放的长度
        
  	 rBDISRC0=(1<<30)+(1<<28)+(U32)output[playing_index].pcm_data;	//Half word,inc,pWave //把下一个缓冲区地址给BDMA0
	   
     rBDICNT0 |= (1<<20);//enable 
     
}

//======================================================
/********  该函数由解码函数调用   ********/
int mp3_finish()
{  

    rIISCON=0x0;    //IIS stop
    rBDICNT0=0x0;   //BDMA stop    
    
    rINTMSK=save_intmsk | BIT_BDMA0;  //禁止BDMA中断

  return 0;
}
//======================================================
/********  该函数由解码函数调用   ********/

int mp3_stop()
{	
  int i;
 
  rBDICNT0 &=0xffefffff;	//BDMA stop  
  
  opened = 0;  

  for (i = 0; i < NBUFFERS; ++i) 
  {

    output[i].playing    = 0;
    output[i].pcm_length = 0;
  }

  bindex = 0;
  playing_index=0;

  return 0;
}
//***************************************************************************

/********  播放及硬件相关初始化函数   ********/
int init(struct audio_init *init)
{
  
  int i;
  /********  初始化解码后数据缓冲区   ********/
  opened = 0;
  
  for (i = 0; i < NBUFFERS; ++i) 
  {
    output[i].playing    = 0;
    output[i].pcm_length = 0;
  }

  bindex = 0;
  playing_index=0;
  
  /********  初始化中断配置   ********/  
   
  INTS_OFF();       //Disable interrupt in PSR  
  SetISR_Interrupt(INT_BDMA0_OFFSET, mp3BDMA0_Done,0);
  Open_INT_GLOBAL();
  Open_INT(BIT_BDMA0);
  INTS_ON();        //Enable interrupt in PSR     
	
  save_intmsk=rINTMSK;		//保存中断使能

  rIISCON=0;	     //disable;
  /****** IIS 配置的初始化 ******/
  rIISCON=0x03;	//Tx DMA enable,Rx idle,prescaler enable
  rIISMOD=0x8d;	//Master,Tx,L-ch=low,iis,16bit ch.,codeclk=256fs,lrck=32fs
  rIISPSR=0x11;	//Prescaler_A/B enable, value=1
    
  rIISFCON=0xa00;	//Tx/Rx DMA,Tx/Rx FIFO --> start piling....

  /********  初始化音频D/A   ********/
  Init_UDA1341();     //初始化UDA1341
    
  return 0;
}

//======================================================
int config(struct audio_config *config)
{

  c_speed=config->speed;   //  
  
  return 0;
}
//======================================================
/********  IIS和BDMA0配置初始化函数   ********/
void write_dev()
{
  output[bindex].playing=1;
  
  if(opened==0)   //如果第一次播放,初始化BDMA
   {
    opened=1;
    playing_index=bindex;
    
    rBDISRC0=(1<<30)+(1<<28)+(U32)output[playing_index].pcm_data;	//Half word,inc,pWave
    rBDIDES0=(1<<30)+(3<<28)+((U32)rIISFIF);	//M2IO,fix,IISFIF
		
    rBDICNT0=(1<<30)+(1<<26)+(3<<22)+(1<<21)+(0<<20)+output[playing_index].pcm_length;
    rBDICNT0 |= (1<<20);//enable
    rBDCON0 = 0x0<<2;
    rIISCON |=0x1;
  
   	rIISCON  |= 0x20;   //Tx DMA 

   }
}
//======================================================

//解码部分调用该函数进行数据播放
int play(struct audio_play *play)
{
  struct buffer *buffer;
  unsigned int len;

  buffer = &output[bindex];
     
  while(buffer->playing==1);

  /* prepare block */
  
  buffer->speed=c_speed;  

  //回调库函数
  len = audio_pcm_s16le(&buffer->pcm_data[buffer->pcm_length], play->nsamples,
			play->samples[0], play->samples[1], play->mode,	play->stats);

  buffer->pcm_length += len;

  if (buffer->pcm_length + MAX_NSAMPLES * 2 * 2 > sizeof(buffer->pcm_data))
  {
    write_dev();
    bindex = (bindex + 1) % NBUFFERS;    
  }

  return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -