1 module PixelPerfectEngine.audio.firFilter; 2 3 /* 4 * Copyright (C) 2015-2018, by Laszlo Szeremi under the Boost license. 5 * 6 * Pixel Perfect Engine, FIR filter module 7 */ 8 9 public struct FiniteImpulseResponse(int L){ 10 //static assert(L % 2 == 0); 11 public short[L] vals; 12 } 13 14 public struct FiniteImpulseResponseFilter(int L){ 15 FiniteImpulseResponse!L* impulseResponse; 16 private short[L + 3] delayLine; 17 private uint stepping; 18 private uint truncating; 19 this(FiniteImpulseResponse!L* impulseResponse){ 20 this.impulseResponse = impulseResponse; 21 version(X86){ 22 truncating = (L * 8) - 1; 23 }else version(X86_64){ 24 truncating = (L * 8) - 1; 25 }else{ 26 truncating = L - 1; 27 } 28 } 29 /*public @nogc int calculate(short input){ 30 if(stepping < 3){ 31 delayLine[L + (L - stepping)] = input; 32 } 33 delayLine[L - stepping] = input; 34 version(X86){ 35 int[4] result; 36 asm @nogc{ 37 mov ESI, impulseResponse[EBP]; 38 mov EDI, delayLine[EBP]; 39 mov EDX, stepping; 40 mov EAX, truncating; 41 mov ECX, L; 42 43 filterloop: 44 mov EBX, EDX; 45 and EBX, EAX; 46 add EBX, EDI; 47 movups XMM0, [EBX]; 48 movups XMM1, [ESI]; 49 pmaddwd XMM1, XMM0; 50 paddd XMM2, XMM1; 51 add ESI, 16; 52 add EDX, 16; 53 dec ECX; 54 cmp ECX, 0; 55 jnz filterloop; 56 movups result, XMM2; 57 } 58 stepping++; 59 stepping &= truncating; 60 return result[0] + result[1] + result[2] + result[3]; 61 }else version(X86_64){ 62 int[4] result; 63 asm @nogc{ 64 mov RSI, impulseResponse[RBP]; 65 mov RDI, delayLine[RBP]; 66 mov EDX, stepping; 67 mov EAX, truncating; 68 mov ECX, L; 69 70 filterloop: 71 mov RBX, RDX; 72 and RBX, RAX; 73 add RBX, RDI; 74 movups XMM0, [RBX]; 75 movups XMM1, [RSI]; 76 mulps XMM1, XMM0; 77 addps XMM2, XMM1; 78 add RSI, 16; 79 add RDX, 16; 80 dec ECX; 81 cmp ECX, 0; 82 jnz filterloop; 83 movups result, XMM2; 84 } 85 stepping++; 86 stepping &= truncating; 87 return result[0] + result[1] + result[2] + result[3]; 88 }else{ 89 int result; 90 for(int i; i < L; i++){ 91 result += delayLine[(i + stepping) & truncating] * impulseResponse.vals[i]; 92 } 93 stepping++; 94 stepping &= truncating; 95 } 96 97 }*/ 98 }