📄 filter_bank.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 QccWAVFilterBankInitialize(QccWAVFilterBank *filter_bank){ if (filter_bank == NULL) return(0); QccStringMakeNull(filter_bank->filename); QccStringCopy(filter_bank->magic_num, QCCWAVFILTERBANK_MAGICNUM); QccGetQccPackVersion(&filter_bank->major_version, &filter_bank->minor_version, NULL); filter_bank->orthogonality = -1; QccFilterInitialize(&filter_bank->lowpass_analysis_filter); QccFilterInitialize(&filter_bank->highpass_analysis_filter); QccFilterInitialize(&filter_bank->lowpass_synthesis_filter); QccFilterInitialize(&filter_bank->highpass_synthesis_filter); return(0);}int QccWAVFilterBankAlloc(QccWAVFilterBank *filter_bank){ int return_value; if (filter_bank == NULL) return(0); if (QccFilterAlloc(&filter_bank->lowpass_analysis_filter)) { QccErrorAddMessage("(QccWAVFilterBankAlloc): Error calling QccFilterAlloc()"); goto Error; } if (QccFilterAlloc(&filter_bank->highpass_analysis_filter)) { QccErrorAddMessage("(QccWAVFilterBankAlloc): Error calling QccFilterAlloc()"); goto Error; } if (QccFilterAlloc(&filter_bank->lowpass_synthesis_filter)) { QccErrorAddMessage("(QccWAVFilterBankAlloc): Error calling QccFilterAlloc()"); goto Error; } if (QccFilterAlloc(&filter_bank->highpass_synthesis_filter)) { QccErrorAddMessage("(QccWAVFilterBankAlloc): Error calling QccFilterAlloc()"); goto Error; } return_value = 0; goto Return; Error: return_value = 1; Return: return(return_value);}void QccWAVFilterBankFree(QccWAVFilterBank *filter_bank){ if (filter_bank == NULL) return; QccFilterFree(&filter_bank->lowpass_analysis_filter); QccFilterFree(&filter_bank->highpass_analysis_filter); QccFilterFree(&filter_bank->lowpass_synthesis_filter); QccFilterFree(&filter_bank->highpass_synthesis_filter); }int QccWAVFilterBankPrint(const QccWAVFilterBank *filter_bank){ if (filter_bank == NULL) return(0); if (QccFilePrintFileInfo(filter_bank->filename, filter_bank->magic_num, filter_bank->major_version, filter_bank->minor_version)) return(1); switch (filter_bank->orthogonality) { case QCCWAVFILTERBANK_ORTHOGONAL: printf(" Orthogonal filter bank\n\n"); break; case QCCWAVFILTERBANK_BIORTHOGONAL: printf(" Biorthogonal filter bank\n\n"); break; case QCCWAVFILTERBANK_GENERAL: default: break; } printf("---------------- Lowpass Analysis Filter ----------------\n"); if (QccFilterPrint(&filter_bank->lowpass_analysis_filter)) goto Error; printf("---------------- Highpass Analysis Filter ----------------\n"); if (QccFilterPrint(&filter_bank->highpass_analysis_filter)) goto Error; printf("---------------- Lowpass Synthesis Filter ----------------\n"); if (QccFilterPrint(&filter_bank->lowpass_synthesis_filter)) goto Error; printf("---------------- Highpass Synthesis Filter ----------------\n"); if (QccFilterPrint(&filter_bank->highpass_synthesis_filter)) goto Error; return(0); Error: QccErrorAddMessage("(QccWAVFilterBankPrint): Error calling QccFilterPrint()"); return(1);}int QccWAVFilterBankMakeOrthogonal(QccWAVFilterBank *filter_bank, const QccFilter *primary_filter){ if (filter_bank == NULL) return(0); if (primary_filter == NULL) return(0); if (primary_filter->causality != QCCFILTER_CAUSAL) { QccErrorAddMessage("(QccWAVFilterBankMakeOrthogonal): Error primary filter must be causal"); return(1); } filter_bank->lowpass_analysis_filter.length = filter_bank->highpass_analysis_filter.length = filter_bank->lowpass_synthesis_filter.length = filter_bank->highpass_synthesis_filter.length = primary_filter->length; if (QccWAVFilterBankAlloc(filter_bank)) { QccErrorAddMessage("(QccWAVFilterBankMakeOrthogonal): Error calling QccWAVFilterBankAlloc()"); return(1); } /* h[n] */ if (QccFilterCopy(&(filter_bank->lowpass_synthesis_filter), primary_filter)) { QccErrorAddMessage("(QccWAVFilterBankMakeOrthogonal): Error calling QccFilterCopy()"); return(1); } /* h[-n] */ if (QccFilterReversal(&(filter_bank->lowpass_synthesis_filter), &(filter_bank->lowpass_analysis_filter))) { QccErrorAddMessage("(QccWAVFilterBankMakeOrthogonal): Error calling QccFilterReversal()"); return(1); } /* g[n] = (-(-1)^n) * h[N - 1 - n] */ if (QccFilterReversal(&(filter_bank->lowpass_synthesis_filter), &(filter_bank->highpass_synthesis_filter))) { QccErrorAddMessage("(QccWAVFilterBankMakeOrthogonal): Error calling QccFilterReversal()"); return(1); } if (QccFilterAlternateSignFlip(&(filter_bank->highpass_synthesis_filter))) { QccErrorAddMessage("(QccWAVFilterBankMakeOrthogonal): Error calling QccFilterAlternateSignFlip()"); return(1); } filter_bank->highpass_synthesis_filter.causality = filter_bank->lowpass_synthesis_filter.causality; /* g[-n] */ if (QccFilterReversal(&(filter_bank->highpass_synthesis_filter), &(filter_bank->highpass_analysis_filter))) { QccErrorAddMessage("(QccWAVFilterBankMakeOrthogonal): Error calling QccFilterReversal()"); return(1); } return(0);}int QccWAVFilterBankMakeBiorthogonal(QccWAVFilterBank *filter_bank, const QccFilter *primary_filter, const QccFilter *dual_filter){ if (filter_bank == NULL) return(0); if (primary_filter == NULL) return(0); if (dual_filter == NULL) return(0); if ((primary_filter->causality != QCCFILTER_SYMMETRICWHOLE) || (dual_filter->causality != QCCFILTER_SYMMETRICWHOLE)) { QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): primary filter and dual filter must by of whole-sample symmetric causality"); return(1); } filter_bank->lowpass_synthesis_filter.length = filter_bank->highpass_analysis_filter.length = primary_filter->length; filter_bank->highpass_synthesis_filter.length = filter_bank->lowpass_analysis_filter.length = dual_filter->length; if (QccWAVFilterBankAlloc(filter_bank)) { QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): Error calling QccWAVFilterBankAlloc()"); return(1); } /* h[n] */ if (QccFilterCopy(&(filter_bank->lowpass_synthesis_filter), primary_filter)) { QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): Error calling QccFilterCopy()"); return(1); } /* ~h[-n] */ if (QccFilterCopy(&(filter_bank->lowpass_analysis_filter), dual_filter)) { QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): Error calling QccFilterCopy()"); return(1); } /* ~g[-n] */ if (QccFilterCopy(&(filter_bank->highpass_analysis_filter), primary_filter)) { QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): Error calling QccFilterCopy()"); return(1); } if (QccFilterAlternateSignFlip(&(filter_bank->highpass_analysis_filter))) { QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): Error calling QccFilterAlternateSignFlip()"); return(1); } /* g[n] */ if (QccFilterCopy(&(filter_bank->highpass_synthesis_filter), dual_filter)) { QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): Error calling QccFilterCopy()"); return(1); } if (QccFilterAlternateSignFlip(&(filter_bank->highpass_synthesis_filter))) { QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): Error calling QccFilterAlternateSignFlip()"); return(1); } return(0);}int QccWAVFilterBankBiorthogonal(const QccWAVFilterBank *filter_bank){ return(filter_bank->orthogonality == QCCWAVFILTERBANK_BIORTHOGONAL);}static int QccWAVFilterBankReadHeader(FILE *infile, QccWAVFilterBank *filter_bank){ if ((infile == NULL) || (filter_bank == NULL)) return(0); if (QccFileReadMagicNumber(infile, filter_bank->magic_num, &filter_bank->major_version, &filter_bank->minor_version)) { QccErrorAddMessage("(QccWAVFilterBankReadHeader): Error reading magic number in filter bank %s", filter_bank->filename); return(1); } if (strcmp(filter_bank->magic_num, QCCWAVFILTERBANK_MAGICNUM)) { QccErrorAddMessage("(QccWAVFilterBankReadHeader): %s is not of filter-bank (%s) type", filter_bank->filename, QCCWAVFILTERBANK_MAGICNUM); return(1); } fscanf(infile, "%d", &(filter_bank->orthogonality)); if (ferror(infile) || feof(infile)) { QccErrorAddMessage("(QccWAVFilterBankReadHeader): Error reading filter-bank orthogonality in filter bank %s", filter_bank->filename); return(1); } if (QccFileSkipWhiteSpace(infile, 0)) { QccErrorAddMessage("(QccWAVFilterBankReadHeader): Error reading filter-bank orthogonality in filter bank %s", filter_bank->filename); return(1); } return(0);}static int QccWAVFilterBankReadData(FILE *infile, QccWAVFilterBank *filter_bank){ int return_value; QccFilter primary_filter; QccFilter dual_filter; if (infile == NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -