Use 2-channel UHJ for stereo output
[openal-soft.git] / Alc / uhjfilter.c
blob63a88aa7e27f636e77c1e91e7e38e986d891a6dd
2 #include "config.h"
4 #include "alu.h"
5 #include "uhjfilter.h"
7 /* This is the maximum number of samples processed for each inner loop
8 * iteration. */
9 #define MAX_UPDATE_SAMPLES 256
12 static const ALfloat Filter1Coeff[4] = {
13 0.6923878f, 0.9360654322959f, 0.9882295226860f, 0.9987488452737f
15 static const ALfloat Filter2Coeff[4] = {
16 0.4021921162426f, 0.8561710882420f, 0.9722909545651f, 0.9952884791278f
19 void EncodeUhj2(Uhj2Encoder *enc, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALfloat (*restrict InSamples)[BUFFERSIZE], ALuint SamplesToDo)
21 ALuint base, i, c;
23 for(base = 0;base < SamplesToDo;)
25 ALfloat D[MAX_UPDATE_SAMPLES], S;
26 ALuint todo = minu(SamplesToDo - base, MAX_UPDATE_SAMPLES);
28 /* D = 0.6554516*Y */
29 for(i = 0;i < todo;i++)
31 ALfloat in = 0.6554516f*InSamples[2][base+i];
32 for(c = 0;c < 4;c++)
34 ALfloat aa = Filter1Coeff[c]*Filter1Coeff[c];
35 ALfloat out = aa*(in + enc->Filter1_Y[c].y[1]) - enc->Filter1_Y[c].x[1];
36 enc->Filter1_Y[c].x[1] = enc->Filter1_Y[c].x[0];
37 enc->Filter1_Y[c].x[0] = in;
38 enc->Filter1_Y[c].y[1] = enc->Filter1_Y[c].y[0];
39 enc->Filter1_Y[c].y[0] = out;
40 in = out;
42 /* NOTE: Filter1 requires a 1 sample delay for the base output, so
43 * take the sample before the last for output.
45 D[i] = enc->Filter1_Y[3].y[1];
48 /* D += j(-0.3420201*W' + 0.5098604*X) */
49 for(i = 0;i < todo;i++)
51 ALfloat in = -0.3420201f*1.414213562f*InSamples[0][base+i] +
52 0.5098604f*InSamples[1][base+i];
53 for(c = 0;c < 4;c++)
55 ALfloat aa = Filter2Coeff[c]*Filter2Coeff[c];
56 ALfloat out = aa*(in + enc->Filter2_WX[c].y[1]) - enc->Filter2_WX[c].x[1];
57 enc->Filter2_WX[c].x[1] = enc->Filter2_WX[c].x[0];
58 enc->Filter2_WX[c].x[0] = in;
59 enc->Filter2_WX[c].y[1] = enc->Filter2_WX[c].y[0];
60 enc->Filter2_WX[c].y[0] = out;
61 in = out;
63 D[i] += enc->Filter2_WX[3].y[0];
66 /* S = 0.9396926*W' + 0.1855740*X
67 * Left = (S + D)/2.0
68 * Right = (S - D)/2.0
70 for(i = 0;i < todo;i++)
72 ALfloat in = 0.9396926f*1.414213562f*InSamples[0][base+i] +
73 0.1855740f*InSamples[1][base+i];
74 for(c = 0;c < 4;c++)
76 ALfloat aa = Filter1Coeff[c]*Filter1Coeff[c];
77 ALfloat out = aa*(in + enc->Filter1_WX[c].y[1]) - enc->Filter1_WX[c].x[1];
78 enc->Filter1_WX[c].x[1] = enc->Filter1_WX[c].x[0];
79 enc->Filter1_WX[c].x[0] = in;
80 enc->Filter1_WX[c].y[1] = enc->Filter1_WX[c].y[0];
81 enc->Filter1_WX[c].y[0] = out;
82 in = out;
84 S = enc->Filter1_WX[3].y[1];
85 OutBuffer[0][base + i] += (S + D[i]) * 0.5f;
86 OutBuffer[1][base + i] += (S - D[i]) * 0.5f;
89 base += todo;