📄 filter.c
字号:
/* * * QccPack: Quantization, compression, and coding libraries * Copyright (C) 1997-2009 James E. Fowler * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * */#include "libQccPack.h"int QccFilterInitialize(QccFilter *filter){ if (filter == NULL) return(0); filter->causality = QCCFILTER_CAUSAL; filter->length = 0; filter->coefficients = NULL; return(0);}int QccFilterAlloc(QccFilter *filter){ if (filter == NULL) return(0); if ((filter->coefficients == NULL) && (filter->length > 0)) if ((filter->coefficients = QccVectorAlloc(filter->length)) == NULL) { QccErrorAddMessage("(QccFilterAlloc): Error calling QccVectorAlloc()"); return(1); } return(0);}void QccFilterFree(QccFilter *filter){ if (filter == NULL) return; QccVectorFree(filter->coefficients); filter->coefficients = NULL;}int QccFilterCopy(QccFilter *filter1, const QccFilter *filter2){ int index; if (filter1 == NULL) return(0); if (filter2 == NULL) return(0); if (filter2->coefficients == NULL) return(0); if (filter1->coefficients == NULL) { filter1->length = filter2->length; if (QccFilterAlloc(filter1)) { QccErrorAddMessage("(QccFilterCopy): Error calling QccFilterAlloc()"); return(1); } } else if (filter1->length != filter2->length) { QccErrorAddMessage("(QccFilterCopy): Filters have different lengths"); return(1); } filter1->causality = filter2->causality; for (index = 0; index < filter1->length; index++) filter1->coefficients[index] = filter2->coefficients[index]; return(0);}int QccFilterReversal(const QccFilter *filter1, QccFilter *filter2){ int index; if (filter1 == NULL) return(0); if (filter2 == NULL) return(0); if (filter1->coefficients == NULL) return(0); if (filter2->coefficients == NULL) return(0); if (filter1->length != filter2->length) { QccErrorAddMessage("(QccFilterReversal): Filters have different lengths"); return(1); } switch (filter1->causality) { case QCCFILTER_CAUSAL: filter2->causality = QCCFILTER_ANTICAUSAL; for (index = 0; index < filter2->length; index++) filter2->coefficients[index] = filter1->coefficients[filter1->length - 1 - index]; break; case QCCFILTER_ANTICAUSAL: filter2->causality = QCCFILTER_CAUSAL; for (index = 0; index < filter2->length; index++) filter2->coefficients[index] = filter1->coefficients[filter1->length - 1 - index]; break; case QCCFILTER_SYMMETRICWHOLE: filter2->causality = QCCFILTER_SYMMETRICWHOLE; for (index = 0; index < filter2->length; index++) filter2->coefficients[index] = filter1->coefficients[index]; break; case QCCFILTER_SYMMETRICHALF: filter2->causality = QCCFILTER_SYMMETRICHALF; for (index = 0; index < filter2->length; index++) filter2->coefficients[index] = filter1->coefficients[index]; break; default: QccErrorAddMessage("(QccFilterReversal): Undefined filter causality"); return(1); } return(0);}int QccFilterAlternateSignFlip(QccFilter *filter){ int index; if (filter == NULL) return(0); if (filter->coefficients == NULL) return(0); for (index = 0; index < filter->length; index += 2) filter->coefficients[index] *= -1; return(0);}int QccFilterRead(FILE *infile, QccFilter *filter){ int index; if (infile == NULL) return(0); if (filter == NULL) return(0); fscanf(infile, "%d", &(filter->causality)); if (ferror(infile) || feof(infile)) goto Error; if (QccFileSkipWhiteSpace(infile, 0)) goto Error; fscanf(infile, "%d", &(filter->length)); if (ferror(infile) || feof(infile)) goto Error; if (QccFileSkipWhiteSpace(infile, 0)) goto Error; if (QccFilterAlloc(filter)) { QccErrorAddMessage("(QccFilterRead): Error calling QccFilterAlloc()"); return(1); } for (index = 0; index < filter->length; index++) { fscanf(infile, "%lf", &(filter->coefficients[index])); if (ferror(infile) || feof(infile)) { QccFilterFree(filter); goto Error; } } return(0); Error: QccErrorAddMessage("(QccFilterRead): Error reading filter"); return(1); }int QccFilterWrite(FILE *outfile, const QccFilter *filter){ int index; if (outfile == NULL) return(0); if (filter == NULL) return(0); fprintf(outfile, "%d\n%d\n", filter->causality, filter->length); for (index = 0; index < filter->length; index++) fprintf(outfile, "% 16.9e\n", filter->coefficients[index]); if (ferror(outfile)) { QccErrorAddMessage("(QccFilterWrite): Error writing filter coefficients"); return(1); } return(0);}int QccFilterPrint(const QccFilter *filter){ if (filter == NULL) return(0); printf(" Causality: "); switch (filter->causality) { case QCCFILTER_CAUSAL: printf(" causal\n"); break; case QCCFILTER_ANTICAUSAL: printf(" anti-causal\n"); break; case QCCFILTER_SYMMETRICWHOLE: printf(" whole-sample symmetric\n"); break; case QCCFILTER_SYMMETRICHALF: printf(" half-sample symmetric\n"); break; } printf(" Coefficients: \n "); QccVectorPrint(filter->coefficients, filter->length); return(0);}static int QccFilterVectorPeriodicExtension(const QccVector input_signal, QccVector output_signal, int length, const QccFilter *filter){ int input_index1; int input_index2; int output_index; int filter_index; switch (filter->causality) { case QCCFILTER_CAUSAL: for (output_index = 0; output_index < length; output_index++) { output_signal[output_index] = 0; for (filter_index = 0; filter_index < filter->length; filter_index++) { input_index1 = QccMathModulus(output_index - filter_index, length); output_signal[output_index] += input_signal[input_index1] * filter->coefficients[filter_index]; } } break; case QCCFILTER_ANTICAUSAL: for (output_index = 0; output_index < length; output_index++) { output_signal[output_index] = 0; for (filter_index = 0; filter_index < filter->length; filter_index++) { input_index1 = QccMathModulus(output_index + filter_index, length); output_signal[output_index] += input_signal[input_index1] * filter->coefficients[filter->length - 1 - filter_index]; } } break; case QCCFILTER_SYMMETRICWHOLE: for (output_index = 0; output_index < length; output_index++) { output_signal[output_index] = input_signal[output_index] * filter->coefficients[0]; for (filter_index = 1; filter_index < filter->length; filter_index++) { input_index1 = QccMathModulus(output_index - filter_index, length); input_index2 = QccMathModulus(output_index + filter_index, length); output_signal[output_index] += (input_signal[input_index1] + input_signal[input_index2]) * filter->coefficients[filter_index]; } } break; case QCCFILTER_SYMMETRICHALF: for (output_index = 0; output_index < length; output_index++) for (filter_index = 0; filter_index < filter->length; filter_index++) { input_index1 = QccMathModulus(output_index - filter_index, length); input_index2 = QccMathModulus(output_index + filter_index + 1, length); output_signal[output_index] += (input_signal[input_index1] + input_signal[input_index2]) * filter->coefficients[filter_index]; } break; default: QccErrorAddMessage("(QccFilterVectorPeriodicExtension): Undefined filter causality (%d)", filter->causality); return(1); } return(0);}int QccFilterCalcSymmetricExtension(int index, int length, int symmetry){ if (symmetry == QCCFILTER_SYMMETRICWHOLE) { if (length > 2) { if ((index < 0) || (index >= (2*length - 2))) index = QccMathModulus(index, 2*length - 2); if (index >= length) index = 2*length - index - 2; } else if ((index < 0) || (index >= length)) index = QccMathModulus(index, length); } else { if (length > 1) { if ((index < 0) || (index >= 2*length)) index = QccMathModulus(index, 2*length); if (index >= length) index = 2*length - index - 1; } else index = 0; } return(index);}static int QccFilterVectorSymmetricExtension(const QccVector input_signal, QccVector output_signal, int length, const QccFilter *filter){ int input_index1; int input_index2; int output_index; int filter_index;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -