Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
DSP_CP.doc
Скачиваний:
19
Добавлен:
02.12.2018
Размер:
209.41 Кб
Скачать

Приложение б Текст программы на языке си

#include <stdio.h>

#include <stdlib.h>

#include <complex.h>

#include <math.h>

#include <conio.h>

#define BlockSz 1024 //размер обрабатываемого блока

#define Freq 22050//масштабирующий коэффициент

#define CrossSz 512 //перекрытие блоков

#define Bits 1 //

#define HdrSz 70 //размер заголовка

#define LineNum 28

typedef struct {

unsigned int N;

complex D;

} Comp;

typedef struct {

double E;

Comp D[LineNum+1];

} CompRec;

unsigned char Buf[BlockSz*Bits];

double Data[BlockSz];

complex Data2[BlockSz];

double win[BlockSz]; //Окно Хемминга

complex X[BlockSz];

unsigned int Line[LineNum]={0, 50, 95, 140, 235, 330, 420,560,660,800,940,

1125,1265,1500,1735,1970,2340,2720,3280,3840,4690,

5440,6375,7690,9375,11625,15375,22050 };

unsigned int LineCnt[LineNum];

CompRec C;

FILE *inf,*cf,*outf;

//---------------------------------------------------------

//чиение WAV файла

int wavRead(FILE * inf)

{

fread(Buf,1,BlockSz,inf);

}

//---------------------------------------------------------

//запись WAV файла

void wavWrite(FILE * outf)

{

fwrite(Buf,1,BlockSz,outf);

}

//---------------------------------------------------------

//запись сжатого файла

void compWrite(FILE * outf)

{

fwrite(&C,sizeof (CompRec),1,outf);

}

//---------------------------------------------------------

//стение сжатого файла

int compRead(FILE * inf)

{

fread(&C,sizeof(CompRec),1,inf);

}

//---------------------------------------------------------

//перевод двоичного формата представления числа в форме с фиксированной запятой //в его десятичный эквивалент

int b2d(int cnt)

{ int i;

unsigned int t;

unsigned int m;

double p;

C.E=0;

for (i=0; i<cnt; i++)

{

if (Bits==2)

t=Buf[i<<1+1]<<8 + Buf[i<<1];

else

t=Buf[i];

p = 0.5;

m = 1<<(Bits*8-1);

Data[i]= 0;

while (m)

{ m >>= 1;

Data[i]=Data[i]+ (t&m ? p : 0);

p /= 2;

}

m = 1<<(Bits*8-1);

Data[i] *= t&m ? 1: -1;

C.E+=fabs(Data[i]);

// Data[i]=Data[i]*win[i];

}

}

//---------------------------------------------------------

//перевод десятичного формата представления числа в форме с фиксированной запятой //в его двоичный эквивалент

int d2b(int cnt)

{ int i;

unsigned int t;

unsigned int m;

double p;

double NewBlockEnergy=0;

for (i=0;i<BlockSz;i++)

NewBlockEnergy+=fabs(real(X[i]));

for (i=0;i<BlockSz;i++)

X[i]=complex(real(X[i])*C.E/NewBlockEnergy,0);

for (i=0; i<cnt; i++)

{ p=real(X[i]);

m = 1<<(Bits*8-1);

t = p>0? m: 0;

p=fabs(p);

while (m)

{ m >>= 1;

p *= 2;

t=t | (p>1 ? m : 0);

p = p>1?p-1:p;

}

Buf[i]=t;

}

}

//---------------------------------------------------------

void Init()

{ int i;

for (i = 0; i < BlockSz ; i++) //Построение окна Hamming

win[i] = 0.54 - 0.46 * cos (2 * M_PI * i / (BlockSz - 1));

for (i = 0; i<LineNum; i++)

LineCnt[i]=((unsigned long)Line[i])*BlockSz/Freq;

}

//---------------------------------------------------------

//БПФ для N/2 отсчетов считается по формулам:

// __ __ __ __

// / N/2-1 \ / N/2-1 \

// | ___ | | ___ |

// | \ nk | | \ nk | k

//X[k] = | / x[2n]W | + | / x[2n+1]W | * W (1)

// | --- N/2 | | --- N/2 | N

// | n=0 | | n=0 |

// +-- --+ +-- --+

//

// k

// X[k] = X [k] + X [k] * W (2)

// 1 2 N

// где 0 < k < N/2

// k

// X[k+N/2] = X [k] - X [k] * W (3)

