パラメータを適応変化させる事により圧縮率を向上させた動的ライス・ゴロム符号を利用した可逆圧縮方式。圧縮ソフト、圧縮率のMATLABシミュレーションは詳細はInterface誌2011年8月号に掲載されるRX62Nマイコン連動特集にて掲載予定。

Dependencies:   mbed

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