パラメータを適応変化させる事により圧縮率を向上させた動的ライス・ゴロム符号を利用した可逆圧縮方式。圧縮ソフト、圧縮率のMATLABシミュレーションは詳細はInterface誌2011年8月号に掲載されるRX62Nマイコン連動特集にて掲載予定。
Diff: main.cpp
- Revision:
- 0:d920d64db582
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Mar 30 06:05:24 2011 +0000 @@ -0,0 +1,320 @@ +#include "mbed.h" +#include "MSCFileSystem.h" +#include "SDHCFileSystem.h" +#include "TextLCD.h" +#include "i2s_irq_test.h" +#include "lpc17xx_i2s.h" +#include "lpc17xx_clkpwr.h" +#include "aic23b_comm.h" +#include "string" +#include "_bitio.h" + +#define _RGM_ADAPTIVE 1 /* 1:Adaptive 0:Constant */ + +#define k_bits 0x07 // k_bits:0x09 to 0x0b? +#define min_of_k 0x07 +#define max_of_k 0x0b /*for dynamic Rice-Golomb codings */ + +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); +Serial pc(USBTX, USBRX); // tx, rx +I2C AIC23B(p9,p10); //sda,scl + +TextLCD lcd(p24, p26, p27, p28, p29, p30); +SDFileSystem sd(p11, p12, p13, p14, "sd");//p5,6,7,8 +//MSCFileSystem msc("msc"); // Mount flash drive under the name "msc" +FILE *infp,*outfp,*playlist; + +Ticker tick; +Ticker fl_leds; + +#define AudioBufRow 256 /* length of proc_r */ +volatile short int AudioBuf[2][AudioBufRow]; /* Audio Data Buffer:AudioBuf[empty_c][proc_r] */ +volatile BYTE empty_c=0; /* Column of AudioBuf */ +volatile BYTE proc_r=0; /* Row of AudioBuf */ +bool dac_semp; /* Write AudioBuf Complete? true:Yes, false:No */ + + +int aic23b_send(int addr,char ctrl_address,char ctrl_data){ + int flag; + char cmd[2]; + cmd[0]=ctrl_address; + cmd[1]=ctrl_data; + flag = AIC23B.write(addr, cmd, 2); + pc.printf("ADDR=0x%x, CTRL_ADD=0x%x, CTRL_DATA=0x%x, RESP=0x%x\r\n",(addr&0x7f),cmd[0],cmd[1],flag); + return (flag); +} + +int aic23b_init(void){ + int flag=0; + printf("*************************\r\nReset TLV320AIC23B\r\n*************************\r\n"); + AIC23B.frequency(150000); + flag = aic23b_send(AIC23B_ADDRESS,RESET_REFGISTER,RESET); + wait(0.1); + flag += aic23b_send(AIC23B_ADDRESS,POWER_DOWN_CONTROL,0); + wait(0.1); + flag += aic23b_send(AIC23B_ADDRESS,POWER_DOWN_CONTROL,1); + wait(0.1); + flag += aic23b_send(AIC23B_ADDRESS,DIGITAL_AUDIO_INTERFACE_FORMAT,(MASTER_MODE|INPUT_DATA_16_BIT_LENGTH|I2S_FORMAT)); + wait(0.1); + flag += aic23b_send(AIC23B_ADDRESS,SAMPLE_RATE_CONTROL,(SR_USB_44_1_KHZ_MODE| BOSR_USB_44_1_KHZ_MODE| USE_USB_CLOCK_44_1_KHZ_MODE)); + wait(0.1); + flag += aic23b_send(AIC23B_ADDRESS,ANALOG_AUDIO_PATH_CONTROL,0x10); + wait(0.1); + flag += aic23b_send(AIC23B_ADDRESS,DIGITAL_AUDIO_PATH_CONTROL,0); + wait(0.1); + flag += aic23b_send(AIC23B_ADDRESS,DIGITAL_INTERFACE_ACTIVATION,DIGITAL_INTERFACE_ACTIVE); + wait(0.1); + flag += aic23b_send(AIC23B_ADDRESS,LEFT_CHANNEL_HEADPHONE_VOLUME_CONTROL,LHV_VOLUME_DEFAULT); + wait(0.1); + flag += aic23b_send(AIC23B_ADDRESS,RIGHT_CHANNEL_HEADPHONE_VOLUME_CONTROL,RHV_VOLUME_DEFAULT); + + if(!flag) { + printf("*************************\r\nReset OK\r\n*************************\r\n"); + return 0; + } + else{ + printf("*************************\r\nReset FAILED\r\n*************************\r\n"); + return -1; + } +} + +void pl_led_flash(void) +{ + if(led1){ + led1 = 0; + led2 = 1; + return; + } + + if(led2){ + led2 = 0; + led3 = 1; + return; + } + + if(led3){ + led3 = 0; + led4 = 1; + return; + } + + if(led4){ + led4 = 0; + led1 = 1; + return; + } + + +} + +void dac_out(void) +{ + volatile static short i,j; // AudioBuf[j][i] + volatile uint32_t DBufLR; // Buffer Data to send I2S_TX + uint16_t BufLPCnt; + for(BufLPCnt=0 ; BufLPCnt < 9 ; BufLPCnt++ ) + { + if(i >= AudioBufRow-1) + { + if(dac_semp) /* colunm (empty_c) is full? true:Yes */ + { + i=0; + empty_c =(empty_c==1)?0:1; /* empty_c:empty column of buffer AudioBuf, Because I2S_TX used these data */ + j=(empty_c==1)?0:1; /* Change column which buffer is filled with data by function decode() */ + dac_semp = false; /* false: empty_c is ready to get data from function decode() */ + + }else{ /* Buffer is NOT ready to read? */ + return; /* NO:return */ + } + } + //Send I2S_TX + if(I2S_GetLevel(LPC_I2S, I2S_TX_MODE)==TXFIFO_FULL)break; + DBufLR = (0xffff0000 & (AudioBuf[j][i++]<<16))|(0x0000ffff & AudioBuf[j][i++]); + I2S_Send(LPC_I2S,DBufLR); + } +} + +void encode(long int n){ + int zero_shift = 0; + + if(n < 0){ + putbit(0); // sign (put 0:if n as negative) + n = -n; // n = abs(n) + //printf("\t 0"); + } + else{ + putbit(1); // sign (put 1:if n as positive) + //printf("\t 1"); + } + zero_shift = (n >> (_lsb_k)); + //printf("\t shift= %d",zero_shift); + while(zero_shift > 0){ + + zero_shift--; + putbit(0); + } // put n/(2^_lsb_k) 0's + + putbit(1); // terminating "1" + putbits(_lsb_k,rightbits(_lsb_k,n)); + //printf("\t finish= %d \r\n",(n & ((1U<<_lsb_k)-1))); +} + + + +void decode(void) +{ + volatile short i=0,j=0; + + volatile long int diff=0,diff2=0; /* differential of previous data buffer */ + volatile unsigned int buff_sign,zero_shift; /* sign buffer,register for unary codings */ + volatile long int decode_buff; + + volatile unsigned char k1= k_bits; /* Coding Parameter (init:k_bits) */ + volatile unsigned char k2= k_bits; + + init_bit_o(); + init_bit_i(); /* init bit control function */ + while(1){ + + if(i!=empty_c) + { + if(j>=AudioBufRow-1) + { + i=empty_c; /* Choose empty buffer*/ + j=0; + } + } + + if (j<AudioBufRow-1) + { + /* decode */ + if((buff_sign = getbit()) == OVERRUN)break; /*get sign*/ + + zero_shift = 0; + while(getbit()==0) + zero_shift++; /* decode unary code */ + + decode_buff = (signed int)(zero_shift*(1U<<k1)); /*decode Rice-Golomb code*/ + decode_buff += getbits(k1); + + if(!buff_sign)decode_buff =- decode_buff; /*add sign */ + diff =(diff + decode_buff); /* get audio data */ + + AudioBuf[i][j]=(short int)(diff); /* write AudioBuf */ + j++; + + +#if _RGM_ADAPTIVE + /* calc k */ + if(zero_shift > 2)k1=k1+1; + if(zero_shift == 0)k1=k1-1; + if(k1 < min_of_k)k1 = min_of_k; + if(k1 > max_of_k)k1 = max_of_k; +#endif + + if((buff_sign = getbit()) == OVERRUN)break; /* get sign */ + + zero_shift = 0; + while(getbit()==0) + zero_shift++; /* decode unary code */ + + decode_buff = (signed int)(zero_shift*(1U<<k2)); /* decode Rice-Golomb code */ + decode_buff += getbits(k2); + + if(!buff_sign)decode_buff =- decode_buff; /* add sign */ + diff2 =(diff2 + decode_buff); /* get Audio data */ + + AudioBuf[i][j]=(short int)(diff2); /* Write Buffer */ + j++; + +#if _RGM_ADAPTIVE + /* calc k */ + if(zero_shift > 2)k2=k2+1; + if(zero_shift == 0)k2=k2-1; + if(k2 < min_of_k)k2 = min_of_k; + if(k2 > max_of_k)k2 = max_of_k; +#endif + + } + if(j>=AudioBufRow-1){ /* AudioBuf is filled with data? */ + dac_semp = true; + } + } +} + + +int main() { + + char s[256]; + char* p; + + lcd.cls(); + lcd.locate(0,0); + lcd.printf("I2S Codec:"); + mbed_i2s_init(); //DAC:44100Hz sampling ,16bit ,Stereo ,MCLK Disable, TLV320AIC23B=Master + if(aic23b_init()==0){ + lcd.locate(12,0); + lcd.printf("OK"); + }else{ + lcd.locate(12,0); + lcd.printf("NG"); + } + Buffer_Init(); + pc.printf("CCLKCFG= %d \r\n",LPC_SC->CCLKCFG); + pc.printf("I2S Send start.\r\n"); + led1=1; + lcd.locate(0,1); + lcd.printf("> Please Wait..."); + + if ( NULL == (playlist = fopen( "/sd/play.txt", "r" )) ) { + printf( "\r\nError: The Playlist file cannot be accessed\r\n" ); + return -1; + } + + + while(1){ + if((fgets( s, 256, playlist ))==NULL){ + fseek(playlist, 0L, SEEK_SET); + fgets( s, 256, playlist ); + } + p=strchr(s,'\n'); + if(p!=NULL){ + *p='\0'; + + } //remove CR code for Macintosh text-file + p=strchr(s,'\r'); + if(p!=NULL){ + *p='\0'; + + } //remove LF code for Linux & Windows text-file + printf("\r\n open file:%s \r\n",s); // cut '\n' symbol + lcd.locate(0,1); + lcd.printf("> "); + s[15]='\0'; + lcd.locate(1,1); + lcd.printf("%s",s); + if ( NULL == (infp = fopen( s, "r" )) ) { + printf( "\r\nError: The message file cannot be accessed\r\n" ); + return -1; + } + + fseek(infp, 0L, SEEK_SET); + tick.attach_us(&dac_out, 181); //set 44.1kHz/8(word FIFO) sampling data + fl_leds.attach(&pl_led_flash,1); + + + decode(); + + fclose( infp ); + infp = NULL; + tick.detach(); + fl_leds.detach(); + lcd.locate(0,1); + lcd.printf("> Please Wait..."); + } +} + + \ No newline at end of file