void deconv3(void *g, int gx, int gy, int gz, void *f, int fx, int fy, int fz, void *out) { double *g2 = unpack3(g, gx, gy, gz, gy, gz); double *f2 = unpack3(f, fx, fy, fz, gy, gz); double ff[(gx - fx + 1) * gy * gz]; deconv(g2, gx * gy * gz, f2, fx * gy * gz, ff, gy * gz); pack3(ff, gx - fx + 1, gy, gz, gy - fy + 1, gz - fz + 1, out); free(g2); free(f2); }
void deconv2(void *g, int row_g, int col_g, void *f, int row_f, int col_f, void *out) { double *g2 = unpack2(g, row_g, col_g, col_g); double *f2 = unpack2(f, row_f, col_f, col_g); double ff[(row_g - row_f + 1) * col_g]; deconv(g2, row_g * col_g, f2, row_f * col_g, ff, col_g); pack2(ff, row_g - row_f + 1, col_g, col_g - col_f + 1, out); free(g2); free(f2); }
void a2lsf(const double* lpc, int displacement, double* lsf, int nbLSF) { // should test if lpc is minimum-phase int nbLPC = nbLSF + 1 - (displacement > 1 ? displacement : 1); int pLen = 1 + nbLPC + displacement; int qLen = pLen; double ak[pLen]; ak[0] = 1; for (int i = 0; i < nbLPC; i++) ak[i + 1] = lpc[i]; for (int i = 0; i < displacement; i++) ak[1 + nbLPC + i] = 0; double rootR[pLen]; double rootI[pLen]; int nbRoots = 0; roots(ak, nbLPC + 1, rootR, rootI, &nbRoots); for (int i = 0; i < nbRoots; i++) { if (pow2(rootR[i]) + pow2(rootI[i]) >= 1) { cerr << "ERROR: try to compute LSF of polynomial which is not minimum-phase !" << endl; break; } } // form the sum and difference filters double pk[pLen]; double qk[qLen]; for (int i = 0; i < pLen; i++) { pk[i] = ak[i] + ak[pLen - 1 - i]; qk[i] = ak[i] - ak[pLen - 1 - i]; } // If order is even, remove the known roots at z = -1 for P and z = 1 for Q // If odd, remove both the roots from Q if (pLen % 2 == 1) { static double qFilt3[] = { 1, 0, -1 }; deconv(qk, qLen, qFilt3, 3); qLen -= 2; } else { static double pFilt2[] = { 1, 1 }; static double qFilt2[] = { 1, -1 }; deconv(pk, pLen, pFilt2, 2); pLen--; deconv(qk, qLen, qFilt2, 2); qLen--; } // Compute the roots of the polynomials int rootIndex = 0; roots(pk, pLen, rootR, rootI, &nbRoots); for (int i = 0; i < nbRoots; i += 2) lsf[rootIndex++] = atan2(rootI[i], rootR[i]); roots(qk, qLen, rootR, rootI, &nbRoots); for (int i = 0; i < nbRoots; i += 2) lsf[rootIndex++] = atan2(rootI[i], rootR[i]); // sort lsfs std::sort(lsf, lsf + rootIndex); for (int i = rootIndex; i < nbLSF; i++) lsf[i] = 0; // Append the scaling parameter for Schussler LSF if (displacement == 0) lsf[nbLSF - 1] = pk[0]; }