S3C2440A的Inter-IC Sound(IIS)總線接口作為一個編解碼接口連接外部8/16位立體聲音頻解碼IC用于迷你碟機和可攜式應用。IIS總線接口支持IIS總線數據格式和MSB-justified數據格式。該接口對FIFO的訪問采用了DMA模式取代了中斷。它可以在同一時間接受和發送數據。S3C2440一共有5個引腳用于IIS:IISDO,IISDI,IISSCLK,IISLRCK和CDCLK。前兩個信號用于數字音頻信號的輸入輸出,另外3個引腳都與音頻信號的頻率有關,可見要用好IIS,就要把信號頻率設置正確。IISSCLK為串行時鐘,每一個時鐘信號傳送一位音頻信號,因此IISSCLK的頻率=聲道數*采樣頻率*采樣位數,如采樣頻率為44.1kHz,采樣的位數為16位,聲道數2個(左,右兩個聲道),則IISSCLK的頻率=32fs=1411.2kHz。IISLRCK為幀時鐘,用于切換左右聲道,如IISLRCK為高電平表示正在傳輸的是左聲道數據,為低表示傳輸的是右聲道數據。因此IISLRCK的頻率應該正好等于采樣頻率。由于IIS只負責數字音頻信號的傳輸,而要真正實現音頻信號的放錄還需要額外的處理芯片(在這里我們使用UDA1341),CDCLK為該芯片提供系統同步時鐘,即編解碼時鐘,主要用于音頻的A/D,D/A采樣時的采樣時鐘,一般CDCLK為256fs或384fs。UDA1341使用L3接口,通過L3接口可以實現UDA1341和S3C2440控制信息的傳遞。L3指3根線,L3DATA(數據線,用于傳輸數據),L3MODE(模式線,用于選擇模式),L3CLOCK(時鐘線,用于傳輸時鐘)。先傳輸地址模式數據,再傳輸數據模式數據。L3MODE為低時是地址模式,L3MODE為高時是數據傳輸模式。L3DATA和L3CLOCK相互作用,完成8位數據的傳輸,傳輸的順序是先低位數據,再高位數據。地址模式用于選擇設備和定義目標寄存器,在這種模式下,8位數據的含義是:高6位是設備地址(UDA1341的地址為000101),低兩位是后面數據模式的類型(00:DATA0,01:DATA1,10:STATUS)。 下面這個程序完成從WAV音頻文件中提取出數組。 #include <stdio.h> #include<stdlib.h> #include <string.h> #include <memory.h> int main(){ FILE *stream, *fp; unsigned char *music; char ch[5]; int start, end, num, t, i, j, r; if(((stream = fopen("D:\\music.wav","rb")) == NULL) || ((fp = fopen("D:\\music.h","wb+")) == NULL)){ printf("%s","cannot open output file.\n"); return 1; } fseek(stream,0,SEEK_SET); start = ftell(stream); //獲得文件的起始地址 fseek(stream,0,SEEK_END); end = ftell(stream); //獲得文件的結束地址 fseek(stream,0,SEEK_SET); music = (unsigned char *)malloc(end-start); //動態分配一個buffer fwrite("unsigned char music[",1,20,fp); fwrite("]={",1,3,fp); fwrite("\n", 2, 1, fp); num = (end - start - 0x2c) / 16; //m每行16個 t = (end - start - 0x2c) % 16; fread(music, 1, end - start, stream); for(i = 0; i < num; i++){ for(j = 0; j < 16; j++){ memset(ch,0,5); r = (int)music[i*16+j+0x2c]; //從0x2c開始是音頻數據 r &= 0xff; sprintf(ch,"0x%02x",r); //先轉化成一定格式 fwrite(ch,sizeof(ch),1,fp); fwrite(",",1,1,fp); } fwrite("\n",1,2,fp); } for(i = 0; i < t; i++){ memset(ch,0,5); r = (int)music[i*16+j+0x2c]; r &= 0xff; sprintf(ch,"0x%02x",r); fwrite(ch,sizeof(ch),1,fp); if(i != t-1) fwrite(",",1,1,fp); } fwrite("};",1,2,fp); fclose(stream); fclose(fp); system("pause"); return 0; } 完成音頻文件的播放。IISFIFO為16位寬,深度為32。將音頻數組中的數據裝入IISFIFO,裝滿后IIS讀取IISFIFO中的數據,即放音,然后再將音頻數組中的數據讀入IISFIFO,周而復始,完成放音。 #include "2440addr.h" #include "music.h" #define L3MODE 1<<2 #define L3DATA 1<<3 #define L3CLOCK 1<<4 void WriteL3(unsigned char data, unsigned int mode){ //mode = 0,地址模式;mode = 1,數據傳輸模式 int i, k; if(mode == 0){ rGPBDAT = rGPBDAT & "(L3MODE|L3DATA|L3CLOCK )|L3CLOCK; } else{ rGPBDAT = rGPBDAT & "(L3MODE|L3DATA|L3CLOCK)|(L3CLOCK|L3MODE); } for(k = 0; k < 5; k++) ; for(i = 0; i < 8; i++){ if(data & 0x1){ rGPBDAT &= "L3CLOCK; rGPBDAT |= L3DATA; for(k = 0; k < 5; k++) ; rGPBDAT |= L3CLOCK; rGPBDAT |= L3DATA; for(k = 0; k < 5; k++) ; } else{ rGPBDAT &= "L3CLOCK; rGPBDAT &= "L3DATA; for(k = 0; k < 5; k++) ; rGPBDAT |= L3CLOCK; rGPBDAT &= "L3DATA; for(k = 0; k < 5; k++) ; } data >>= 1; } rGPBDAT = rGPBDAT & "(L3MODE|L3DATA|L3CLOCK)|(L3CLOCK|L3MODE); } void PlayMusic(unsigned char buffer[], unsigned int length){ int i, fifo; //UDA1341 //STATUS模式 rGPBDAT = rGPBDAT & "(L3MODE|L3DATA|L3CLOCK)|(L3CLOCK|L3MODE); WriteL3(0x14+2,0); //復位 WriteL3(0x60,1); WriteL3(0x14+2,0); //00010000 系統時鐘頻率384fs WriteL3(0x10,1); WriteL3(0x14+2,0); //11000001 輸出增益,ADC關,DAC開 WriteL3(0xc1,1); //IIS //DMA禁止,在接受空閑狀態,不產生IISLRCK信號,IIS預分頻使能 rIISCON = (0<<5)|(0<<4)|(0<<3)|(1<<2)|(1<<1); //主設備時鐘PCLK,主設備模式,發送模式,串行數據16位,主時鐘是384fs,串行位時鐘32fs rIISMOD = (0<<9)|(0<<8)|(2<<6)|(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<0); //預分頻都是N=3 rIISPSR = (3<<5)|3; //發送FIFO正常,發送FIFO使能 rIISFCON = (0<<15)|(1<<13); //IIS start rIISCON |= 0x1; for(fifo = 0; fifo <= length; fifo += 64){ while(rIISCON &(1<<7)); for(i = 0; i < 32; i++) rIISFIFO = (buffer[i*2+fifo]) + (buffer[i*2+1+fifo]<<8); } //IIS close rIISCON = 0x0; } int Main(){ rGPBUP = rGPBUP & "(0x7<<2) | (0x7<<2); //The pull up function is disabled GPB[4:2] 1 1100 rGPBCON = rGPBCON & "(0x3f<<4) | (0x15<<4); //GPB[4:2]=Output(L3CLOCK):Output(L3DATA):Output(L3MODE) rGPBDAT = 0x1ec; rGPEUP = rGPEUP & "(0x1f) | 0x1f; //The pull up function is disabled GPE[4:0] 1 1111 rGPECON = rGPECON & "(0x3ff) | 0x2aa; //GPE[4:0]=I2SSDO:I2SSDI:CDCLK:I2SSCLK:I2SLRCK rMPLLCON = (150<<12)|(5<<4)|(0<<0); PlayMusic(music, sizeof(music)); while(1); return 0; } 作者:李萬鵬 |
你好,關于你那個提取音頻文件那個函數,你在下面怎么沒有用到啊?? 既然你已經提取了數組,怎么還需要#include "music.h" 這個呢??這個是用軟件取的數組吧??求解釋啊。。。。。 |