📄 filter_bank.c
字号:
#include "spiht.h"
#include "spihtdecode.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 QccError;
}
if (QccFilterAlloc(&filter_bank->highpass_analysis_filter))
{
QccErrorAddMessage("(QccWAVFilterBankAlloc): Error calling QccFilterAlloc()");
goto QccError;
}
if (QccFilterAlloc(&filter_bank->lowpass_synthesis_filter))
{
QccErrorAddMessage("(QccWAVFilterBankAlloc): Error calling QccFilterAlloc()");
goto QccError;
}
if (QccFilterAlloc(&filter_bank->highpass_synthesis_filter))
{
QccErrorAddMessage("(QccWAVFilterBankAlloc): Error calling QccFilterAlloc()");
goto QccError;
}
return_value = 0;
goto QccReturn;
QccError:
return_value = 1;
QccReturn:
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 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_SYMMETRIC) ||
(dual_filter->causality != QCCFILTER_SYMMETRIC))
{
QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): primary filter and dual filter must by of 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);
}
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)
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 QccError;
}
if (QccWAVFilterBankMakeOrthogonal(filter_bank, &primary_filter))
{
QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccWAVFilterBankMakeOrthogonal()");
goto QccError;
}
break;
case QCCWAVFILTERBANK_BIORTHOGONAL:
if (QccFilterRead(infile,
&primary_filter))
{
QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()");
goto QccError;
}
if (QccFilterRead(infile,
&dual_filter))
{
QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()");
goto QccError;
}
if (QccWAVFilterBankMakeBiorthogonal(filter_bank,
&primary_filter,
&dual_filter))
{
QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccWAVFilterBankMakeBiorthogonal()");
goto QccError;
}
break;
case QCCWAVFILTERBANK_GENERAL:
if (QccFilterRead(infile,
&(filter_bank->lowpass_analysis_filter)))
{
QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()");
goto QccError;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -