5 #include "mixer_defs.h"
8 #define LIKELY(x) __builtin_expect(!!(x), 1)
9 #define UNLIKELY(x) __builtin_expect(!!(x), 0)
12 #define UNLIKELY(x) (x)
15 #define REAL_MERGE2(a,b) a##b
16 #define MERGE2(a,b) REAL_MERGE2(a,b)
18 #define MixDirect_Hrtf MERGE2(MixDirect_Hrtf_,SUFFIX)
21 static __inline
void ApplyCoeffsStep(ALuint Offset
, ALfloat (*RESTRICT Values
)[2],
23 ALfloat (*RESTRICT Coeffs
)[2],
24 ALfloat (*RESTRICT CoeffStep
)[2],
25 ALfloat left
, ALfloat right
);
26 static __inline
void ApplyCoeffs(ALuint Offset
, ALfloat (*RESTRICT Values
)[2],
28 ALfloat (*RESTRICT Coeffs
)[2],
29 ALfloat left
, ALfloat right
);
32 void MixDirect_Hrtf(ALsource
*Source
, ALCdevice
*Device
, DirectParams
*params
,
33 const ALfloat
*RESTRICT data
, ALuint srcchan
,
34 ALuint OutPos
, ALuint SamplesToDo
, ALuint BufferSize
)
36 ALfloat (*RESTRICT DryBuffer
)[BUFFERSIZE
] = Device
->DryBuffer
;
37 ALfloat
*RESTRICT ClickRemoval
= Device
->ClickRemoval
;
38 ALfloat
*RESTRICT PendingClicks
= Device
->PendingClicks
;
39 const ALuint IrSize
= GetHrtfIrSize(Device
->Hrtf
);
40 const ALint
*RESTRICT DelayStep
= params
->Hrtf
.DelayStep
;
41 ALfloat (*RESTRICT CoeffStep
)[2] = params
->Hrtf
.CoeffStep
;
42 ALfloat (*RESTRICT TargetCoeffs
)[2] = params
->Hrtf
.Coeffs
[srcchan
];
43 ALuint
*RESTRICT TargetDelay
= params
->Hrtf
.Delay
[srcchan
];
44 ALfloat
*RESTRICT History
= Source
->Hrtf
.History
[srcchan
];
45 ALfloat (*RESTRICT Values
)[2] = Source
->Hrtf
.Values
[srcchan
];
46 ALint Counter
= maxu(Source
->Hrtf
.Counter
, OutPos
) - OutPos
;
47 ALuint Offset
= Source
->Hrtf
.Offset
+ OutPos
;
48 ALIGN(16) ALfloat Coeffs
[HRIR_LENGTH
][2];
55 for(c
= 0;c
< IrSize
;c
++)
57 Coeffs
[c
][0] = TargetCoeffs
[c
][0] - (CoeffStep
[c
][0]*Counter
);
58 Coeffs
[c
][1] = TargetCoeffs
[c
][1] - (CoeffStep
[c
][1]*Counter
);
61 Delay
[0] = TargetDelay
[0] - (DelayStep
[0]*Counter
);
62 Delay
[1] = TargetDelay
[1] - (DelayStep
[1]*Counter
);
64 if(LIKELY(OutPos
== 0))
66 History
[Offset
&SRC_HISTORY_MASK
] = data
[pos
];
67 left
= lerp(History
[(Offset
-(Delay
[0]>>HRTFDELAY_BITS
))&SRC_HISTORY_MASK
],
68 History
[(Offset
-(Delay
[0]>>HRTFDELAY_BITS
)-1)&SRC_HISTORY_MASK
],
69 (Delay
[0]&HRTFDELAY_MASK
)*(1.0f
/HRTFDELAY_FRACONE
));
70 right
= lerp(History
[(Offset
-(Delay
[1]>>HRTFDELAY_BITS
))&SRC_HISTORY_MASK
],
71 History
[(Offset
-(Delay
[1]>>HRTFDELAY_BITS
)-1)&SRC_HISTORY_MASK
],
72 (Delay
[1]&HRTFDELAY_MASK
)*(1.0f
/HRTFDELAY_FRACONE
));
74 ClickRemoval
[FrontLeft
] -= Values
[(Offset
+1)&HRIR_MASK
][0] +
76 ClickRemoval
[FrontRight
] -= Values
[(Offset
+1)&HRIR_MASK
][1] +
79 for(pos
= 0;pos
< BufferSize
&& Counter
> 0;pos
++)
81 History
[Offset
&SRC_HISTORY_MASK
] = data
[pos
];
82 left
= lerp(History
[(Offset
-(Delay
[0]>>HRTFDELAY_BITS
))&SRC_HISTORY_MASK
],
83 History
[(Offset
-(Delay
[0]>>HRTFDELAY_BITS
)-1)&SRC_HISTORY_MASK
],
84 (Delay
[0]&HRTFDELAY_MASK
)*(1.0f
/HRTFDELAY_FRACONE
));
85 right
= lerp(History
[(Offset
-(Delay
[1]>>HRTFDELAY_BITS
))&SRC_HISTORY_MASK
],
86 History
[(Offset
-(Delay
[1]>>HRTFDELAY_BITS
)-1)&SRC_HISTORY_MASK
],
87 (Delay
[1]&HRTFDELAY_MASK
)*(1.0f
/HRTFDELAY_FRACONE
));
89 Delay
[0] += DelayStep
[0];
90 Delay
[1] += DelayStep
[1];
92 Values
[(Offset
+IrSize
)&HRIR_MASK
][0] = 0.0f
;
93 Values
[(Offset
+IrSize
)&HRIR_MASK
][1] = 0.0f
;
96 ApplyCoeffsStep(Offset
, Values
, IrSize
, Coeffs
, CoeffStep
, left
, right
);
97 DryBuffer
[FrontLeft
][OutPos
] += Values
[Offset
&HRIR_MASK
][0];
98 DryBuffer
[FrontRight
][OutPos
] += Values
[Offset
&HRIR_MASK
][1];
104 Delay
[0] >>= HRTFDELAY_BITS
;
105 Delay
[1] >>= HRTFDELAY_BITS
;
106 for(;pos
< BufferSize
;pos
++)
108 History
[Offset
&SRC_HISTORY_MASK
] = data
[pos
];
109 left
= History
[(Offset
-Delay
[0])&SRC_HISTORY_MASK
];
110 right
= History
[(Offset
-Delay
[1])&SRC_HISTORY_MASK
];
112 Values
[(Offset
+IrSize
)&HRIR_MASK
][0] = 0.0f
;
113 Values
[(Offset
+IrSize
)&HRIR_MASK
][1] = 0.0f
;
116 ApplyCoeffs(Offset
, Values
, IrSize
, Coeffs
, left
, right
);
117 DryBuffer
[FrontLeft
][OutPos
] += Values
[Offset
&HRIR_MASK
][0];
118 DryBuffer
[FrontRight
][OutPos
] += Values
[Offset
&HRIR_MASK
][1];
122 if(LIKELY(OutPos
== SamplesToDo
))
124 History
[Offset
&SRC_HISTORY_MASK
] = data
[pos
];
125 left
= History
[(Offset
-Delay
[0])&SRC_HISTORY_MASK
];
126 right
= History
[(Offset
-Delay
[1])&SRC_HISTORY_MASK
];
128 PendingClicks
[FrontLeft
] += Values
[(Offset
+1)&HRIR_MASK
][0] +
130 PendingClicks
[FrontRight
] += Values
[(Offset
+1)&HRIR_MASK
][1] +
131 Coeffs
[0][1] * right
;
136 #undef MixDirect_Hrtf