summaryrefslogtreecommitdiff
path: root/servers/audio/reverb_sw.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/audio/reverb_sw.cpp')
-rw-r--r--servers/audio/reverb_sw.cpp569
1 files changed, 569 insertions, 0 deletions
diff --git a/servers/audio/reverb_sw.cpp b/servers/audio/reverb_sw.cpp
new file mode 100644
index 0000000000..df36886db8
--- /dev/null
+++ b/servers/audio/reverb_sw.cpp
@@ -0,0 +1,569 @@
+/*************************************************************************/
+/* reverb_sw.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#include "reverb_sw.h"
+#include "stdlib.h"
+#include "print_string.h"
+#define SETMIN( x, y ) (x) = MIN ( (x), (y) )
+#define rangeloop( c, min, max ) \
+ for ( (c) = (min) ; (c) < (max) ; (c)++ )
+
+#define ABSDIFF(x, y)\
+ ( ((x) < (y)) ? ((y) - (x)) : ((x) - (y)) )
+
+
+#ifdef bleh_MSC_VER
+
+#if _MSC_VER >= 1400
+ _FORCE_INLINE_ int32_tMULSHIFT_S32 (
+ int32_t Factor1,
+ int32_t Factor2,
+ uint8_t Bits
+ ) {
+
+ return __ll_rshift (
+ __emul ( Factor1, Factor2 ),
+ Bits
+ );
+ }
+#endif
+
+#else
+#define MULSHIFT_S32( Factor1, Factor2, Bits )\
+ ( (int) (( (int64_t)(Factor1) * (Factor2) ) >> (Bits)) )
+#endif
+
+
+
+struct ReverbParamsSW {
+ unsigned int BufferSize; // Required buffer size
+ int gLPF; // Coefficient
+ int gEcho0; // Coefficient
+ int gEcho1; // Coefficient
+ int gEcho2; // Coefficient
+ int gEcho3; // Coefficient
+ int gWall; // Coefficient
+ int gReva; // Coefficient
+ int gRevb; // Coefficient
+ int gInputL; // Coefficient
+ int gInputR; // Coefficient
+ unsigned int nRevaOldL; // Offset
+ unsigned int nRevaOldR; // Offset
+ unsigned int nRevbOldL; // Offset
+ unsigned int nRevbOldR; // Offset
+ unsigned int nLwlNew; // Offset
+ unsigned int nRwrNew; // Offset
+ unsigned int nEcho0L; // Offset
+ unsigned int nEcho0R; // Offset
+ unsigned int nEcho1L; // Offset
+ unsigned int nEcho1R; // Offset
+ unsigned int nLwlOld; // Offset
+ unsigned int nRwrOld; // Offset
+ unsigned int nLwrNew; // Offset
+ unsigned int nRwlNew; // Offset
+ unsigned int nEcho2L; // Offset
+ unsigned int nEcho2R; // Offset
+ unsigned int nEcho3L; // Offset
+ unsigned int nEcho3R; // Offset
+ unsigned int nLwrOld; // Offset
+ unsigned int nRwlOld; // Offset
+ unsigned int nRevaNewL; // Offset
+ unsigned int nRevaNewR; // Offset
+ unsigned int nRevbNewL; // Offset
+ unsigned int nRevbNewR; // Offset
+};
+
+static ReverbParamsSW reverb_params_Room = {
+ 0x26C0/2,
+// gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
+ 0x6D80, 0x54B8, -0x4130, 0x0000, 0x0000, -0x4580,
+// gReva gRevb gInputL gInputR
+ 0x5800, 0x5300, -0x8000, -0x8000,
+// nRevaOldL nRevaOldR nRevbOldL nRevbOldR
+ 0x01B4 - 0x007D, 0x0136 - 0x007D, 0x00B8 - 0x005B, 0x005C - 0x005B,
+// nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
+ 0x04D6, 0x0333, 0x03F0, 0x0227, 0x0374, 0x01EF,
+// nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
+ 0x0334, 0x01B5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+// nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
+ 0x0000, 0x0000, 0x01B4, 0x0136, 0x00B8, 0x005C
+};
+
+static ReverbParamsSW reverb_params_StudioSmall = {
+ 0x1F40/2,
+// gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
+ 0x70F0, 0x4FA8, -0x4320, 0x4410, -0x3F10, -0x6400,
+// gReva gRevb gInputL gInputR
+ 0x5280, 0x4EC0, -0x8000, -0x8000,
+// nRevaOldL nRevaOldR nRevbOldL nRevbOldR
+ 0x00B4 - 0x0033, 0x0080 - 0x0033, 0x004C - 0x0025, 0x0026 - 0x0025,
+// nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
+ 0x03E4, 0x031B, 0x03A4, 0x02AF, 0x0372, 0x0266,
+// nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
+ 0x031C, 0x025D, 0x025C, 0x018E, 0x022F, 0x0135, 0x01D2, 0x00B7,
+// nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
+ 0x018F, 0x00B5, 0x00B4, 0x0080, 0x004C, 0x0026
+};
+
+static ReverbParamsSW reverb_params_StudioMedium = {
+ 0x4840/2,
+// gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
+ 0x70F0, 0x4FA8, -0x4320, 0x4510, -0x4110, -0x4B40,
+// gReva gRevb gInputL gInputR
+ 0x5280, 0x4EC0, -0x8000, -0x8000,
+// nRevaOldL nRevaOldR nRevbOldL nRevbOldR
+ 0x0264 - 0x00B1, 0x01B2 - 0x00B1, 0x0100 - 0x007F, 0x0080 - 0x007F,
+// nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
+ 0x0904, 0x076B, 0x0824, 0x065F, 0x07A2, 0x0616,
+// nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
+ 0x076C, 0x05ED, 0x05EC, 0x042E, 0x050F, 0x0305, 0x0462, 0x02B7,
+// nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
+ 0x042F, 0x0265, 0x0264, 0x01B2, 0x0100, 0x0080
+};
+
+static ReverbParamsSW reverb_params_StudioLarge = {
+ 0x6FE0/2,
+// gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
+ 0x6F60, 0x4FA8, -0x4320, 0x4510, -0x4110, -0x5980,
+// gReva gRevb gInputL gInputR
+ 0x5680, 0x52C0, -0x8000, -0x8000,
+// nRevaOldL nRevaOldR nRevbOldL nRevbOldR
+ 0x031C - 0x00E3, 0x0238 - 0x00E3, 0x0154 - 0x00A9, 0x00AA - 0x00A9,
+// nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
+ 0x0DFB, 0x0B58, 0x0D09, 0x0A3C, 0x0BD9, 0x0973,
+// nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
+ 0x0B59, 0x08DA, 0x08D9, 0x05E9, 0x07EC, 0x04B0, 0x06EF, 0x03D2,
+// nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
+ 0x05EA, 0x031D, 0x031C, 0x0238, 0x0154, 0x00AA
+};
+
+static ReverbParamsSW reverb_params_Hall = {
+ 0xADE0/2,
+// gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
+ 0x6000, 0x5000, 0x4C00, -0x4800, -0x4400, -0x4000,
+// gReva gRevb gInputL gInputR
+ 0x6000, 0x5C00, -0x8000, -0x8000,
+// nRevaOldL nRevaOldR nRevbOldL nRevbOldR
+ 0x05C0 - 0x01A5, 0x041A - 0x01A5, 0x0274 - 0x0139, 0x013A - 0x0139,
+// nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
+ 0x15BA, 0x11BB, 0x14C2, 0x10BD, 0x11BC, 0x0DC1,
+// nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
+ 0x11C0, 0x0DC3, 0x0DC0, 0x09C1, 0x0BC4, 0x07C1, 0x0A00, 0x06CD,
+// nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
+ 0x09C2, 0x05C1, 0x05C0, 0x041A, 0x0274, 0x013A
+};
+
+static ReverbParamsSW reverb_params_SpaceEcho = {
+ 0xF6C0/2,
+// gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
+ 0x7E00, 0x5000, -0x4C00, -0x5000, 0x4C00, -0x5000,
+// gReva gRevb gInputL gInputR
+ 0x6000, 0x5400, -0x8000, -0x8000,
+// nRevaOldL nRevaOldR nRevbOldL nRevbOldR
+ 0x0AE0 - 0x033D, 0x07A2 - 0x033D, 0x0464 - 0x0231, 0x0232 - 0x0231,
+// nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
+ 0x1ED6, 0x1A31, 0x1D14, 0x183B, 0x1BC2, 0x16B2,
+// nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
+ 0x1A32, 0x15EF, 0x15EE, 0x1055, 0x1334, 0x0F2D, 0x11F6, 0x0C5D,
+// nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
+ 0x1056, 0x0AE1, 0x0AE0, 0x07A2, 0x0464, 0x0232
+};
+
+static ReverbParamsSW reverb_params_Echo = {
+ 0x18040/2,
+// gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
+ 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, -0x7F00,
+// gReva gRevb gInputL gInputR
+ 0x0000, 0x0000, -0x8000, -0x8000,
+// nRevaOldL nRevaOldR nRevbOldL nRevbOldR
+ 0x1004 - 0x0001, 0x1002 - 0x0001, 0x0004 - 0x0001, 0x0002 - 0x0001,
+// nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
+ 0x1FFF, 0x0FFF, 0x1005, 0x0005, 0x0000, 0x0000,
+// nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
+ 0x1005, 0x0005, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+// nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
+ 0x0000, 0x0000, 0x1004, 0x1002, 0x0004, 0x0002
+};
+
+static ReverbParamsSW reverb_params_Delay = {
+ 0x18040/2,
+// gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
+ 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000,
+// gReva gRevb gInputL gInputR
+ 0x0000, 0x0000, -0x8000, -0x8000,
+// nRevaOldL nRevaOldR nRevbOldL nRevbOldR
+ 0x1004 - 0x0001, 0x1002 - 0x0001, 0x0004 - 0x0001, 0x0002 - 0x0001,
+// nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
+ 0x1FFF, 0x0FFF, 0x1005, 0x0005, 0x0000, 0x0000,
+// nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
+ 0x1005, 0x0005, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+// nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
+ 0x0000, 0x0000, 0x1004, 0x1002, 0x0004, 0x0002
+};
+
+static ReverbParamsSW reverb_params_HalfEcho = {
+ 0x3C00/2,
+// gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
+ 0x70F0, 0x4FA8, -0x4320, 0x4510, -0x4110, -0x7B00,
+// gReva gRevb gInputL gInputR
+ 0x5F80, 0x54C0, -0x8000, -0x8000,
+// nRevaOldL nRevaOldR nRevbOldL nRevbOldR
+ 0x0058 - 0x0017, 0x0040 - 0x0017, 0x0028 - 0x0013, 0x0014 - 0x0013,
+// nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
+ 0x0371, 0x02AF, 0x02E5, 0x01DF, 0x02B0, 0x01D7,
+// nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
+ 0x0358, 0x026A, 0x01D6, 0x011E, 0x012D, 0x00B1, 0x011F, 0x0059,
+// nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
+ 0x01A0, 0x00E3, 0x0058, 0x0040, 0x0028, 0x0014
+};
+
+
+static ReverbParamsSW * reverb_param_modes[] = {
+ &reverb_params_Room,
+ &reverb_params_StudioSmall,
+ &reverb_params_StudioMedium,
+ &reverb_params_StudioLarge,
+ &reverb_params_Hall,
+ &reverb_params_SpaceEcho,
+ &reverb_params_Echo,
+ &reverb_params_Delay,
+ &reverb_params_HalfEcho,
+};
+
+bool ReverbSW::process(int *p_input,int *p_output,int p_frames,int p_stereo_stride) {
+
+ if (!reverb_buffer)
+ return false;
+
+
+ //
+ // p_input must point to a non-looping buffer.
+ // BOTH p_input and p_output must be touched (use ClearModuleBuffer).
+
+ // �������LOCAL MACROS ������۲
+
+#undef LM_SETSRCOFFSET
+#define LM_SETSRCOFFSET(x) \
+ (x) = current_params->x + Offset; \
+ if ( (x) >= reverb_buffer_size ) { \
+ (x) -= reverb_buffer_size; \
+ } \
+ SETMIN ( aSample, reverb_buffer_size - (x) );
+
+/*
+#undef LM_SETSRCOFFSET2
+#define LM_SETSRCOFFSET2(x,y) \
+ (x) = ((y) << 3) >> HZShift; \
+ (x) += Offset; \
+ if ( (x) >= reverb_buffer_size ) { \
+ (x) -= reverb_buffer_size; \
+ } \
+ SETMIN ( aSample, reverb_buffer_size - (x) );
+*/
+#undef LM_SRCADVANCE
+#define LM_SRCADVANCE(x) \
+ (x) += aSample;
+
+#undef LM_MUL
+#define LM_MUL(x,y) \
+MULSHIFT_S32 ( x, current_params->y, 15 )
+
+#undef LM_REVERB
+#define LM_REVERB(x) reverb_buffer[ (x) + cSample ]
+
+ // �������LOCAL VARIABLES ������۲
+
+ unsigned int Offset;
+
+ int lwl, lwr, rwl, rwr;
+// unsigned char HZShift;
+
+ // �������CODE ������۲
+
+
+ lwl = state.lwl;
+ lwr = state.lwr;
+ rwl = state.rwl;
+ rwr = state.rwr;
+ Offset = state.Offset;
+
+ int max=0;
+
+ while ( p_frames ) {
+
+ // Offsets
+
+ unsigned int nLwlOld;
+ unsigned int nRwrOld;
+ unsigned int nLwlNew;
+ unsigned int nRwrNew;
+
+ unsigned int nLwrOld;
+ unsigned int nRwlOld;
+ unsigned int nLwrNew;
+ unsigned int nRwlNew;
+
+ unsigned int nEcho0L;
+ unsigned int nEcho1L;
+ unsigned int nEcho2L;
+ unsigned int nEcho3L;
+
+ unsigned int nEcho0R;
+ unsigned int nEcho1R;
+ unsigned int nEcho2R;
+ unsigned int nEcho3R;
+
+ unsigned int nRevaOldL;
+ unsigned int nRevaOldR;
+ unsigned int nRevbOldL;
+ unsigned int nRevbOldR;
+
+ unsigned int nRevaNewL;
+ unsigned int nRevaNewR;
+ unsigned int nRevbNewL;
+ unsigned int nRevbNewR;
+
+ // Other variables
+
+ unsigned int aSample = p_frames;
+
+ // Set initial offsets
+
+ LM_SETSRCOFFSET ( nLwlOld );
+ LM_SETSRCOFFSET ( nRwrOld );
+ LM_SETSRCOFFSET ( nLwlNew );
+ LM_SETSRCOFFSET ( nRwrNew );
+ LM_SETSRCOFFSET ( nLwrOld );
+ LM_SETSRCOFFSET ( nRwlOld );
+ LM_SETSRCOFFSET ( nLwrNew );
+ LM_SETSRCOFFSET ( nRwlNew );
+ LM_SETSRCOFFSET ( nEcho0L );
+ LM_SETSRCOFFSET ( nEcho1L );
+ LM_SETSRCOFFSET ( nEcho2L );
+ LM_SETSRCOFFSET ( nEcho3L );
+ LM_SETSRCOFFSET ( nEcho0R );
+ LM_SETSRCOFFSET ( nEcho1R );
+ LM_SETSRCOFFSET ( nEcho2R );
+ LM_SETSRCOFFSET ( nEcho3R );
+ LM_SETSRCOFFSET ( nRevaOldL );
+ LM_SETSRCOFFSET ( nRevaOldR );
+ LM_SETSRCOFFSET ( nRevbOldL );
+ LM_SETSRCOFFSET ( nRevbOldR );
+ LM_SETSRCOFFSET ( nRevaNewL );
+ LM_SETSRCOFFSET ( nRevaNewR );
+ LM_SETSRCOFFSET ( nRevbNewL );
+ LM_SETSRCOFFSET ( nRevbNewR );
+
+ //SETMIN ( aSample, p_output.Size - p_output.Offset );
+
+ for (unsigned int cSample=0;cSample<aSample;cSample++) {
+
+ int tempL0, tempL1, tempR0, tempR1;
+
+ tempL1 = p_input[(cSample<<p_stereo_stride)]>>8;
+ tempR1 = p_input[(cSample<<p_stereo_stride) + 1]>>8;
+
+ tempL0 = LM_MUL ( tempL1, gInputL );
+ tempR0 = LM_MUL ( tempR1, gInputR );
+
+ /*
+ Left -> Wall -> Left Reflection
+ */
+ tempL1 = tempL0 + LM_MUL ( LM_REVERB( nLwlOld ), gWall );
+ tempR1 = tempR0 + LM_MUL ( LM_REVERB( nRwrOld ), gWall );
+ lwl += LM_MUL ( tempL1 - lwl, gLPF );
+ rwr += LM_MUL ( tempR1 - rwr, gLPF );
+ LM_REVERB( nLwlNew ) = lwl;
+ LM_REVERB( nRwrNew ) = rwr;
+ /*
+ Left -> Wall -> Right Reflection
+ */
+ tempL1 = tempL0 + LM_MUL ( LM_REVERB( nRwlOld ), gWall );
+ tempR1 = tempR0 + LM_MUL ( LM_REVERB( nLwrOld ), gWall );
+ lwr += LM_MUL ( tempL1 - lwr, gLPF );
+ rwl += LM_MUL ( tempR1 - rwl, gLPF );
+ LM_REVERB( nLwrNew ) = lwr;
+ LM_REVERB( nRwlNew ) = rwl;
+ /*
+ Early Echo(Early Reflection)
+ */
+ tempL0 =
+ LM_MUL ( LM_REVERB( nEcho0L ), gEcho0 ) +
+ LM_MUL ( LM_REVERB( nEcho1L ), gEcho1 ) +
+ LM_MUL ( LM_REVERB( nEcho2L ), gEcho2 ) +
+ LM_MUL ( LM_REVERB( nEcho3L ), gEcho3 );
+ tempR0 =
+ LM_MUL ( LM_REVERB( nEcho0R ), gEcho0 ) +
+ LM_MUL ( LM_REVERB( nEcho1R ), gEcho1 ) +
+ LM_MUL ( LM_REVERB( nEcho2R ), gEcho2 ) +
+ LM_MUL ( LM_REVERB( nEcho3R ), gEcho3 );
+ /*
+ Late Reverb
+ */
+ tempL1 = LM_REVERB( nRevaOldL );
+ tempR1 = LM_REVERB( nRevaOldR );
+ tempL0 -= LM_MUL ( tempL1, gReva );
+ tempR0 -= LM_MUL ( tempR1, gReva );
+ LM_REVERB( nRevaNewL ) = tempL0;
+ LM_REVERB( nRevaNewR ) = tempR0;
+ tempL0 = LM_MUL ( tempL0, gReva ) + tempL1;
+ tempR0 = LM_MUL ( tempR0, gReva ) + tempR1;
+ tempL1 = LM_REVERB( nRevbOldL );
+ tempR1 = LM_REVERB( nRevbOldR );
+ tempL0 -= LM_MUL ( tempL1, gRevb );
+ tempR0 -= LM_MUL ( tempR1, gRevb );
+ LM_REVERB( nRevbNewL ) = tempL0;
+ LM_REVERB( nRevbNewR ) = tempR0;
+ tempL0 = LM_MUL ( tempL0, gRevb ) + tempL1;
+ tempR0 = LM_MUL ( tempR0, gRevb ) + tempR1;
+ /*
+ Output
+ */
+
+ max|=abs(tempL0);
+ max|=abs(tempR0);
+
+ p_output[(cSample<<p_stereo_stride)] += tempL0<<8;
+ p_output[(cSample<<p_stereo_stride) + 1] += tempR0<<8;
+
+ }
+
+ // Advance offsets
+
+ Offset += aSample;
+ if ( Offset >= reverb_buffer_size ) { Offset -= reverb_buffer_size; }
+
+ p_input += aSample << p_stereo_stride;
+ p_output += aSample << p_stereo_stride;
+
+ p_frames -= aSample;
+ }
+
+ state.lwl = lwl;
+ state.lwr = lwr;
+ state.rwl = rwl;
+ state.rwr = rwr;
+ state.Offset = Offset;
+
+ return (max&0x7FFFFF00)!=0; // audio was mixed?
+}
+
+void ReverbSW::adjust_current_params() {
+
+ *current_params=*reverb_param_modes[mode];
+
+ uint32_t maxofs=0;
+
+#define LM_CONFIG_PARAM( x )\
+ current_params->x=(int)( ( (int64_t)current_params->x*(int64_t)mix_rate*8L)/(int64_t)44100);\
+ if (current_params->x>maxofs)\
+ maxofs=current_params->x;
+
+
+ LM_CONFIG_PARAM ( nLwlOld );
+ LM_CONFIG_PARAM ( nRwrOld );
+ LM_CONFIG_PARAM ( nLwlNew );
+ LM_CONFIG_PARAM ( nRwrNew );
+ LM_CONFIG_PARAM ( nLwrOld );
+ LM_CONFIG_PARAM ( nRwlOld );
+ LM_CONFIG_PARAM ( nLwrNew );
+ LM_CONFIG_PARAM ( nRwlNew );
+ LM_CONFIG_PARAM ( nEcho0L );
+ LM_CONFIG_PARAM ( nEcho1L );
+ LM_CONFIG_PARAM ( nEcho2L );
+ LM_CONFIG_PARAM ( nEcho3L );
+ LM_CONFIG_PARAM ( nEcho0R );
+ LM_CONFIG_PARAM ( nEcho1R );
+ LM_CONFIG_PARAM ( nEcho2R );
+ LM_CONFIG_PARAM ( nEcho3R );
+ LM_CONFIG_PARAM ( nRevaOldL );
+ LM_CONFIG_PARAM ( nRevaOldR );
+ LM_CONFIG_PARAM ( nRevbOldL );
+ LM_CONFIG_PARAM ( nRevbOldR );
+ LM_CONFIG_PARAM ( nRevaNewL );
+ LM_CONFIG_PARAM ( nRevaNewR );
+ LM_CONFIG_PARAM ( nRevbNewL );
+ LM_CONFIG_PARAM ( nRevbNewR );
+
+ int needed_buffer_size=maxofs+1;
+ if (reverb_buffer)
+ memdelete_arr(reverb_buffer);
+
+ reverb_buffer = memnew_arr(int,needed_buffer_size);
+ reverb_buffer_size=needed_buffer_size;
+
+ for (uint32_t i=0;i<reverb_buffer_size;i++)
+ reverb_buffer[i]=0;
+
+ state.reset();
+
+
+}
+
+void ReverbSW::set_mode(ReverbMode p_mode) {
+
+ if (mode==p_mode)
+ return;
+
+ mode=p_mode;
+
+ adjust_current_params();
+}
+
+void ReverbSW::set_mix_rate(int p_mix_rate) {
+
+ if (p_mix_rate==mix_rate)
+ return;
+
+ mix_rate=p_mix_rate;
+
+ adjust_current_params();
+
+}
+
+
+ReverbSW::ReverbSW() {
+
+ reverb_buffer=0;
+ reverb_buffer_size=0;
+ mode=REVERB_MODE_ROOM;
+ mix_rate=1;
+ current_params = memnew(ReverbParamsSW);
+}
+
+
+ReverbSW::~ReverbSW() {
+
+
+ if (reverb_buffer)
+ memdelete_arr(reverb_buffer);
+
+ memdelete(current_params);
+
+}
+