То, что недопонял, по ссылке -> Исправил, заработало. http://caxapa.ru/259602.html
//кольцевой буфер фильтра имеет длинну Nsample отсчёта
//static float cbuff[Nsample]; //input samples
#define OE (1<<3) //переполнение
#define UE (1<<4) //обнуление
#define PE (1<<5) //неточный результат
#define PC 8 //Точность
#define RC 10 //округление
unsigned short fpu_ini(void){ //настроить ФПУ
unsigned short Src;
__asm FNINIT
__asm FWAIT
//__asm fstcw Src
//Src &= ~((3<<PC) | (3<<RC)); //сбросить биты
//Src |= ((3<<PC) | (0<<RC)); //PC одинарная точность RC округление к ближайшему числу
//__asm fldcw Src
__asm fstcw Src //посмотреть что накрутил
return Src;
}
void fmull(float fpuFIRCoef, float fnewsample){
unsigned short fmsw =0;
__asm{
FNCLEX //сбросить флаги
//FLD xx
FLD fnewsample
FLD fpuFIRCoef
fmulp ST(1),ST0
faddp ST(1),ST0
//fstp xx
FSTSW fmsw //взять флаги
FWAIT
};
__asm FSTSW fmsw
__asm FWAIT
if ( ( fmsw & (OE | UE | PE)) )
printf("\n\rERROR=%d",fmsw);
}
// - принимает 1 отсчёт на частоте n выдаёт n4 отсчёта -
#define Ntap 104 // только кратное 4 !
#define Nsample ((Ntap/4))
//кольцевой буфер фильтра имее длинну Nsample отсчёта
static float cbuff[Nsample]; //input samples
unsigned int ptr_head; //для правильного кольцевого буффера
unsigned int ptr_tail;
signed int upsample[4]; //output sample n*4
void fir(signed short NewSample) {
float FIRCoef[Ntap] = {
-0.000074035058,
-0.000067430290,
-0.000009453891,
0.000088561075,
0.000180576152,
0.000200605334,
0.000098994503,
-0.000115520966,
-0.000354872271,
-0.000475520112,
-0.000349720297,
0.000044499294,
0.000567124454,
0.000943494070,
0.000888178129,
0.000280106756,
-0.000704935192,
-0.001602413302,
-0.001848484236,
-0.001090609537,
0.000534576107,
0.002335685046,
0.003314950100,
0.002670242447,
0.000320908124,
-0.002848361753,
-0.005243956449,
-0.005298983887,
-0.002380840324,
0.002611903049,
0.007381960854,
0.009193363350,
0.006308091150,
-0.000800760759,
-0.009189450771,
-0.014496256066,
-0.013017618755,
-0.003898567222,
0.009722539075,
0.021453196776,
0.024284022404,
0.014159235547,
-0.007136552309,
-0.031334719642,
-0.046002402363,
-0.039237264225,
-0.004953168107,
0.053522019428,
0.123305237673,
0.185680485265,
0.222445109287,
0.222445109287,
0.185680485265,
0.123305237673,
0.053522019428,
-0.004953168107,
-0.039237264225,
-0.046002402363,
-0.031334719642,
-0.007136552309,
0.014159235547,
0.024284022404,
0.021453196776,
0.009722539075,
-0.003898567222,
-0.013017618755,
-0.014496256066,
-0.009189450771,
-0.000800760759,
0.006308091150,
0.009193363350,
0.007381960854,
0.002611903049,
-0.002380840324,
-0.005298983887,
-0.005243956449,
-0.002848361753,
0.000320908124,
0.002670242447,
0.003314950100,
0.002335685046,
0.000534576107,
-0.001090609537,
-0.001848484236,
-0.001602413302,
-0.000704935192,
0.000280106756,
0.000888178129,
0.000943494070,
0.000567124454,
0.000044499294,
-0.000349720297,
-0.000475520112,
-0.000354872271,
-0.000115520966,
0.000098994503,
0.000200605334,
0.000180576152,
0.000088561075,
-0.000009453891,
-0.000067430290,
-0.000074035058,
0.0,
0.0
};
int n=0;
//получить новый отсчёт
for(n=Nsample-1; n>0; n--) // типа для удобства и нагляднасти
cbuff[n] = cbuff[n-1];
n=17; //сдвинуть на 17 бит
//переыести во флоат и умножить чтобы не округлять
_asm fild n
_asm fild NewSample
_asm FSCALE //типа не округлять
_asm fstp cbuff[0] //типа сделать флоат
// - первый семпл -
__asm FLDZ
for ( unsigned int j=0; j<Nsample ; j++ )
fmull(FIRCoef[j*4],cbuff[j]);
__asm fistp upsample[0]
// - фторой семпл -
__asm FLDZ
for ( unsigned int j=0; j<Nsample ; j++ )
fmull(FIRCoef[j*4+1],cbuff[j]);
__asm fistp upsample[0]+4
// - третий семпл -
__asm FLDZ
for ( unsigned int j=0; j<Nsample ; j++ )
fmull(FIRCoef[j*4+2],cbuff[j]);
__asm fistp upsample[0]+4+4
// - и четвёртый семпл -
__asm FLDZ
for ( unsigned int j=0; j<Nsample ; j++ )
fmull(FIRCoef[j*4+3],cbuff[j]);
__asm fistp upsample[0]+4+4+4
}
В первый раз писал на ПЦ. Чёта как то подозрительно быстро с ФПУ разобралсо %-/