aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-07-13 23:08:11 -0700
committerChris Robinson <[email protected]>2016-07-13 23:08:11 -0700
commit470f454c5363b09eb4ae7cf12bde9c5fbe6d8266 (patch)
tree486dd1ba14ec0b6d6bd50461a43d1d087f9b8190
parent5106f035df7153efa411feb090ba22b1d756998b (diff)
Modify bs2b_cross_feed to do multiple samples at once
-rw-r--r--Alc/ALu.c39
-rw-r--r--Alc/bs2b.c57
-rw-r--r--OpenAL32/Include/bs2b.h41
3 files changed, 78 insertions, 59 deletions
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 2a94d940..c1478b50 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -1534,33 +1534,28 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
device->Dry.Buffer, SamplesToDo
);
}
- else
+ else if(device->Uhj_Encoder)
{
- if(device->Uhj_Encoder)
+ int lidx = GetChannelIdxByName(device->RealOut, FrontLeft);
+ int ridx = GetChannelIdxByName(device->RealOut, FrontRight);
+ if(lidx != -1 && ridx != -1)
{
- int lidx = GetChannelIdxByName(device->RealOut, FrontLeft);
- int ridx = GetChannelIdxByName(device->RealOut, FrontRight);
- if(lidx != -1 && ridx != -1)
- {
- /* Encode to stereo-compatible 2-channel UHJ output. */
- EncodeUhj2(device->Uhj_Encoder,
- device->RealOut.Buffer[lidx], device->RealOut.Buffer[ridx],
- device->Dry.Buffer, SamplesToDo
- );
- }
+ /* Encode to stereo-compatible 2-channel UHJ output. */
+ EncodeUhj2(device->Uhj_Encoder,
+ device->RealOut.Buffer[lidx], device->RealOut.Buffer[ridx],
+ device->Dry.Buffer, SamplesToDo
+ );
}
- if(device->Bs2b)
+ }
+ else if(device->Bs2b)
+ {
+ int lidx = GetChannelIdxByName(device->RealOut, FrontLeft);
+ int ridx = GetChannelIdxByName(device->RealOut, FrontRight);
+ if(lidx != -1 && ridx != -1)
{
/* Apply binaural/crossfeed filter */
- for(i = 0;i < SamplesToDo;i++)
- {
- float samples[2];
- samples[0] = device->RealOut.Buffer[0][i];
- samples[1] = device->RealOut.Buffer[1][i];
- bs2b_cross_feed(device->Bs2b, samples);
- device->RealOut.Buffer[0][i] = samples[0];
- device->RealOut.Buffer[1][i] = samples[1];
- }
+ bs2b_cross_feed(device->Bs2b, device->RealOut.Buffer[lidx],
+ device->RealOut.Buffer[ridx], SamplesToDo);
}
}
diff --git a/Alc/bs2b.c b/Alc/bs2b.c
index 6c3f052b..ddc2e2f2 100644
--- a/Alc/bs2b.c
+++ b/Alc/bs2b.c
@@ -129,4 +129,59 @@ void bs2b_clear(struct bs2b *bs2b)
memset(&bs2b->last_sample, 0, sizeof(bs2b->last_sample));
} /* bs2b_clear */
-extern inline void bs2b_cross_feed(struct bs2b *bs2b, float *restrict samples);
+void bs2b_cross_feed(struct bs2b *bs2b, float *restrict Left, float *restrict Right, unsigned int SamplesToDo)
+{
+ float lsamples[128][2];
+ float rsamples[128][2];
+ unsigned int base;
+
+ for(base = 0;base < SamplesToDo;)
+ {
+ unsigned int todo = minu(128, SamplesToDo-base);
+ unsigned int i;
+
+ /* Process left input */
+ lsamples[0][0] = bs2b->a0_lo*Left[0] +
+ bs2b->b1_lo*bs2b->last_sample[0].lo;
+ lsamples[0][1] = bs2b->a0_hi*Left[0] +
+ bs2b->a1_hi*bs2b->last_sample[0].asis +
+ bs2b->b1_hi*bs2b->last_sample[0].hi;
+ for(i = 1;i < todo;i++)
+ {
+ lsamples[i][0] = bs2b->a0_lo*Left[i] +
+ bs2b->b1_lo*lsamples[i-1][0];
+ lsamples[i][1] = bs2b->a0_hi*Left[i] +
+ bs2b->a1_hi*Left[i-1] +
+ bs2b->b1_hi*lsamples[i-1][1];
+ }
+ bs2b->last_sample[0].asis = Left[i-1];
+ bs2b->last_sample[0].lo = lsamples[i-1][0];
+ bs2b->last_sample[0].hi = lsamples[i-1][1];
+
+ /* Process right input */
+ rsamples[0][0] = bs2b->a0_lo*Right[0] +
+ bs2b->b1_lo*bs2b->last_sample[1].lo;
+ rsamples[0][1] = bs2b->a0_hi*Right[0] +
+ bs2b->a1_hi*bs2b->last_sample[1].asis +
+ bs2b->b1_hi*bs2b->last_sample[1].hi;
+ for(i = 1;i < todo;i++)
+ {
+ rsamples[i][0] = bs2b->a0_lo*Right[i] +
+ bs2b->b1_lo*rsamples[i-1][0];
+ rsamples[i][1] = bs2b->a0_hi*Right[i] +
+ bs2b->a1_hi*Right[i-1] +
+ bs2b->b1_hi*rsamples[i-1][1];
+ }
+ bs2b->last_sample[1].asis = Right[i-1];
+ bs2b->last_sample[1].lo = rsamples[i-1][0];
+ bs2b->last_sample[1].hi = rsamples[i-1][1];
+
+ /* Crossfeed */
+ for(i = 0;i < todo;i++)
+ *(Left++) = lsamples[i][1] + rsamples[i][0];
+ for(i = 0;i < todo;i++)
+ *(Right++) = rsamples[i][1] + lsamples[i][0];
+
+ base += todo;
+ }
+} /* bs2b_cross_feed */
diff --git a/OpenAL32/Include/bs2b.h b/OpenAL32/Include/bs2b.h
index 903c6bc5..bfe5c274 100644
--- a/OpenAL32/Include/bs2b.h
+++ b/OpenAL32/Include/bs2b.h
@@ -63,10 +63,10 @@ struct bs2b {
* [0] - first channel, [1] - second channel
*/
struct t_last_sample {
- float asis[2];
- float lo[2];
- float hi[2];
- } last_sample;
+ float asis;
+ float lo;
+ float hi;
+ } last_sample[2];
};
/* Clear buffers and set new coefficients with new crossfeed level and sample
@@ -85,38 +85,7 @@ int bs2b_get_srate(struct bs2b *bs2b);
/* Clear buffer */
void bs2b_clear(struct bs2b *bs2b);
-/* Crossfeeds one stereo sample that are pointed by sample.
- * [0] - first channel, [1] - second channel.
- * Returns crossfided sample by sample pointer.
- */
-inline void bs2b_cross_feed(struct bs2b *bs2b, float *restrict sample)
-{
-/* Single pole IIR filter.
- * O[n] = a0*I[n] + a1*I[n-1] + b1*O[n-1]
- */
-
-/* Lowpass filter */
-#define lo_filter(in, out_1) (bs2b->a0_lo*(in) + bs2b->b1_lo*(out_1))
-
-/* Highboost filter */
-#define hi_filter(in, in_1, out_1) (bs2b->a0_hi*(in) + bs2b->a1_hi*(in_1) + bs2b->b1_hi*(out_1))
-
- /* Lowpass filter */
- bs2b->last_sample.lo[0] = lo_filter(sample[0], bs2b->last_sample.lo[0]);
- bs2b->last_sample.lo[1] = lo_filter(sample[1], bs2b->last_sample.lo[1]);
-
- /* Highboost filter */
- bs2b->last_sample.hi[0] = hi_filter(sample[0], bs2b->last_sample.asis[0], bs2b->last_sample.hi[0]);
- bs2b->last_sample.hi[1] = hi_filter(sample[1], bs2b->last_sample.asis[1], bs2b->last_sample.hi[1]);
- bs2b->last_sample.asis[0] = sample[0];
- bs2b->last_sample.asis[1] = sample[1];
-
- /* Crossfeed */
- sample[0] = bs2b->last_sample.hi[0] + bs2b->last_sample.lo[1];
- sample[1] = bs2b->last_sample.hi[1] + bs2b->last_sample.lo[0];
-#undef hi_filter
-#undef lo_filter
-} /* bs2b_cross_feed */
+void bs2b_cross_feed(struct bs2b *bs2b, float *restrict Left, float *restrict Right, unsigned int SamplesToDo);
#ifdef __cplusplus
} /* extern "C" */