diff options
Diffstat (limited to 'sms/filters.c')
-rw-r--r-- | sms/filters.c | 190 |
1 files changed, 0 insertions, 190 deletions
diff --git a/sms/filters.c b/sms/filters.c deleted file mode 100644 index 7f31317..0000000 --- a/sms/filters.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG) - * UNIVERSITAT POMPEU FABRA - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -/*! \file filters.c - * \brief various filters - */ - -#include "sms.h" - -/*! \brief coefficient for pre_emphasis filter */ -#define SMS_EMPH_COEF .9 - -/* pre-emphasis filter function, it returns the filtered value - * - * sfloat fInput; sound sample - */ -sfloat sms_preEmphasis(sfloat fInput, SMS_AnalParams *pAnalParams) -{ - if(pAnalParams->preEmphasis) - { - sfloat fOutput = fInput - SMS_EMPH_COEF * pAnalParams->preEmphasisLastValue; - pAnalParams->preEmphasisLastValue = fOutput; - return fOutput; - } - return fInput; -} - -/* de-emphasis filter function, it returns the filtered value - * - * sfloat fInput; sound input - */ -sfloat sms_deEmphasis(sfloat fInput, SMS_SynthParams *pSynthParams) -{ - if(pSynthParams->deEmphasis) - { - sfloat fOutput = fInput + SMS_EMPH_COEF * pSynthParams->deEmphasisLastValue; - pSynthParams->deEmphasisLastValue = fInput; - return fOutput; - } - return fInput; -} - -/*! \brief function to implement a zero-pole filter - * - * \todo will forgetting to reset pD to zero at the beginning of a new analysis - * (when there are multiple analyses within the life of one program) - * cause problems? - * - * \param pFa pointer to numerator coefficients - * \param pFb pointer to denominator coefficients - * \param nCoeff number of coefficients - * \param fInput input sample - * \return value is the filtered sample - */ -static sfloat ZeroPoleFilter(sfloat *pFa, sfloat *pFb, int nCoeff, sfloat fInput ) -{ - double fOut = 0; - int iSection; - static sfloat pD[5] = {0, 0, 0, 0, 0}; - - pD[0] = fInput; - for (iSection = nCoeff-1; iSection > 0; iSection--) - { - fOut = fOut + pFa[iSection] * pD[iSection]; - pD[0] = pD[0] - pFb[iSection] * pD[iSection]; - pD[iSection] = pD [iSection-1]; - } - fOut = fOut + pFa[0] * pD[0]; - return (sfloat) fOut; -} - -/*! \brief function to filter a waveform with a high-pass filter - * - * cutoff =1500 Hz - * - * \todo this filter only works on sample rates up to 48k? - * - * \param sizeResidual size of signal - * \param pResidual pointer to residual signal - * \param iSamplingRate sampling rate of signal - */ -void sms_filterHighPass(int sizeResidual, sfloat *pResidual, int iSamplingRate) -{ - /* cutoff 800Hz */ - static sfloat pFCoeff32k[10] = {0.814255, -3.25702, 4.88553, -3.25702, - 0.814255, 1, -3.58973, 4.85128, -2.92405, 0.66301}; - static sfloat pFCoeff36k[10] = {0.833098, -3.33239, 4.99859, -3.33239, - 0.833098, 1, -3.63528, 4.97089, -3.02934,0.694052}; - static sfloat pFCoeff40k[10] = {0.848475, -3.3939, 5.09085, -3.3939, - 0.848475, 1, -3.67173, 5.068, -3.11597, 0.71991}; - static sfloat pFCoeff441k[10] = {0.861554, -3.44622, 5.16932, -3.44622, - 0.861554, 1, -3.70223, 5.15023, -3.19013, 0.742275}; - static sfloat pFCoeff48k[10] = {0.872061, -3.48824, 5.23236, -3.48824, - 0.872061, 1, -3.72641, 5.21605, -3.25002, 0.76049}; - sfloat *pFCoeff, fSample = 0; - int i; - - if(iSamplingRate <= 32000) - pFCoeff = pFCoeff32k; - else if(iSamplingRate <= 36000) - pFCoeff = pFCoeff36k; - else if(iSamplingRate <= 40000) - pFCoeff = pFCoeff40k; - else if(iSamplingRate <= 44100) - pFCoeff = pFCoeff441k; - else - pFCoeff = pFCoeff48k; - - for(i = 0; i < sizeResidual; i++) - { - /* try to avoid underflow when there is nothing to filter */ - if(i > 0 && fSample == 0 && pResidual[i] == 0) - return; - - fSample = pResidual[i]; - pResidual[i] = ZeroPoleFilter (&pFCoeff[0], &pFCoeff[5], 5, fSample); - } -} - -/*! \brief a spectral filter - * - * filter each point of the current array by the surounding - * points using a triangular window - * - * \param pFArray two dimensional input array - * \param size1 vertical size of pFArray - * \param size2 horizontal size of pFArray - * \param pFOutArray output array of size size1 - */ -void sms_filterArray(sfloat *pFArray, int size1, int size2, sfloat *pFOutArray) -{ - int i, j, iPoint, iFrame, size2_2 = size2-2, size2_1 = size2-1; - sfloat *pFCurrentArray = pFArray + (size2_1) * size1; - sfloat fVal, fWeighting, fTotalWeighting, fTmpVal; - - /* find the filtered envelope */ - for(i = 0; i < size1; i++) - { - fVal = pFCurrentArray[i]; - fTotalWeighting = 1; - /* filter by the surrounding points */ - for(j = 1; j < (size2_2); j++) - { - fWeighting = (sfloat) size2 / (1+ j); - /* filter on the vertical dimension */ - /* consider the lower points */ - iPoint = i - (size2_1) + j; - if(iPoint >= 0) - { - fVal += pFCurrentArray[iPoint] * fWeighting; - fTotalWeighting += fWeighting; - } - /* consider the higher points */ - iPoint = i + (size2_1) - j; - if(iPoint < size1) - { - fVal += pFCurrentArray[iPoint] * fWeighting; - fTotalWeighting += fWeighting; - } - /*filter on the horizontal dimension */ - /* consider the previous points */ - iFrame = j; - fTmpVal = pFArray[iFrame*size1 + i]; - if(fTmpVal) - { - fVal += fTmpVal * fWeighting; - fTotalWeighting += fWeighting; - } - } - /* scale value by weighting */ - pFOutArray[i] = fVal / fTotalWeighting; - } -} |