Эксперт
   
Профиль
Группа: Завсегдатай
Сообщений: 2097
Регистрация: 8.3.2006
Репутация: нет Всего: 73
|
Добрый день. Посоветуйте, в какую сторону смотреть для реализации алгоритма (банка фильтров) для разложения аудиосигнала на 32 частотных поддиапазона. Самое желательное - найти реализацию уже готового алгоритма на java, С# или C++. Я попытался с помощью вейвлета Daubechie разложить. Вобщем-то вроде работает, можно разложить на два поддиапазона, потом на 4, и так 5 ступеней, но возникают проблемы из-за краевых искажений. Прямое преобразование: | Код | boolean dwt(double signal[], int k) { int N; // Длинна буфера int L=20; // Длинна фильтра int K; double buffer[], approx[], details[]; double Daubechies10[] = { 0.01885857879640, 0.13306109139687, 0.37278753574266, 0.48681405536610, 0.19881887088440, -0.17666810089647, -0.13855493935993, 0.09006372426666, 0.06580149355070, -0.05048328559801, -0.02082962404385, 0.02348490704841, 0.00255021848393, -0.00758950116768, 0.00098666268244, 0.00140884329496, -0.00048497391996, -0.00008235450295, 0.00006617718320, -0.00000937920789 }; //Вычисляем длинну буфера N=k; buffer = new double[N+L+2]; for(int i=0;i<k;i++) { buffer[i]=signal[i]; } for(int i=0;i<(L-2);i++) { buffer[N+i]=buffer[i]; } N=N/2; K=L/2; details = new double[N]; approx = new double[N]; // Вычисление свертки сигнала с КЗФ for(int i=0;i<N;i++)// Цикл по отсчетам сигнала { int I0 = i * 2; approx[i] = 0; details[i] = 0; for(int j=0;j<K;j++)// // Цикл по отсчетам фильтра { int J0 = j * 2; int J1 = J0 + 1; int J2 = J0 + 2; approx[i] = approx[i] + buffer[I0+J0]*Daubechies10[J0] + buffer[I0+J1]*Daubechies10[J1]; details[i] = details[i] + buffer[I0+J0]*Daubechies10[L-J1] - buffer[I0+J1]*Daubechies10[L-J2]; //*/ /* approx[i] = approx[i] + buffer[I0+J0]*Daubechies10[J0] + buffer[I0+J1]*Daubechies10[J1]; details[i] = details[i] + buffer[I0+J0]*Daubechies10[J0] - buffer[I0+J1]*Daubechies10[J1]; //*/ } } for(int i=0;i<k/2;i++) { signal[i]= approx[i]; signal[i+k/2]= details[i]; } buffer = null; approx = null; details = null; return true; }
|
Обратное: | Код | boolean idwt(double[] result, int Na)//, double *aprox, double *detail) { int Nd=Na; int L=20; int N, k; double AppBuf[], DetBuf[]; double Daubechies10[] = { 0.01885857879640, 0.13306109139687, 0.37278753574266, 0.48681405536610, 0.19881887088440, -0.17666810089647, -0.13855493935993, 0.09006372426666, 0.06580149355070, -0.05048328559801, -0.02082962404385, 0.02348490704841, 0.00255021848393, -0.00758950116768, 0.00098666268244, 0.00140884329496, -0.00048497391996, -0.00008235450295, 0.00006617718320, -0.00000937920789 }; double aprox[], detail[]; aprox =new double[Na]; detail=new double[Nd]; if (Na!=Nd) return false; for(int i=0;i<Na;i++) { aprox[i] =result[i]; detail[i]=result[i+Na]; } k = (L/2-1); //N = max(Na, Nd); N=Na;//���� � (Na,Nd) AppBuf = new double[L+N]; DetBuf = new double[L+N]; for(int i=0;i<k;i++) { AppBuf[i] = aprox[Na-k+i]; DetBuf[i] = detail[Nd-k+i]; } for(int i=0;i<Na;i++) AppBuf[i+k] = aprox[i]; for(int i=0;i<Nd;i++) DetBuf[i+k] = detail[i]; // ����� ���������� ����� ��� for(int i=0;i<N;i++) { int I0 = i*2; int I1 = I0+1; result[I0] = 0; result[I1] = 0; for(int j=0;j<=k;j++) { int J0 = j*2; int J1 = J0+1; int J2 = J0+2; result[I0] = result[I0] + AppBuf[i+j]*Daubechies10[L-J2] + DetBuf[i+j]*Daubechies10[J1]; result[I1] = result[I1] + AppBuf[i+j]*Daubechies10[L-J1] - DetBuf[i+j]*Daubechies10[J0]; // */ /* result[I0] = result[I0] + AppBuf[i+j]*Daubechies10[J1] + DetBuf[i+j]*Daubechies10[J1]; result[I1] = result[I1] + AppBuf[i+j]*Daubechies10[J0] - DetBuf[i+j]*Daubechies10[J0]; //*/ } result[I0] = 2*result[I0]; result[I1] = 2*result[I1]; } AppBuf = null; DetBuf = null; aprox = null; detail = null; return true; }
|
Писал это очень данвно еще на С++, для других задач... Сейчас переделал на Java, но по мойму для разложения на 32 поддиапазона не очень подходит.
--------------------
Придумать идеальную защиту от дурака невозможно, дураки, наудивление, изобретательны.
|