📄 filter_bank.c
字号:
return(0); if (filter_bank == NULL) return(0); QccFilterInitialize(&primary_filter); QccFilterInitialize(&dual_filter); switch (filter_bank->orthogonality) { case QCCWAVFILTERBANK_ORTHOGONAL: if (QccFilterRead(infile, &primary_filter)) { QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()"); goto Error; } if (QccWAVFilterBankMakeOrthogonal(filter_bank, &primary_filter)) { QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccWAVFilterBankMakeOrthogonal()"); goto Error; } break; case QCCWAVFILTERBANK_BIORTHOGONAL: if (QccFilterRead(infile, &primary_filter)) { QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()"); goto Error; } if (QccFilterRead(infile, &dual_filter)) { QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()"); goto Error; } if (QccWAVFilterBankMakeBiorthogonal(filter_bank, &primary_filter, &dual_filter)) { QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccWAVFilterBankMakeBiorthogonal()"); goto Error; } break; case QCCWAVFILTERBANK_GENERAL: if (QccFilterRead(infile, &(filter_bank->lowpass_analysis_filter))) { QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()"); goto Error; } if (QccFilterRead(infile, &(filter_bank->highpass_analysis_filter))) { QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()"); goto Error; } if (QccFilterRead(infile, &(filter_bank->lowpass_synthesis_filter))) { QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()"); goto Error; } if (QccFilterRead(infile, &(filter_bank->highpass_synthesis_filter))) { QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()"); goto Error; } break; default: QccErrorAddMessage("(QccWAVFilterBankReadData): Undefined orthogonality"); goto Error; } return_value = 0; goto Return; Error: return_value = 1; Return: QccFilterFree(&primary_filter); QccFilterFree(&dual_filter); return(return_value);}int QccWAVFilterBankRead(QccWAVFilterBank *filter_bank){ FILE *infile = NULL; if (filter_bank == NULL) return(0); if ((infile = QccFileOpen(filter_bank->filename, "r")) == NULL) { QccErrorAddMessage("(QccWAVFilterBankRead): Error calling QccFileOpen()"); return(1); } if (QccWAVFilterBankReadHeader(infile, filter_bank)) { QccErrorAddMessage("(QccWAVFilterBankRead): Error calling QccWAVFilterBankReadHeader()"); return(1); } if (QccWAVFilterBankReadData(infile, filter_bank)) { QccErrorAddMessage("(QccWAVFilterBankRead): Error calling QccWAVFilterBankReadData()"); return(1); } QccFileClose(infile); return(0);}static int QccWAVFilterBankWriteHeader(FILE *outfile, const QccWAVFilterBank *filter_bank){ if ((outfile == NULL) || (filter_bank == NULL)) return(0); if (QccFileWriteMagicNumber(outfile, QCCWAVFILTERBANK_MAGICNUM)) goto Error; fprintf(outfile, "%d\n", filter_bank->orthogonality); if (ferror(outfile)) goto Error; return(0); Error: QccErrorAddMessage("(QccWAVFilterBankWriteHeader): Error writing header to %s", filter_bank->filename); return(1); }static int QccWAVFilterBankWriteData(FILE *outfile, const QccWAVFilterBank *filter_bank){ if (outfile == NULL) return(0); if (filter_bank == NULL) return(0); switch (filter_bank->orthogonality) { case QCCWAVFILTERBANK_ORTHOGONAL: if (QccFilterWrite(outfile, &(filter_bank->lowpass_synthesis_filter))) { QccErrorAddMessage("(QccWAVFilterBankWriteData): Error calling QccFilterWrite()"); return(1); } break; case QCCWAVFILTERBANK_BIORTHOGONAL: if (QccFilterWrite(outfile, &(filter_bank->lowpass_synthesis_filter))) { QccErrorAddMessage("(QccWAVFilterBankWriteData): Error calling QccFilterWrite()"); return(1); } if (QccFilterWrite(outfile, &(filter_bank->lowpass_analysis_filter))) { QccErrorAddMessage("(QccWAVFilterBankWriteData): Error calling QccFilterWrite()"); return(1); } break; case QCCWAVFILTERBANK_GENERAL: if (QccFilterWrite(outfile, &(filter_bank->lowpass_analysis_filter))) { QccErrorAddMessage("(QccWAVFilterBankWriteData): Error calling QccFilterWrite()"); return(1); } if (QccFilterWrite(outfile, &(filter_bank->lowpass_synthesis_filter))) { QccErrorAddMessage("(QccWAVFilterBankWriteData): Error calling QccFilterWrite()"); return(1); } if (QccFilterWrite(outfile, &(filter_bank->highpass_analysis_filter))) { QccErrorAddMessage("(QccWAVFilterBankWriteData): Error calling QccFilterWrite()"); return(1); } if (QccFilterWrite(outfile, &(filter_bank->highpass_synthesis_filter))) { QccErrorAddMessage("(QccWAVFilterBankWriteData): Error calling QccFilterWrite()"); return(1); } break; default: QccErrorAddMessage("(QccWAVFilterBankWriteData): Undefined orthogonality"); return(1); } return(0);}int QccWAVFilterBankWrite(const QccWAVFilterBank *filter_bank){ FILE *outfile; if (filter_bank == NULL) return(0); if ((outfile = QccFileOpen(filter_bank->filename, "w")) == NULL) { QccErrorAddMessage("(QccWAVFilterBankWrite): Error calling QccFileOpen()"); return(1); } if (QccWAVFilterBankWriteHeader(outfile, filter_bank)) { QccErrorAddMessage("(QccWAVFilterBankWrite): Error calling QccWAVFilterBankWriteHeader()"); return(1); } if (QccWAVFilterBankWriteData(outfile, filter_bank)) { QccErrorAddMessage("(QccWAVFilterBankWrite): Error calling QccWAVFilterBankWriteData()"); return(1); } QccFileClose(outfile); return(0);}int QccWAVFilterBankAnalysis(QccVector signal, int signal_length, int phase, const QccWAVFilterBank *filter_bank, int boundary_extension){ int return_value = 0; QccVector lowpass_band; int lowpass_band_length; int lowpass_subsampling; QccVector highpass_band; int highpass_band_length; int highpass_subsampling; QccVector signal2 = NULL; if (signal == NULL) return(0); if (filter_bank == NULL) return(0); if (!signal_length) return(0); if (boundary_extension == QCCWAVWAVELET_BOUNDARY_BOUNDARY_WAVELET) { QccErrorAddMessage("(QccWAVFilterBankAnalysis): Boundary wavelets not supported for filter banks"); goto Error; } if ((filter_bank->orthogonality == QCCWAVFILTERBANK_ORTHOGONAL) && (boundary_extension != QCCWAVWAVELET_BOUNDARY_PERIODIC_EXTENSION)) { QccErrorAddMessage("(QccWAVFilterBankAnalysis): Orthogonal filter banks must use periodic boundary extension"); goto Error; } if ((boundary_extension == QCCWAVWAVELET_BOUNDARY_PERIODIC_EXTENSION) && (signal_length % 2)) { QccErrorAddMessage("(QccWAVFilterBankAnalysis): Signal length must be even for periodic extension"); goto Error; } if (signal_length == 1) { if (phase == QCCWAVFILTERBANK_PHASE_EVEN) signal[0] *= M_SQRT2; else signal[0] /= M_SQRT2; return(0); } if ((signal2 = QccVectorAlloc(signal_length)) == NULL) { QccErrorAddMessage("(QccWAVFilterBankAnalysis): Error calling QccVectorAlloc()"); goto Error; } if (QccVectorCopy(signal2, signal, signal_length)) { QccErrorAddMessage("(QccWAVFilterBankAnalysis): Error calling QccVectorCopy()"); goto Error; } if (signal_length % 2) if (phase == QCCWAVFILTERBANK_PHASE_ODD) lowpass_band_length = signal_length / 2; else lowpass_band_length = signal_length / 2 + 1; else lowpass_band_length = signal_length / 2; if (phase == QCCWAVFILTERBANK_PHASE_ODD) { lowpass_subsampling = QCCFILTER_SUBSAMPLEODD; highpass_subsampling = (filter_bank->orthogonality == QCCWAVFILTERBANK_BIORTHOGONAL) ? QCCFILTER_SUBSAMPLEEVEN : QCCFILTER_SUBSAMPLEODD; } else { lowpass_subsampling = QCCFILTER_SUBSAMPLEEVEN; highpass_subsampling = (filter_bank->orthogonality == QCCWAVFILTERBANK_BIORTHOGONAL) ? QCCFILTER_SUBSAMPLEODD : QCCFILTER_SUBSAMPLEEVEN; } highpass_band_length = signal_length - lowpass_band_length; lowpass_band = signal; highpass_band = &(signal[lowpass_band_length]); if (QccFilterMultiRateFilterVector(signal2, signal_length, lowpass_band, lowpass_band_length, &filter_bank->lowpass_analysis_filter, QCCFILTER_SAMESAMPLING, lowpass_subsampling, boundary_extension)) { QccErrorAddMessage("(QccWAVFilterBankAnalysis): Error calling QccFilterMultiRateFilterVector()"); goto Error; } if (QccFilterMultiRateFilterVector(signal2, signal_length, highpass_band, highpass_band_length, &filter_bank->highpass_analysis_filter, QCCFILTER_SAMESAMPLING, highpass_subsampling,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -