/******************************************************************************* * モジュール名称 :APP EWO Common - Wave compression * * 機能 :波形データのサブバンド圧縮を行う * * 作成日・作成者 :2015/11/18 T.Imachi * * 注意 :EDIT権限は、EWO組 * *******************************************************************************/ #include "app_common.h" #include "app_EWO.h" #define TRUE 1 #define FALSE 0 #define BANDNUM 8 // バンド数 #define PREC 8 // 最大量子化サイズ #define DATALEN 1024 // 入力データの長さ(1単位処理あたり) #define FILTER 16 // フィルタの次数 #define FILTER2 8 // フィルタの次数/2 #define BUFNUM (BANDNUM*2-1) // バッファの数 (BANDNUM*2-1) = (8 * 2 - 1) = 15 //#define BLKN 8 // ブロック数 #define BLKN 1 // ブロック数 (Changed by Y.Kasahara, 2015.11.18) #define PRESSEND (DATALEN/BANDNUM) // 1帯域あたりのデータ数 unsigned int app_EWO_compWave( short *input, // [INPUT] Input data int inlen, // [INPUT] Input data長 unsigned short *output, // [OUTPUT] Output data double *f_waveBuf // [INPUT/OUTPUT] 計算結果引継ぎバッファ ) { // General unsigned int sub,prec,datalen,step; // 圧縮パラメータ unsigned int blocknumber; unsigned int blocklength; unsigned int datacount; // 入力データのカウンタ unsigned int codeout; // 出力数のカウント // unsigned int pcount; // 出力数のアドレス unsigned int outcount; // analyzerでの出力コードのカウンタ unsigned int pressout; // 圧縮したデータ数のカウント unsigned int pressend; // for subband filter int subband[BANDNUM][PRESSEND]; double fsubband[BANDNUM][PRESSEND]; double *Lnext[BUFNUM], *Hnext[BUFNUM]; double H0filter[16] = { 0.001050167, -0.005054526, -0.002589756, 0.027641400, -0.009666376, -0.090392230, 0.097798170, 0.48102840, 0.48102840, 0.097798170, -0.090392230, -0.009666376, 0.027641400, -0.002589756, -0.005054526, 0.001050167 }; int indextbl[8] = { 1, 1, 1, 1, 1, 1, 1, 1 }; int banktbl [8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; // for encode double fscale1[16] = { 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 2048.0, 4096.0, 8192.0, 16384.0, 32768.0 }; double fscale2[16] = { 1.0, 0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125, 0.00390625, 0.001953125, 0.0009765625, 0.00048828125, 0.000244140625, 0.0001220703125, 0.00006103515625, 0.00003051757812 }; // unsigned int scale[16] = { // 1, 2, 4, 8, // 16, 32, 64, 128, // 256, 512, 1024, 2048, // 4096, 8192, 16384, 32768 }; // Analyzer int now, loop, stindex; int nextindex; double *tmpbuf; int tmp; double tmp1, tmp2, ftmp; //DetectMax register int dmax; int bits; // CompressBlock unsigned int bln; unsigned int ch; // チャネル毎に処理するためのループ用 unsigned int bl; // データ点毎に処理するためのブロック用 double data; // 圧縮するデータ unsigned int num; // 圧縮済のデータ unsigned int n, n1, n2; int bitmax = 0; // ブロック中の最大ビット幅 int bitshift[BANDNUM]; // ブロック中の最大ビット幅からprec引いた値 int chbitmax[BANDNUM]; // チャネル毎の最大値のビット幅 int DATA_SIZE = 3*16*8*256; // <-ヘッダ部 // 出力データサイズ数 (力づくで計算) int i, j; //======================================================== // Initialize //======================================================== /*パラメータの取得*/ sub = BANDNUM; // prec = PREC; prec = G5ui_EWO_WFCH_prec; datalen = DATALEN; step = 3; pressend = datalen / sub; /* 1帯域あたりのデータ数 */ blocknumber = BLKN; blocklength = pressend / blocknumber; /*各枝での結果が次にどの枝に送られるかを示すポインタを初期化*/ tmp = 0; for( loop = 0; loop < BUFNUM; loop++){ tmp++; // Lnext[loop] = Gf_EWO_compWaveBuf+tmp*FILTER; Lnext[loop] = f_waveBuf+tmp*FILTER; tmp++; // Hnext[loop] = Gf_EWO_compWaveBuf+tmp*FILTER; Hnext[loop] = f_waveBuf+tmp*FILTER; } //======================================================== // Analyzer //======================================================== // サブバンド分割処理 codeout = 0; // 出力コードの数 outcount = 0; // analyzerでの出力コードのカウンタ datacount = 0; // 入力データのカウンタ pressout = 0; // 圧縮後のカウンタ while(datalen != datacount){ now = loop = stindex = 1; while(now < step+1){ if(now == 1){ // *(Gf_EWO_compWaveBuf+1) = (double) *(input+datacount); *(f_waveBuf+1) = (double) *(input+datacount); datacount++; // *Gf_EWO_compWaveBuf = (double) *(input+datacount); *f_waveBuf = (double) *(input+datacount); datacount++; } nextindex = loop-1; for(i = 0; i < loop; i++){ // tmpbuf = Gf_EWO_compWaveBuf+(loop-1+i)*FILTER; tmpbuf = f_waveBuf+(loop-1+i)*FILTER; tmp1 = 0.0; tmp2 = 0.0; // フィルタ処理 for(j = 0; j < FILTER2; j++){ tmp1 += tmpbuf[j*2] * H0filter[j*2]; tmp2 += tmpbuf[j*2+1] * H0filter[j*2+1]; } *((*(Lnext+nextindex))+stindex) = tmp1+tmp2; *((*(Hnext+nextindex))+stindex) = tmp1-tmp2; nextindex++; for(j = FILTER-1; j >= 2; j--){ tmpbuf[j] = tmpbuf[j-2]; } } if(now < step){ if(stindex == 0){ stindex = 1; indextbl[now] = 1; loop = banktbl[now]; now = now+1; stindex = indextbl[now]; } else{ indextbl[now] = 0; now = 1; stindex = indextbl[now]; loop = 1; } } else{ now = now+1; } } // while(now < step+1){ loop = banktbl[now-1]; for( i = 0; i < loop; i++){ // ftmp = *(Gf_EWO_compWaveBuf+(loop-1+i)*FILTER+1); // Pointer計算は残せるかどうか要検討。 ftmp = *(f_waveBuf+(loop-1+i)*FILTER+1); // Pointer計算は残せるかどうか要検討。 fsubband[i][outcount] = ftmp; if( ftmp >= 0 ) ftmp += 0.5; else ftmp -= 0.5; tmp = (int)ftmp; if (tmp>0) subband[i][outcount] = tmp; // "abs"から変更 else subband[i][outcount] = -tmp; // "abs"から変更 } outcount = outcount+1; } // while(datalen != datacount){ //======================================================== // CompressBlock //======================================================== for( bln = 0; bln < blocknumber; bln++){ // ************************************* // 各チャネルの最大値のビット幅を調べ // ブロック全体の最大ビット幅を求める // ************************************* for( ch = 0; ch < sub; ch++ ) { dmax=0; for(bl = 0; bl < blocklength; bl++){ tmp = subband[ch][pressout+bl]; if(tmp > dmax) dmax = tmp; } /*そのビット数を求める*/ bits = 0; while(1){ if( dmax == 0 ) break; dmax = (dmax>>1); bits++; } chbitmax[ch] = bits+1; // chbitmax[ch] = DetectMax(ch,pressout); if( bitmax < chbitmax[ch] ) bitmax = chbitmax[ch]; } if ( bitmax <= prec ){ //prec = 最大量子化サイズ for( ch = 0; ch < sub; ch++ ) bitshift[ch] = 0; } else{ for( ch = 0; ch < sub; ch++ ) { bitshift[ch] = chbitmax[ch] - prec; if ( bitshift[ch] < 0 ) bitshift[ch] = 0; chbitmax[ch] -= bitshift[ch]; } } // ブロック中の最大ビット幅 ー prec for( ch = 0; ch < sub; ch++ ){ *(output+codeout) = bitshift[ch]; // Pointer計算は残せるかどうか要検討。 codeout++ ; } // 各チャネルのビット幅 for(ch = 0; ch < sub; ch++){ *(output+codeout) = chbitmax[ch]; // Pointer計算は残せるかどうか要検討。 DATA_SIZE += chbitmax[ch] * 16; codeout ++ ; } for( ch = 0; ch < sub; ch++ ) { if (bitshift[ch] == 0){ // 各データを圧縮せずそのまま出力 if( chbitmax[ch] != 0 ) { n = chbitmax[ch] -1; for( bl = 0; bl < blocklength; bl++ ) { data = fsubband[ch][pressout+bl] + fscale1[n]; if(data < 0) data = 0.0; if(data+0.5 > fscale1[n+1]) num = (unsigned int) data; else{ num = (unsigned int) (data+0.5); } *(output+codeout)= num; // Pointer計算は残せるかどうか要検討。 codeout ++; } } }else{ // 各データを圧縮し出力 if ( chbitmax[ch] != 0 ) { n1 = chbitmax[ch]+bitshift[ch]-1; n2 = chbitmax[ch] -1; for ( bl = 0; bl < blocklength; bl++ ) { data = fsubband[ch][pressout+bl] + fscale1[n1]; if(data < 0) data = 0.0; data = data * fscale2[bitshift[ch]]; if(data+0.5 > fscale1[n2+1]) num = (unsigned int) data; else{ num = (unsigned int) (data+0.5); } *(output+codeout)= num; codeout ++; } } } } pressout += blocklength; }// while(pressout != pressend){ return codeout; } /* int main(int argc, char *argv[]) { int i, j, tmp, framecount; unsigned int irc; char encodefilename[256]; char file[20]; short input[DATALEN]; unsigned short output[DATALEN]; FILE *fpin, *fpencode; // エラー処理 , ファイルオープン if(argc != 2){ fprintf( stderr,"Usage: %s [inputfilename] \n",argv[0]); exit( -1 ); } if( ( fpin = fopen(argv[1],"rb") ) == NULL ){ fprintf(stderr,"Cannot open the file \"%s\"",argv[1]); exit( -1 ); } strcpy(file, argv[1]); strcpy(encodefilename, "enc-"); strcat(encodefilename, file); if( ( fpencode = fopen(encodefilename,"w")) == NULL ){ fprintf(stderr,"Cannot open the file \"%s\"",encodefilename); exit( -1 ); } framecount = (int)((double)RAWDATA/(double)DATALEN); for( i = 0; i < framecount; i++){ // for( i = 0; i < 1; i++){ for(j = 0; j < DATALEN; j++){ fread(&tmp, sizeof(int), 1, fpin); input[j] = tmp / 4; //16bit -> 14bit data // printf("%4d %8d\n",j, input[j]); } irc = app_EWO_compWave(input,(int)DATALEN,output); // printf("irc= %d\n", irc); for(j = 0; j < irc; j++){ fprintf(fpencode,"%d\n",(int)output[j]); } } } */