パラメータを適応変化させる事により圧縮率を向上させた動的ライス・ゴロム符号を利用した可逆圧縮方式。圧縮ソフト、圧縮率のMATLABシミュレーションは詳細はInterface誌2011年8月号に掲載されるRX62Nマイコン連動特集にて掲載予定。
main.cpp
- Committer:
- lynxeyed_atsu
- Date:
- 2011-03-30
- Revision:
- 0:d920d64db582
File content as of revision 0:d920d64db582:
#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..."); } }