- •Содержание
- •Введение
- •1. Обзор существующих методов решения задачи
- •1.2 Перцептивное кодирование
- •2. Обоснование выбранного метода
- •3. Разработка структурной схемы системы
- •4. Разработка и тестирование модели
- •5. Разработка программного обеспечения на языке си
- •Библиографический список
- •Приложение а Текст программы на языке matlab
- •Приложение б Текст программы на языке си
Приложение б Текст программы на языке си
#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);
}