Cepstrogram Cepstrogram_smooth (Cepstrogram me, double timeAveragingWindow, double quefrencyAveragingWindow) { try { autoCepstrogram thee = (Cepstrogram) Data_copy (me); long numberOfFrames = timeAveragingWindow / my dx; if (numberOfFrames > 1) { // 1. average across time if (numberOfFrames % 2 == 0) { // make symmetric numberOfFrames++; } autoNUMvector<double> qin (1, my nx); autoNUMvector<double> qout (1, my nx); for (long iq = 1; iq <= my ny; iq++) { for (long iframe = 1; iframe <= my nx; iframe++) { qin[iframe] = my z[iq][iframe] * my z[iq][iframe]; } NUMvector_smoothByMovingAverage (qin.peek(), my nx, numberOfFrames, qout.peek()); for (long iframe = 1; iframe <= my nx; iframe++) { thy z[iq][iframe] = sqrt (qout[iframe]); } } } // 2. average across quefrencies long numberOfQuefrencyBins = quefrencyAveragingWindow / my dy; if (numberOfQuefrencyBins > 0) { if (numberOfQuefrencyBins % 2 == 0) { numberOfQuefrencyBins++; } autoNUMvector<double> qin (1, thy ny); autoNUMvector<double> qout (1, thy ny); for (long iframe = 1; iframe <= my nx; iframe++) { for (long iq = 1; iq <= thy ny; iq++) { qin[iq] = thy z[iq][iframe] * thy z[iq][iframe]; //fabs (thy z[iq][iframe]); } NUMvector_smoothByMovingAverage (qin.peek(), thy ny, numberOfQuefrencyBins, qout.peek()); for (long iq = 1; iq <= thy ny; iq++) { thy z[iq][iframe] = sqrt (qout[iq]); } } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": not smoothed."); } }
PowerCepstrogram PowerCepstrogram_smooth (PowerCepstrogram me, double timeAveragingWindow, double quefrencyAveragingWindow) { try { autoPowerCepstrogram thee = (PowerCepstrogram) Data_copy (me); // 1. average across time long numberOfFrames = timeAveragingWindow / my dx; if (numberOfFrames > 1) { autoNUMvector<double> qin (1, my nx); autoNUMvector<double> qout (1, my nx); for (long iq = 1; iq <= my ny; iq++) { for (long iframe = 1; iframe <= my nx; iframe++) { //qin[iframe] = TO10LOG (my z[iq][iframe]); qin[iframe] = thy z[iq][iframe]; } NUMvector_smoothByMovingAverage (qin.peek(), my nx, numberOfFrames, qout.peek()); for (long iframe = 1; iframe <= my nx; iframe++) { //thy z[iq][iframe] = FROMLOG (qout[iframe]); // inverse thy z[iq][iframe] = qout[iframe]; // inverse } } } // 2. average across quefrencies long numberOfQuefrencyBins = quefrencyAveragingWindow / my dy; if (numberOfQuefrencyBins > 1) { autoNUMvector<double> qin (1, thy ny); autoNUMvector<double> qout (1, thy ny); for (long iframe = 1; iframe <= my nx; iframe++) { for (long iq = 1; iq <= thy ny; iq++) { //qin[iq] = TO10LOG (my z[iq][iframe]); qin[iq] = thy z[iq][iframe]; } NUMvector_smoothByMovingAverage (qin.peek(), thy ny, numberOfQuefrencyBins, qout.peek()); for (long iq = 1; iq <= thy ny; iq++) { //thy z[iq][iframe] = FROMLOG (qout[iq]); thy z[iq][iframe] = qout[iq]; } } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": not smoothed."); } }
void PowerCepstrum_smooth_inline (PowerCepstrum me, double quefrencyAveragingWindow, long numberOfIterations) { try { long numberOfQuefrencyBins = (long) floor (quefrencyAveragingWindow / my dx); if (numberOfQuefrencyBins > 1) { autoNUMvector<double> qin (1, my nx); autoNUMvector<double> qout (1, my nx); for (long iq = 1; iq <= my nx; iq ++) { qin [iq] = my z [1] [iq]; } double *xin, *xout; for (long k = 1; k <= numberOfIterations; k ++) { xin = k % 2 == 1 ? qin.peek() : qout.peek (); xout = k % 2 == 1 ? qout.peek () : qin.peek(); NUMvector_smoothByMovingAverage (xin, my nx, numberOfQuefrencyBins, xout); } for (long iq = 1; iq <= my nx; iq++) { my z [1] [iq] = xout [iq]; } } } catch (MelderError) { Melder_throw (me, U": not smoothed."); } }