Updated 8-point interpolation
This commit is contained in:
@@ -53,7 +53,7 @@ WINDOSOBJ=${DOSDIR}/debug.o ${DOSDIR}/joy.o ${DOSDIR}/modemrtn.o ${DOSDIR}/vesa2
|
||||
|
||||
#PREOBJ=${OBJDIR}/unzip.o ${OBJDIR}/zzip.o ${DOSDIR}/zsipx.o
|
||||
|
||||
ZIPOBJ=${ZIPDIR}/zzip.o ${ZIPDIR}/unzip.o ${ZIPDIR}/zpng.o ${ZIPDIR}/fir_proc.o
|
||||
ZIPOBJ=${ZIPDIR}/zzip.o ${ZIPDIR}/unzip.o ${ZIPDIR}/zpng.o
|
||||
|
||||
MAINOBJ=cfgload.o endmem.o fixsin.o init.o ui.o vcache.o water.o
|
||||
|
||||
@@ -78,7 +78,6 @@ ALL: @ZSNESEXE@
|
||||
${ZIPDIR}/zpng.o: ${ZIPDIR}/zpng.c ${ZIPDIR}/zpng.h
|
||||
${ZIPDIR}/unzip.o: ${ZIPDIR}/unzip.c ${ZIPDIR}/unzip.h
|
||||
${ZIPDIR}/zzip.o: ${ZIPDIR}/zzip.c ${ZIPDIR}/unzip.h
|
||||
${ZIPDIR}/fir_proc.o: ${ZIPDIR}/fir_proc.cpp
|
||||
fixsin.o: fixsin.c
|
||||
water.o: water.c
|
||||
${VIDEODIR}/procvid.o: ${VIDEODIR}/procvid.asm macros.mac ${VIDEODIR}/copyvid.inc ${VIDEODIR}/2xsaimmx.inc
|
||||
|
||||
@@ -381,6 +381,8 @@ CubicSpline:
|
||||
dw -3, -3, -2, -2, -2, -1, -1, -1
|
||||
dw 0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
||||
%include "cpu/fir_tables.inc"
|
||||
|
||||
ALIGN32
|
||||
|
||||
NEWSYM spcWptr, times 16 dd 0 ; SPC Write pointers (point to their own functions)
|
||||
@@ -1765,7 +1767,6 @@ section .text
|
||||
%endmacro
|
||||
|
||||
;EXTSYM fir_downsample
|
||||
EXTSYM fir_lut_co
|
||||
|
||||
%macro ProcessDynamicLowPass 0
|
||||
mov ecx,[curvoice]
|
||||
@@ -1954,7 +1955,7 @@ ALIGN16
|
||||
sub edx,0F80000h
|
||||
shr edx,15
|
||||
and edx,7FFF0h
|
||||
add edx,[fir_lut_co]
|
||||
add edx,fir_lut_co
|
||||
movq mm2,[edx]
|
||||
movq mm3,[edx+8]
|
||||
%%DLPF_fir_loop
|
||||
@@ -3550,8 +3551,6 @@ WaveIndex times 8 dd 0
|
||||
; add eax,edx ;
|
||||
;%%DontFilter1 ;
|
||||
|
||||
EXTSYM fir_lut
|
||||
|
||||
section .data
|
||||
NEWSYM fir_tmp,dd 0,0
|
||||
section .text
|
||||
@@ -3609,7 +3608,7 @@ section .text
|
||||
add ebx,1000h
|
||||
shr ebx,9
|
||||
and ebx,0FFF0h
|
||||
add ebx,[fir_lut]
|
||||
add ebx,fir_lut
|
||||
movq mm0,[eax+PSampleBuf+(%1*26*4)]
|
||||
packssdw mm0,[eax+PSampleBuf+(%1*26*4)+8]
|
||||
movq mm1,[eax+PSampleBuf+(%1*26*4)+16]
|
||||
|
||||
6149
zsnes/src/cpu/fir_tables.inc
Normal file
6149
zsnes/src/cpu/fir_tables.inc
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
||||
/Fezsnesw.exe chips\dsp1proc.obj dos\sw.obj dos\gppro.obj dos\vesa12.obj dos\zsipx.obj dos\modemrtn.obj dos\joy.obj dos\debug.obj dos\vesa2.obj dos\initvid.obj cfgload.obj endmem.obj fixsin.obj init.obj ui.obj vcache.obj water.obj video\procvid.obj win\copyvwin.obj win\winintrf.obj win\winlink.obj win\zloaderw.obj win\ztcp.obj win\zfilew.obj win\zipxw.obj video\makev16b.obj video\makev16t.obj video\makevid.obj video\mode716.obj video\mode716b.obj video\mode716d.obj video\mode716e.obj video\mode716t.obj video\mode7.obj video\mode7ext.obj video\mv16tms.obj video\newg162.obj video\newgfx16.obj video\newgfx2.obj video\newgfx.obj video\m716text.obj video\2xsaiw.obj gui\gui.obj gui\menu.obj cpu\addrni.obj cpu\dma.obj cpu\dsp.obj cpu\dspproc.obj cpu\execute.obj cpu\irq.obj cpu\memory.obj cpu\spc700.obj cpu\stable.obj cpu\table.obj cpu\tableb.obj cpu\tablec.obj chips\dsp1emu.obj chips\fxemu2.obj chips\fxemu2b.obj chips\fxemu2c.obj chips\fxtable.obj chips\sa1proc.obj chips\sa1regs.obj chips\sfxproc.obj zip\unzip.obj zip\zzip.obj zip\zpng.obj zip\fir_proc.obj obj\libpng.lib zlib.lib wsock32.lib user32.lib gdi32.lib shell32.lib winmm.lib ddraw.lib dsound.lib dinput8.lib d3dx.lib /link /section:.text,erw
|
||||
/Fezsnesw.exe chips\dsp1proc.obj dos\sw.obj dos\gppro.obj dos\vesa12.obj dos\zsipx.obj dos\modemrtn.obj dos\joy.obj dos\debug.obj dos\vesa2.obj dos\initvid.obj cfgload.obj endmem.obj fixsin.obj init.obj ui.obj vcache.obj water.obj video\procvid.obj win\copyvwin.obj win\winintrf.obj win\winlink.obj win\zloaderw.obj win\ztcp.obj win\zfilew.obj win\zipxw.obj video\makev16b.obj video\makev16t.obj video\makevid.obj video\mode716.obj video\mode716b.obj video\mode716d.obj video\mode716e.obj video\mode716t.obj video\mode7.obj video\mode7ext.obj video\mv16tms.obj video\newg162.obj video\newgfx16.obj video\newgfx2.obj video\newgfx.obj video\m716text.obj video\2xsaiw.obj gui\gui.obj gui\menu.obj cpu\addrni.obj cpu\dma.obj cpu\dsp.obj cpu\dspproc.obj cpu\execute.obj cpu\irq.obj cpu\memory.obj cpu\spc700.obj cpu\stable.obj cpu\table.obj cpu\tableb.obj cpu\tablec.obj chips\dsp1emu.obj chips\fxemu2.obj chips\fxemu2b.obj chips\fxemu2c.obj chips\fxtable.obj chips\sa1proc.obj chips\sa1regs.obj chips\sfxproc.obj zip\unzip.obj zip\zzip.obj zip\zpng.obj obj\libpng.lib zlib.lib wsock32.lib user32.lib gdi32.lib shell32.lib winmm.lib ddraw.lib dsound.lib dinput8.lib d3dx.lib /link /section:.text,erw
|
||||
|
||||
@@ -52,7 +52,7 @@ WINOBJ=${WINDIR}/copywin.o ${WINDIR}/winintrf.o ${WINDIR}/winlink.o\
|
||||
|
||||
PREOBJ=${OBJDIR}/dosbuff.o ${OBJDIR}/ipx.o ${OBJDIR}/zipx.o
|
||||
|
||||
ZIPOBJ=${ZIPDIR}/zzip.o ${ZIPDIR}/unzip.o ${ZIPDIR}/zpng.o ${ZIPDIR}/fir_proc.o
|
||||
ZIPOBJ=${ZIPDIR}/zzip.o ${ZIPDIR}/unzip.o ${ZIPDIR}/zpng.o
|
||||
|
||||
MAINOBJ=cfgload.o endmem.o fixsin.o init.o ui.o vcache.o water.o
|
||||
|
||||
@@ -94,7 +94,6 @@ ${DOSDIR}/zfile.o: ${DOSDIR}/zfile.c
|
||||
${ZIPDIR}/unzip.o: ${ZIPDIR}/unzip.c ${ZIPDIR}/unzip.h
|
||||
${ZIPDIR}/zzip.o: ${ZIPDIR}/zzip.c ${ZIPDIR}/unzip.h
|
||||
${ZIPDIR}/zpng.o: ${ZIPDIR}/zpng.c ${ZIPDIR}/zpng.h ${ZIPDIR}/png.h
|
||||
${ZIPDIR}/fir_proc.o: ${ZIPDIR}/fir_proc.cpp
|
||||
${VIDEODIR}/procvid.o: ${VIDEODIR}/procvid.asm macros.mac ${VIDEODIR}/copyvid.inc ${VIDEODIR}/2xSaImmx.inc
|
||||
${CHIPDIR}/dsp1proc.o: ${CHIPDIR}/dsp1proc.asm macros.mac
|
||||
${CHIPDIR}/sa1regs.o: ${CHIPDIR}/sa1regs.asm macros.mac\
|
||||
|
||||
@@ -61,13 +61,13 @@ WINDOSOBJ=${DOSDIR}/debug.obj ${DOSDIR}/joy.obj ${DOSDIR}/modemrtn.obj ${DOSDIR}
|
||||
|
||||
PREOBJ=
|
||||
|
||||
ZIPOBJ=${ZIPDIR}/zzip.obj ${ZIPDIR}/unzip.obj ${ZIPDIR}/zpng.obj ${ZIPDIR}/fir_proc.obj
|
||||
ZIPOBJ=${ZIPDIR}/zzip.obj ${ZIPDIR}/unzip.obj ${ZIPDIR}/zpng.obj
|
||||
|
||||
MAINOBJ=cfgload.obj endmem.obj fixsin.obj init.obj ui.obj vcache.obj water.obj
|
||||
|
||||
OBJS=${CHIPSOBJ} ${CPUOBJ} ${WINOBJ} ${GUIOBJ} ${VIDEOBJ} ${ZIPOBJ} ${MAINOBJ} ${WINDOSOBJ}
|
||||
LIBS=
|
||||
CFLAGS=/O2pt /G6 /c /D__WIN32__
|
||||
CFLAGS=/O2t /G6 /c /D__WIN32__
|
||||
ASM=nasm
|
||||
ASMFLAGS=-f win32 -D__WIN32__
|
||||
CC=cl
|
||||
@@ -100,7 +100,6 @@ ${WINDIR}/winlink.obj: ${WINDIR}/winlink.cpp ${WINDIR}/resource.h
|
||||
${ZIPDIR}/unzip.obj: ${ZIPDIR}/unzip.c ${ZIPDIR}/unzip.h
|
||||
${ZIPDIR}/zzip.obj: ${ZIPDIR}/zzip.c ${ZIPDIR}/unzip.h
|
||||
${ZIPDIR}/zpng.obj: ${ZIPDIR}/zpng.c ${ZIPDIR}/zpng.h ${ZIPDIR}/png.h
|
||||
${ZIPDIR}/fir_proc.obj: ${ZIPDIR}/fir_proc.cpp
|
||||
${DOSDIR}/initvid.o:${DOSDIR}/initvid.asm macros.mac
|
||||
${DOSDIR}/modemrtn.o: ${DOSDIR}/modemrtn.asm macros.mac
|
||||
${DOSDIR}/zsipx.o: ${DOSDIR}/zsipx.asm
|
||||
|
||||
@@ -1,335 +0,0 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the license or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Authors: Markus Fick <webmaster@mark-f.de> fir-resampler
|
||||
* Chris Moeller <chris@kode54.net> C/C++ fir_interpolate functions based off original macros
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __LINUX__
|
||||
#include "../gblhdr.h"
|
||||
#else
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifndef log2
|
||||
inline float log2(float f) {
|
||||
float t;
|
||||
#ifdef __GNUC__
|
||||
__asm__ ("
|
||||
fld1\n
|
||||
fxch\n
|
||||
fyl2x\n
|
||||
fst (%1)"
|
||||
:
|
||||
: "st" (f), "r" (&t)
|
||||
);
|
||||
#else
|
||||
__asm {
|
||||
fld1
|
||||
fld f
|
||||
fyl2x
|
||||
fstp t
|
||||
}
|
||||
#endif
|
||||
return t;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------------------------
|
||||
fir interpolation doc,
|
||||
(derived from "an engineer's guide to fir digital filters", n.j. loy)
|
||||
|
||||
calculate coefficients for ideal lowpass filter (with cutoff = fc in 0..1 (mapped to 0..nyquist))
|
||||
c[-N..N] = (i==0) ? fc : sin(fc*pi*i)/(pi*i)
|
||||
|
||||
then apply selected window to coefficients
|
||||
c[-N..N] *= w(0..N)
|
||||
with n in 2*N and w(n) being a window function (see loy)
|
||||
|
||||
then calculate gain and scale filter coefs to have unity gain.
|
||||
------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
// quantizer scale of window coefs
|
||||
#define WFIR_QUANTBITS 14
|
||||
#define WFIR_QUANTSCALE (1L<<WFIR_QUANTBITS)
|
||||
#define WFIR_8SHIFT (WFIR_QUANTBITS-8)
|
||||
#define WFIR_16BITSHIFT (WFIR_QUANTBITS)
|
||||
// log2(number)-1 of precalculated taps range is [4..12]
|
||||
#define WFIR_FRACBITS 10
|
||||
#define WFIR_LUTLEN ((1L<<(WFIR_FRACBITS+1))+1)
|
||||
// number of samples in window
|
||||
#define WFIR_LOG2WIDTH 3
|
||||
#define WFIR_WIDTH (1L<<WFIR_LOG2WIDTH)
|
||||
#define WFIR_SMPSPERWING ((WFIR_WIDTH-1)>>1)
|
||||
// cutoff (1.0 == pi/2)
|
||||
#define WFIR_CUTOFF 0.90f
|
||||
#define WFIR_CUTOFFBITS 12
|
||||
#define WFIR_CUTOFFLEN ((1L<<(WFIR_CUTOFFBITS))+1)
|
||||
// wfir type
|
||||
#define WFIR_HANN 0
|
||||
#define WFIR_HAMMING 1
|
||||
#define WFIR_BLACKMANEXACT 2
|
||||
#define WFIR_BLACKMAN3T61 3
|
||||
#define WFIR_BLACKMAN3T67 4
|
||||
#define WFIR_BLACKMAN4T92 5
|
||||
#define WFIR_BLACKMAN4T74 6
|
||||
#define WFIR_KAISER4T 7
|
||||
#define WFIR_TYPE WFIR_BLACKMANEXACT
|
||||
// wfir help
|
||||
#ifndef M_zPI
|
||||
#define M_zPI 3.1415926535897932384626433832795
|
||||
#endif
|
||||
#define M_zEPS 1e-8
|
||||
#define M_zBESSELEPS 1e-21
|
||||
|
||||
class CzWINDOWEDFIR
|
||||
{ public:
|
||||
CzWINDOWEDFIR( );
|
||||
~CzWINDOWEDFIR( );
|
||||
float coef( int _PCnr, float _POfs, float _PCut, int _PWidth, int _PType ) //float _PPos, float _PFc, int _PLen )
|
||||
{ double _LWidthM1 = _PWidth-1;
|
||||
double _LWidthM1Half = 0.5*_LWidthM1;
|
||||
double _LPosU = ((double)_PCnr - _POfs);
|
||||
double _LPos = _LPosU-_LWidthM1Half;
|
||||
double _LPIdl = 2.0*M_zPI/_LWidthM1;
|
||||
double _LWc,_LSi;
|
||||
if( fabs(_LPos)<M_zEPS )
|
||||
{ _LWc = 1.0;
|
||||
_LSi = _PCut;
|
||||
}
|
||||
else
|
||||
{ switch( _PType )
|
||||
{ case WFIR_HANN:
|
||||
_LWc = 0.50 - 0.50 * cos(_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_HAMMING:
|
||||
_LWc = 0.54 - 0.46 * cos(_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMANEXACT:
|
||||
_LWc = 0.42 - 0.50 * cos(_LPIdl*_LPosU) + 0.08 * cos(2.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN3T61:
|
||||
_LWc = 0.44959 - 0.49364 * cos(_LPIdl*_LPosU) + 0.05677 * cos(2.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN3T67:
|
||||
_LWc = 0.42323 - 0.49755 * cos(_LPIdl*_LPosU) + 0.07922 * cos(2.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN4T92:
|
||||
_LWc = 0.35875 - 0.48829 * cos(_LPIdl*_LPosU) + 0.14128 * cos(2.0*_LPIdl*_LPosU) - 0.01168 * cos(3.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN4T74:
|
||||
_LWc = 0.40217 - 0.49703 * cos(_LPIdl*_LPosU) + 0.09392 * cos(2.0*_LPIdl*_LPosU) - 0.00183 * cos(3.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_KAISER4T:
|
||||
_LWc = 0.40243 - 0.49804 * cos(_LPIdl*_LPosU) + 0.09831 * cos(2.0*_LPIdl*_LPosU) - 0.00122 * cos(3.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
default:
|
||||
_LWc = 1.0;
|
||||
break;
|
||||
}
|
||||
_LPos *= M_zPI;
|
||||
_LSi = sin(_PCut*_LPos)/_LPos;
|
||||
}
|
||||
return (float)(_LWc*_LSi);
|
||||
}
|
||||
static signed short lut[WFIR_LUTLEN*WFIR_WIDTH];
|
||||
static signed short lut_co[WFIR_CUTOFFLEN*WFIR_WIDTH];
|
||||
};
|
||||
|
||||
signed short CzWINDOWEDFIR::lut[WFIR_LUTLEN*WFIR_WIDTH];
|
||||
signed short CzWINDOWEDFIR::lut_co[WFIR_CUTOFFLEN*WFIR_WIDTH];
|
||||
|
||||
CzWINDOWEDFIR::CzWINDOWEDFIR()
|
||||
{ int _LPcl;
|
||||
float _LPcllen = (float)(1L<<WFIR_FRACBITS); // number of precalculated lines for 0..1 (-1..0)
|
||||
float _LNorm = 1.0f / (float)(2.0f * _LPcllen);
|
||||
float _LCut = WFIR_CUTOFF;
|
||||
float _LScale = (float)WFIR_QUANTSCALE;
|
||||
float _LGain,_LCoefs[WFIR_WIDTH];
|
||||
for( _LPcl=0;_LPcl<WFIR_LUTLEN;_LPcl++ )
|
||||
{
|
||||
float _LOfs = ((float)_LPcl-_LPcllen)*_LNorm;
|
||||
int _LCc,_LIdx = _LPcl<<WFIR_LOG2WIDTH;
|
||||
for( _LCc=0,_LGain=0.0f;_LCc<WFIR_WIDTH;_LCc++ )
|
||||
{ _LGain += (_LCoefs[_LCc] = coef( _LCc, _LOfs, _LCut, WFIR_WIDTH, WFIR_TYPE ));
|
||||
}
|
||||
_LGain = 1.0f/_LGain;
|
||||
for( _LCc=0;_LCc<WFIR_WIDTH;_LCc++ )
|
||||
{ float _LCoef = (float)floor( 0.5 + _LScale*_LCoefs[_LCc]*_LGain );
|
||||
lut[_LIdx+_LCc] = (signed short)( (_LCoef<-_LScale)?-_LScale:((_LCoef>_LScale)?_LScale:_LCoef) );
|
||||
}
|
||||
}
|
||||
for( _LPcl=0;_LPcl<WFIR_CUTOFFLEN;_LPcl++ )
|
||||
{
|
||||
int _LCc,_LIdx = _LPcl<<WFIR_LOG2WIDTH;
|
||||
_LCut = 1.0f - pow((float)_LPcl / WFIR_CUTOFFLEN,1/5.0f); // bleh (1.0f + 5.0f * (log2(2.0f + (_LPcl / (WFIR_CUTOFFLEN / 256.0f))) - 1.0f));
|
||||
for(_LCc=0,_LGain=0.0f;_LCc<WFIR_WIDTH;_LCc++ )
|
||||
{
|
||||
_LGain += (_LCoefs[_LCc] = coef( _LCc, -0.5f, _LCut, WFIR_WIDTH, WFIR_TYPE ));
|
||||
}
|
||||
_LGain = 1.0f/_LGain;
|
||||
for( _LCc=0; _LCc<WFIR_WIDTH;_LCc++ )
|
||||
{
|
||||
float _LCoef = (float)floor( 0.5 + _LScale*_LCoefs[_LCc]*_LGain );
|
||||
lut_co[_LIdx+_LCc] = (signed short)( (_LCoef<-_LScale)?-_LScale:((_LCoef>_LScale)?_LScale:_LCoef) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CzWINDOWEDFIR::~CzWINDOWEDFIR()
|
||||
{ // nothing todo
|
||||
}
|
||||
|
||||
/*
|
||||
float coef( int _PCnr, float _POfs, float _PCut, int _PWidth, int _PType ) //float _PPos, float _PFc, int _PLen )
|
||||
{
|
||||
double _LWidthM1 = _PWidth-1;
|
||||
double _LWidthM1Half = 0.5*_LWidthM1;
|
||||
double _LPosU = ((double)_PCnr - _POfs);
|
||||
double _LPos = _LPosU-_LWidthM1Half;
|
||||
double _LPIdl = 2.0*M_zPI/_LWidthM1;
|
||||
double _LWc,_LSi;
|
||||
if( fabs(_LPos)<M_zEPS )
|
||||
{ _LWc = 1.0;
|
||||
_LSi = _PCut;
|
||||
}
|
||||
else
|
||||
{ switch( _PType )
|
||||
{ case WFIR_HANN:
|
||||
_LWc = 0.50 - 0.50 * cos(_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_HAMMING:
|
||||
_LWc = 0.54 - 0.46 * cos(_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMANEXACT:
|
||||
_LWc = 0.42 - 0.50 * cos(_LPIdl*_LPosU) + 0.08 * cos(2.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN3T61:
|
||||
_LWc = 0.44959 - 0.49364 * cos(_LPIdl*_LPosU) + 0.05677 * cos(2.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN3T67:
|
||||
_LWc = 0.42323 - 0.49755 * cos(_LPIdl*_LPosU) + 0.07922 * cos(2.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN4T92:
|
||||
_LWc = 0.35875 - 0.48829 * cos(_LPIdl*_LPosU) + 0.14128 * cos(2.0*_LPIdl*_LPosU) - 0.01168 * cos(3.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN4T74:
|
||||
_LWc = 0.40217 - 0.49703 * cos(_LPIdl*_LPosU) + 0.09392 * cos(2.0*_LPIdl*_LPosU) - 0.00183 * cos(3.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_KAISER4T:
|
||||
_LWc = 0.40243 - 0.49804 * cos(_LPIdl*_LPosU) + 0.09831 * cos(2.0*_LPIdl*_LPosU) - 0.00122 * cos(3.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
default:
|
||||
_LWc = 1.0;
|
||||
break;
|
||||
}
|
||||
_LPos *= M_zPI;
|
||||
_LSi = sin(_PCut*_LPos)/_LPos;
|
||||
}
|
||||
return (float)(_LWc*_LSi);
|
||||
}
|
||||
*/
|
||||
|
||||
CzWINDOWEDFIR sfir;
|
||||
|
||||
extern "C" signed short *fir_lut = &CzWINDOWEDFIR::lut[0];
|
||||
extern "C" signed short *fir_lut_co = &CzWINDOWEDFIR::lut_co[0];
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
// fir interpolation
|
||||
#define WFIR_FRACSHIFT (16-(WFIR_FRACBITS+1+WFIR_LOG2WIDTH))
|
||||
#define WFIR_FRACMASK ((((1L<<(17-WFIR_FRACSHIFT))-1)&~((1L<<WFIR_LOG2WIDTH)-1)))
|
||||
#define WFIR_FRACHALVE (1L<<(16-(WFIR_FRACBITS+2)))
|
||||
|
||||
inline int __fir_interpolate(unsigned int nPos, int *p)
|
||||
{
|
||||
int poshi = nPos >> 24;
|
||||
int poslo = ((nPos >> 8) & 0xFFFF);
|
||||
int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK;
|
||||
int vol = (CzWINDOWEDFIR::lut[firidx+0]*p[poshi+0]);
|
||||
vol += (CzWINDOWEDFIR::lut[firidx+1]*p[poshi+1]);
|
||||
vol += (CzWINDOWEDFIR::lut[firidx+2]*p[poshi+2]);
|
||||
vol += (CzWINDOWEDFIR::lut[firidx+3]*p[poshi+3]);
|
||||
vol += (CzWINDOWEDFIR::lut[firidx+4]*p[poshi+4]);
|
||||
vol += (CzWINDOWEDFIR::lut[firidx+5]*p[poshi+5]);
|
||||
vol += (CzWINDOWEDFIR::lut[firidx+6]*p[poshi+6]);
|
||||
vol += (CzWINDOWEDFIR::lut[firidx+7]*p[poshi+7]);
|
||||
vol >>= WFIR_16BITSHIFT;
|
||||
|
||||
return vol;
|
||||
}
|
||||
|
||||
extern "C" int fir_interpolate(unsigned int nPos, int *p)
|
||||
{
|
||||
return __fir_interpolate(nPos, p);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
#define WFIR_CUTOFFSHIFT (32-(WFIR_CUTOFFBITS+1+WFIR_LOG2WIDTH))
|
||||
#define WFIR_CUTOFFMASK ((((1L<<(33-WFIR_CUTOFFSHIFT))-1)&~((1L<<WFIR_LOG2WIDTH)-1)))
|
||||
#define WFIR_CUTOFFHALVE (1L<<(32-(WFIR_CUTOFFBITS+1)))
|
||||
|
||||
inline void __fir_downsample(unsigned int freq, signed int *p, signed short *out)
|
||||
{
|
||||
/*
|
||||
float cutoff = WFIR_CUTOFF / (1.0f + log2((float)freq / 16777216.0f));
|
||||
float _LGain, _LCoefs[WFIR_WIDTH];
|
||||
int _LCc;
|
||||
for(_LCc=0,_LGain=0.0f;_LCc<WFIR_WIDTH;_LCc++ )
|
||||
{
|
||||
_LGain += (_LCoefs[_LCc] = coef( _LCc, -0.5f, cutoff, WFIR_WIDTH, WFIR_TYPE ));
|
||||
}
|
||||
_LGain = 1.0f/_LGain;
|
||||
for(int ct=0;ct<16;ct++)
|
||||
{
|
||||
signed int vol;
|
||||
float acc = (_LCoefs[0] * _LGain * (float)p[ct+0]);
|
||||
acc += (_LCoefs[1] * _LGain * (float)p[ct+1]);
|
||||
acc += (_LCoefs[2] * _LGain * (float)p[ct+2]);
|
||||
acc += (_LCoefs[3] * _LGain * (float)p[ct+3]);
|
||||
acc += (_LCoefs[4] * _LGain * (float)p[ct+4]);
|
||||
acc += (_LCoefs[5] * _LGain * (float)p[ct+5]);
|
||||
acc += (_LCoefs[6] * _LGain * (float)p[ct+6]);
|
||||
acc += (_LCoefs[7] * _LGain * (float)p[ct+7]);
|
||||
|
||||
vol = (signed int)acc;
|
||||
if (vol > 32767) vol=32767;
|
||||
else if (vol < -32768) vol=-32768;
|
||||
out[ct]=(signed short)vol;
|
||||
}
|
||||
*/
|
||||
int firidx = (((freq-16777216)+WFIR_CUTOFFHALVE)>>WFIR_CUTOFFSHIFT) & WFIR_CUTOFFMASK;
|
||||
for(int ct=0;ct<16;ct++)
|
||||
{
|
||||
int vol = (CzWINDOWEDFIR::lut_co[firidx+0]*p[ct+0]);
|
||||
vol += (CzWINDOWEDFIR::lut_co[firidx+1]*p[ct+1]);
|
||||
vol += (CzWINDOWEDFIR::lut_co[firidx+2]*p[ct+2]);
|
||||
vol += (CzWINDOWEDFIR::lut_co[firidx+3]*p[ct+3]);
|
||||
vol += (CzWINDOWEDFIR::lut_co[firidx+4]*p[ct+4]);
|
||||
vol += (CzWINDOWEDFIR::lut_co[firidx+5]*p[ct+5]);
|
||||
vol += (CzWINDOWEDFIR::lut_co[firidx+6]*p[ct+6]);
|
||||
vol += (CzWINDOWEDFIR::lut_co[firidx+7]*p[ct+7]);
|
||||
vol >>= WFIR_16BITSHIFT;
|
||||
if (vol > 32767) vol=32767;
|
||||
else if (vol < -32768) vol=-32768;
|
||||
out[ct]=(signed short)vol;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void fir_downsample(unsigned int freq, signed int *p, signed short *out)
|
||||
{
|
||||
__fir_downsample(freq, p, out);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user