shithub: opus

Download patch

ref: ef8115bd9a9163a65834298b0dcd702872141523
parent: a30c96aa8a6da49f9844f12fcb40cc9ecf67bf8d
author: Jean-Marc Valin <jmvalin@amazon.com>
date: Fri Oct 20 18:07:58 EDT 2023

Stop using tansig_table.h (both copies)

--- a/dnn/nnet.c
+++ b/dnn/nnet.c
@@ -34,7 +34,6 @@
 #include <math.h>
 #include "opus_types.h"
 #include "arch.h"
-#include "tansig_table.h"
 #include "nnet.h"
 #include "dred_rdovae_constants.h"
 #include "plc_data.h"
--- a/dnn/vec.h
+++ b/dnn/vec.h
@@ -29,7 +29,6 @@
 #ifndef VEC_H
 #define VEC_H
 
-#include "tansig_table.h"
 #include "opus_types.h"
 #include <math.h>
 #include "arch.h"
@@ -81,7 +80,7 @@
    }
 }
 
-static inline void sgemv16x1(float *out, const float *weights, int rows, int cols, int col_stride, const float *x)
+static inline void sgemv8x1(float *out, const float *weights, int rows, int cols, int col_stride, const float *x)
 {
    int i, j;
    OPUS_CLEAR(out, rows);
@@ -334,23 +333,21 @@
 }
 #define lpcnet_exp(x) lpcnet_exp2((x)*1.44269504f)
 
-static inline float tanh_approx(float x)
+#define fmadd(a, b, c) ((a)*(b)+(c))
+static OPUS_INLINE float tanh_approx(float x)
 {
-    int i;
-    float y, dy;
-    float sign=1;
-    if (x<0)
-    {
-       x=-x;
-       sign=-1;
-    }
-    i = (int)floor(.5f+25*x);
-    i = IMAX(0, IMIN(200, i));
-    x -= .04f*i;
-    y = tansig_table[i];
-    dy = 1-y*y;
-    y = y + x*dy*(1 - y*x);
-    return sign*y;
+    const float N0 = 952.52801514f;
+    const float N1 = 96.39235687f;
+    const float N2 = 0.60863042f;
+    const float D0 = 952.72399902f;
+    const float D1 = 413.36801147f;
+    const float D2 = 11.88600922f;
+    float X2, num, den;
+    X2 = x*x;
+    num = fmadd(fmadd(N2, X2, N1), X2, N0);
+    den = fmadd(fmadd(D2, X2, D1), X2, D0);
+    num = num*x/den;
+    return MAX32(-1.f, MIN32(1.f, num));
 }
 
 static inline float sigmoid_approx(float x)
--- a/lpcnet_headers.mk
+++ b/lpcnet_headers.mk
@@ -8,7 +8,6 @@
 dnn/lpcnet_private.h \
 dnn/nnet.h \
 dnn/plc_data.h \
-dnn/tansig_table.h \
 dnn/vec.h \
 dnn/vec_avx.h \
 dnn/vec_neon.h \
--- a/opus_headers.mk
+++ b/opus_headers.mk
@@ -5,5 +5,4 @@
 src/opus_private.h \
 src/analysis.h \
 src/mapping_matrix.h \
-src/mlp.h \
-src/tansig_table.h
+src/mlp.h
--- a/src/mlp.c
+++ b/src/mlp.c
@@ -33,35 +33,23 @@
 #include "opus_types.h"
 #include "opus_defines.h"
 #include "arch.h"
-#include "tansig_table.h"
 #include "mlp.h"
 
+#define fmadd(a, b, c) ((a)*(b)+(c))
 static OPUS_INLINE float tansig_approx(float x)
 {
-    int i;
-    float y, dy;
-    float sign=1;
-    /* Tests are reversed to catch NaNs */
-    if (!(x<8))
-        return 1;
-    if (!(x>-8))
-        return -1;
-#ifndef FIXED_POINT
-    /* Another check in case of -ffast-math */
-    if (celt_isnan(x))
-       return 0;
-#endif
-    if (x<0)
-    {
-       x=-x;
-       sign=-1;
-    }
-    i = (int)floor(.5f+25*x);
-    x -= .04f*i;
-    y = tansig_table[i];
-    dy = 1-y*y;
-    y = y + x*dy*(1 - y*x);
-    return sign*y;
+    const float N0 = 952.52801514f;
+    const float N1 = 96.39235687f;
+    const float N2 = 0.60863042f;
+    const float D0 = 952.72399902f;
+    const float D1 = 413.36801147f;
+    const float D2 = 11.88600922f;
+    float X2, num, den;
+    X2 = x*x;
+    num = fmadd(fmadd(N2, X2, N1), X2, N0);
+    den = fmadd(fmadd(D2, X2, D1), X2, D0);
+    num = num*x/den;
+    return MAX32(-1.f, MIN32(1.f, num));
 }
 
 static OPUS_INLINE float sigmoid_approx(float x)
--