upfirdn.cc
#include <octave/config.h>
#include <octave/defun-dld.h>
#include <octave/error.h>
#include <octave/gripes.h>
#include <octave/oct-obj.h>
#include <octave/pager.h>
#include <octave/quit.h>
#include <octave/variables.h>
DEFUN_DLD (upfirdn, args,,
"-*- texinfo -*-\n\
@deftypefn {Loadable Function} {@var{y} =} upfirdn (@var{x},@var{h},@var{p},@var{q})\n\
Upsample, FIR filtering and downsample.@*\n\
@end deftypefn\n")
{
octave_value_list retval;
int nargin = args.length ();
if (nargin < 4)
{
print_usage();
return retval;
}
Matrix x ( args(0).matrix_value () );
if (error_state)
{
gripe_wrong_type_arg("upfirdn",args(0));
return retval;
}
int rx=x.rows();
int cx=x.columns();
bool isrowvector=false;
if ((rx==1)&&(cx>1))
{
x=x.transpose();
rx=x.rows();
cx=x.columns();
isrowvector=true;
}
int Lx=rx;
ColumnVector h( args(1).vector_value() );
if (error_state)
{
gripe_wrong_type_arg("upfirdn",args(1));
return retval;
}
int Lh=h.length();
int p=args(2).int_value();
if (error_state)
{
gripe_wrong_type_arg("upfirdn",args(2));
return retval;
}
int q=args(3).int_value();
if (error_state)
{
gripe_wrong_type_arg("upfirdn",args(3));
return retval;
}
double r=p/((double) q);
int Ly= ceil( ((Lx-1)*p + Lh)/q );
Matrix y(Ly,cx,0.0);
for (int c=0; c<cx; c++)
{
int m=0;
while (m<Ly)
{
int n=floor(m/r);
int lm=(m*q)%p;
int k=0;
double accum=0.0;
do
{
int ix=n-k;
if (ix>=Lx)
{
k++;
continue;
}
int ih=k*p+lm;
if ((ih>=Lh)|(ix<0))
break;
accum += h(ih)*x(ix,c);
k++;
}
while(1);
y(m,c)=accum;
m++;
}
}
if (isrowvector)
y=y.transpose();
retval(0)=y;
}