📄 filter_bank.c
字号:
if (QccFilterRead(infile,
&(filter_bank->highpass_analysis_filter)))
{
QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()");
goto QccError;
}
if (QccFilterRead(infile,
&(filter_bank->lowpass_synthesis_filter)))
{
QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()");
goto QccError;
}
if (QccFilterRead(infile,
&(filter_bank->lowpass_synthesis_filter)))
{
QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()");
goto QccError;
}
break;
default:
QccErrorAddMessage("(QccWAVFilterBankReadData): Undefined orthogonality");
goto QccError;
}
return_value = 0;
goto QccReturn;
QccError:
return_value = 1;
QccReturn:
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);
}
int QccWAVFilterBankAnalysis(const QccVector input_signal,
QccVector output_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;
if (input_signal == NULL)
return(0);
if (output_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 QccError;
}
if ((filter_bank->orthogonality == QCCWAVFILTERBANK_ORTHOGONAL) &&
(boundary_extension != QCCWAVWAVELET_BOUNDARY_PERIODIC_EXTENSION))
{
QccErrorAddMessage("(QccWAVFilterBankAnalysis): Orthogonal filter banks must use periodic boundary extension");
goto QccError;
}
if ((boundary_extension == QCCWAVWAVELET_BOUNDARY_PERIODIC_EXTENSION) &&
(signal_length % 2))
{
QccErrorAddMessage("(QccWAVFilterBankAnalysis): Signal length must be even for periodic extension");
goto QccError;
}
if (signal_length == 1)
{
if (phase == QCCWAVFILTERBANK_PHASE_EVEN)
output_signal[0] = input_signal[0] * M_SQRT2;
else
output_signal[0] = input_signal[0] / M_SQRT2;
return(0);
}
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 = output_signal;
highpass_band = &(output_signal[lowpass_band_length]);
if (QccFilterMultiRateFilterVector(input_signal,
signal_length,
lowpass_band,
lowpass_band_length,
&filter_bank->lowpass_analysis_filter,
QCCFILTER_SAMESAMPLING,
lowpass_subsampling,
boundary_extension))
{
QccErrorAddMessage("(QccWAVFilterBankAnalysis): Error calling QccFilterMultiRateFilterVector()");
goto QccError;
}
if (QccFilterMultiRateFilterVector(input_signal,
signal_length,
highpass_band,
highpass_band_length,
&filter_bank->highpass_analysis_filter,
QCCFILTER_SAMESAMPLING,
highpass_subsampling,
boundary_extension))
{
QccErrorAddMessage("(QccWAVFilterBankAnalysis): Error calling QccFilterMultiRateFilterVector()");
goto QccError;
}
return_value = 0;
goto QccReturn;
QccError:
return_value = 1;
QccReturn:
return(return_value);
}
int QccWAVFilterBankSynthesis(const QccVector input_signal,
QccVector output_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_upsampling;
QccVector highpass_band;
int highpass_band_length;
int highpass_upsampling;
QccVector temp_vector = NULL;
if (input_signal == NULL)
return(0);
if (output_signal == NULL)
return(0);
if (filter_bank == NULL)
return(0);
if (!signal_length)
return(0);
if (boundary_extension == QCCWAVWAVELET_BOUNDARY_BOUNDARY_WAVELET)
{
QccErrorAddMessage("(QccWAVFilterBankSynthesis): Boundary wavelets not supported for filter banks");
goto QccError;
}
if ((filter_bank->orthogonality == QCCWAVFILTERBANK_ORTHOGONAL) &&
(boundary_extension != QCCWAVWAVELET_BOUNDARY_PERIODIC_EXTENSION))
{
QccErrorAddMessage("(QccWAVFilterBankSynthesis): Orthogonal filter banks must use periodic boundary extension");
goto QccError;
}
if ((boundary_extension == QCCWAVWAVELET_BOUNDARY_PERIODIC_EXTENSION) &&
(signal_length % 2))
{
QccErrorAddMessage("(QccWAVFilterBankSynthesis): Signal length must be even for periodic extension");
goto QccError;
}
if (signal_length == 1)
{
if (phase == QCCWAVFILTERBANK_PHASE_EVEN)
output_signal[0] = input_signal[0] / M_SQRT2;
else
output_signal[0] = input_signal[0] * M_SQRT2;
return(0);
}
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;
highpass_band_length = signal_length - lowpass_band_length;
if (phase == QCCWAVFILTERBANK_PHASE_ODD)
{
lowpass_upsampling = QCCFILTER_UPSAMPLEODD;
highpass_upsampling =
(filter_bank->orthogonality == QCCWAVFILTERBANK_BIORTHOGONAL) ?
QCCFILTER_UPSAMPLEEVEN :
QCCFILTER_UPSAMPLEODD;
}
else
{
lowpass_upsampling = QCCFILTER_UPSAMPLEEVEN;
highpass_upsampling =
(filter_bank->orthogonality == QCCWAVFILTERBANK_BIORTHOGONAL) ?
QCCFILTER_UPSAMPLEODD :
QCCFILTER_UPSAMPLEEVEN;
}
lowpass_band = input_signal;
highpass_band = &(input_signal[lowpass_band_length]);
if ((temp_vector = QccVectorAlloc(signal_length)) == NULL)
{
QccErrorAddMessage("(QccWAVFilterBankSynthesis): Error calling QccVectorAlloc()");
goto QccError;
}
if (QccFilterMultiRateFilterVector(lowpass_band,
lowpass_band_length,
temp_vector,
signal_length,
&filter_bank->lowpass_synthesis_filter,
lowpass_upsampling,
QCCFILTER_SAMESAMPLING,
boundary_extension))
{
QccErrorAddMessage("(QccWAVFilterBankSynthesis): Error calling QccFilterMultiRateFilterVector()");
goto QccError;
}
if (QccFilterMultiRateFilterVector(highpass_band,
highpass_band_length,
output_signal,
signal_length,
&filter_bank->highpass_synthesis_filter,
highpass_upsampling,
QCCFILTER_SAMESAMPLING,
boundary_extension))
{
QccErrorAddMessage("(QccWAVFilterBankSynthesis): Error calling QccFilterMultiRateFilterVector()");
goto QccError;
}
if (QccVectorAdd(output_signal,
temp_vector,
signal_length))
{
QccErrorAddMessage("(QccWAVFilterBankSynthesis): Error calling QccVectorAdd()");
goto QccError;
}
return_value = 0;
goto QccReturn;
QccError:
return_value = 1;
QccReturn:
QccVectorFree(temp_vector);
return(return_value);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -