ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
18 апреля
699693 Топик полностью
Николай Коровин (15.09.2016 12:54, просмотров: 212) ответил Dingo на Первый способ, предложенный вами. Для примера передрал с диска "The best of Gershwin" Allegro (у коллеги взял)один канал, обработал, записывая разницу - даже архиваторы стали более лояльно относиться.
Что-то типа такого:  #include <fstream.h> //тестовая прога, по-быстрому накиданная из разных кусков для демонстрации #include <math.h> //caxapa.ru fstream LogF; #define SPLINE_LEN 32 signed long Basis[5][SPLINE_LEN]; signed long Coeff[5]; signed long Spline (int X) { signed long long V=0,T; T=Coeff[0]; T*=Basis[0][X]; V+=T; T=Coeff[1]; T*=Basis[1][X]; V+=T; T=Coeff[2]; T*=Basis[2][X]; V+=T; T=Coeff[3]; T*=Basis[3][X]; V+=T; T=Coeff[4]; T*=Basis[4][X]; V+=T; return V/16777216; } void FitGauss (signed long *Buffer, int Size) { double LinearEqA[5][5]={0}, LinearEqC[5]={0}, LinearEqX[5]={0}; int i,j,k,t; double Tmp; for (i=0;i<5;i++) for (j=0;j<Size;j++) LinearEqC[i]+=(double)(Buffer[j])*(double)(Basis[i][j]); for (i=0;i<5;i++) for (j=0;j<5;j++) for (k=0;k<Size;k++) LinearEqA[i][j]+=(double)(Basis[i][k])*(double)(Basis[j][k]); t=5; for(i=0;i<t-1;i++) { k=i; for(j=i+1;j<t;j++) if(fabs(LinearEqA[j][i])>fabs(LinearEqA[k][i])) k=j; if(i!=k) { for(j=i;j<t;j++) {Tmp=LinearEqA[k][j];LinearEqA[k][j]=LinearEqA[i][j];LinearEqA[i][j]=Tmp;} Tmp=LinearEqC[k];LinearEqC[k]=LinearEqC[i];LinearEqC[i]=Tmp; } Tmp=LinearEqA[i][i]; for(j=i;j<t;j++) LinearEqA[i][j]=LinearEqA[i][j]/Tmp; LinearEqC[i]=LinearEqC[i]/Tmp; for(j=i+1;j<t;j++) { Tmp=LinearEqA[j][i];LinearEqC[j]-=LinearEqC[i]*Tmp; for(k=i+1;k<t;k++) LinearEqA[j][k]-=LinearEqA[i][k]*Tmp; } } LinearEqX[t-1]=LinearEqC[t-1]/LinearEqA[t-1][t-1]; for(i=t-2;i>=0;i--) { Tmp=0.0; for(j=i+1;j<t;j++) Tmp+=LinearEqA[i][j]*LinearEqX[j]; LinearEqX[i]=LinearEqC[i]-Tmp; } Coeff[0]=LinearEqX[0]*16777216.0; Coeff[1]=LinearEqX[1]*16777216.0; Coeff[2]=LinearEqX[2]*16777216.0; Coeff[3]=LinearEqX[3]*16777216.0; Coeff[4]=LinearEqX[4]*16777216.0; // LogF<<LinearEqX[0]<<" "<<Coeff[0]<<" "<<LinearEqX[1]<<" "<<Coeff[1]<<" "<<LinearEqX[2]<<" "<<Coeff[2]<<" "<<LinearEqX[3]<<" "<<Coeff[3]<<" "<<LinearEqX[4]<<" "<<Coeff[4]<<endl; } void main (void) { int i; fstream InF, OutF, DiffF, OutDiffF; signed long Raw[SPLINE_LEN],Diff[SPLINE_LEN]; double Tmp; LogF.open ("test_log.xls", ios::out|ios::text); for (i=0; i<SPLINE_LEN; i++) { Basis[0][i]=0x00FFFFFF; Basis[1][i]=cos(i*3.1415926*2.0*1.0 / SPLINE_LEN)*0x00FFFFFF; Basis[2][i]=cos(i*3.1415926*2.0*2.0 / SPLINE_LEN)*0x00FFFFFF; Basis[3][i]=cos(i*3.1415926*2.0*4.0 / SPLINE_LEN)*0x00FFFFFF; Basis[4][i]=cos(i*3.1415926*2.0*8.0 / SPLINE_LEN)*0x00FFFFFF; /* Tmp=(double)(i) / (double)(SPLINE_LEN); Basis[1][i]=Tmp * 0x00FFFFFF; Tmp*=(double)(i) / (double)(SPLINE_LEN); Basis[2][i]=Tmp * 0x00FFFFFF; Tmp*=(double)(i) / (double)(SPLINE_LEN); Basis[3][i]=Tmp * 0x00FFFFFF; Tmp*=(double)(i) / (double)(SPLINE_LEN); Basis[4][i]=Tmp * 0x00FFFFFF;*/ // LogF<<Basis[0][i]<<" "<<Basis[1][i]<<" "<<Basis[2][i]<<" "<<Basis[3][i]<<" "<<Basis[4][i]<<endl; } InF.open ("test.raw", ios::in|ios::binary); OutF.open ("test_out.raw", ios::out|ios::binary); DiffF.open ("test_dif.raw", ios::out|ios::binary); OutDiffF.open ("test_SnD.raw", ios::out|ios::binary); for (;;) { InF.read ((char*)Raw, SPLINE_LEN*4); if (InF.fail()) break; FitGauss (Raw, SPLINE_LEN); for (i=0; i<SPLINE_LEN; i++) Diff[i]=Raw[i]-Spline(i); for (i=0; i<SPLINE_LEN; i++) { LogF<<Raw[i]<<" "<<Spline(i)<<" "<<Diff[i]; if (i) LogF<<endl; else LogF<<" "<<Coeff[0]<<" "<<Coeff[1]<<" "<<Coeff[2]<<" "<<Coeff[3]<<" "<<Coeff[4]<<endl; } OutF.write ((char*)Coeff,sizeof(Coeff)); OutF.write ((char*)Diff, SPLINE_LEN*4); for (i=SPLINE_LEN-1; i>0; i--) Diff[i]-=Diff[i-1]; OutDiffF.write ((char*)Coeff,sizeof(Coeff)); OutDiffF.write ((char*)Diff, SPLINE_LEN*4); for (i=1; i<SPLINE_LEN; i++) Diff[i]=Raw[i]-Raw[i-1]; Diff[0]=Raw[0]; DiffF.write ((char*)Diff, SPLINE_LEN*4); } InF.close(); OutF.close(); DiffF.close(); OutDiffF.close(); LogF.close(); } Разумеется, оно должно хорошо натягиваться на аппроксимирующую кривую. Может, имеет смысл сделать БПФ и записать его выхлоп. Или работать на маленьких интервалах, интерполируя максимум квадратами. В любом случае, суть в том, чтобы провести сжатие с потерями, задав форму части кривой приближённо, и хранить его плюс разницу с реальным, которая уписывается уже в считанные биты и вельми хаффманоугодна.