?? audio_44b0x.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 + -