// 1 2 N

//

//

//----------------------------------------------------------

void fft(complex *D, int d0, int n, int st, int x0)

{ complex W;

complex DH,DG;

if (n>2)

{ fft(D,d0,n/2,st*2,x0);

fft(D,d0+st,n/2,st*2,x0+n/2);

int i,k,gk,hk;

for (i=0,k=x0,gk=x0,hk=x0+st; i<n/2; i++,k+=st,gk+=st*2,hk+=st*2)

{ W=complex(cos(2*M_PI*i/n),-sin(2*M_PI*i/n));

DG=D[x0+i]; DH=D[x0+n/2+i]*W;

D[x0+i]=DG+DH;

D[x0+n/2+i]=DG-DH;

}

} else

{ D[x0]=complex(Data[d0],0)+complex(Data[d0+st],0)*complex(1,0);

D[x0+1]=complex(Data[d0],0)-complex(Data[d0+st],0)*complex(1,0);

}

}

//---------------------------------------------------------

//ОДПФ считается по формуле:

//

//

// x[n] = 1/N SUM (X[k]*exp(j*2*pi*k*n/N))

// 0<k<N-1

//

//---------------------------------------------------------

void ifft(complex *D, int d0, int n, int st, int x0)

{ complex W;

complex DH,DG;

if (n>2)

{ ifft(D,d0,n/2,st*2,x0);

ifft(D,d0+st,n/2,st*2,x0+n/2);

int i,k,gk,hk;

for (i=0,k=x0,gk=x0,hk=x0+st; i<n/2; i++,k+=st,gk+=st*2,hk+=st*2)

{ W=complex(cos(2*M_PI*i/n),sin(2*M_PI*i/n));

DG=D[x0+i]; DH=D[x0+n/2+i]*W;

D[x0+i]=(DG+DH)/n;

D[x0+n/2+i]=(DG-DH)/n;

}

} else

{ D[x0]=Data2[d0]+Data2[d0+st]*complex(1,0);

D[x0+1]=Data2[d0]-Data2[d0+st]*complex(1,0);

}

}

//---------------------------------------------------------

void Compress()

{ int i,j;

for (i=0; i<LineNum-1; i++)

{ for (j=LineCnt[i], C.D[i].N=j, C.D[i].D=X[j]; j<LineCnt[i+1]; j++)

if (abs(real(C.D[i].D))<abs(real(X[j])))

{ C.D[i].D=X[j];

C.D[i].N=j;

}

}

}

//---------------------------------------------------------

void UnCompress()

{ int i,j;

for (i=0; i<BlockSz; i++)

Data2[i]=complex(0,0);

for (i=0; i<LineNum; i++)

{ Data2[C.D[i].N]=C.D[i].D;

}

}

//---------------------------------------------------------

long filesize(char *fName)

{ FILE *stream;

stream=fopen(fName,"r");

fseek(stream, 0L, SEEK_END);

return ftell(stream);

}

//---------------------------------------------------------

void CopyHdr(FILE *inf,FILE *outf)

{ char b[HdrSz];

fread(b,HdrSz,1,inf);

fwrite(b,HdrSz,1,outf);

}

//---------------------------------------------------------

void main(void)

{ int i,j;

char *fName="x3.wav";

char *cName="out.cmp";

char *oName="out.wav";

long FLen=filesize(fName);

Init();

inf=fopen(fName,"rb");

cf=fopen(cName,"wb");

// outf=fopen(oName,"wb");

// CopyHdr(inf,outf);

printf("Compressing ...");

CopyHdr(inf,cf);

for (i=0; i<(FLen-HdrSz)/BlockSz+1; i++)

{ wavRead(inf);

b2d(BlockSz);

fft(X,0,BlockSz,1,0);

Compress();

compWrite(cf);

// printf("Compressing block %d\n",i);

}

fclose(inf);

fclose(cf);

clrscr();

FLen=filesize(cName);

cf=fopen(cName,"rb");

outf=fopen(oName,"wb");

CopyHdr(cf,outf);

printf("Decompressing ...");

for (i=0; i<(FLen-HdrSz)/sizeof(C); i++)

{ compRead(cf);

UnCompress();

ifft(X,0,BlockSz,1,0);

d2b(BlockSz);

wavWrite(outf);

// printf("Decompressing block %d\n",i);

}

// fclose(inf);

fclose(cf);

fclose(outf);

exit(0);

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]