📄 filter.c
字号:
#include "spiht.h"
#include "spihtdecode.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_SYMMETRIC:
filter2->causality = QCCFILTER_SYMMETRIC;
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 QccError;
if (QccFileSkipWhiteSpace(infile, 0))
goto QccError;
fscanf(infile, "%d", &(filter->length));
if (ferror(infile) || feof(infile))
goto QccError;
if (QccFileSkipWhiteSpace(infile, 0))
goto QccError;
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 QccError;
}
}
return(0);
QccError:
QccErrorAddMessage("(QccFilterRead): Error reading filter");
return(1);
}
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_SYMMETRIC:
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;
default:
QccErrorAddMessage("(QccFilterVectorPeriodicExtension): Undefined filter causality (%d)",
filter->causality);
return(1);
}
return(0);
}
int QccFilterCalcSymmetricExtension(int index, int length)
{
if (length > 2)
{
index = QccMathModulus(index, 2*length - 2);
if (index >= length)
index = 2*length - index - 2;
}
else
index = QccMathModulus(index, length);
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;
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 =
QccFilterCalcSymmetricExtension(output_index - filter_index,
length);
output_signal[output_index] +=
input_signal[input_index1] *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -