Fix 40/60ms zero-length frame decode failure
[opus.git] / src / mlp.c
index 200f1cb..73b1d31 100644 (file)
--- a/src/mlp.c
+++ b/src/mlp.c
@@ -25,6 +25,9 @@
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
 #include <math.h>
 #include "mlp.h"
@@ -32,8 +35,7 @@
 #include "tansig_table.h"
 #define MAX_NEURONS 100
 
-#ifdef FIXED_POINT
-extern const opus_val16 tansig_table[501];
+#if 0
 static inline opus_val16 tansig_approx(opus_val32 _x) /* Q19 */
 {
        int i;
@@ -41,9 +43,9 @@ static inline opus_val16 tansig_approx(opus_val32 _x) /* Q19 */
        /*double x, y;*/
        opus_val16 dy, yy; /* Q14 */
        /*x = 1.9073e-06*_x;*/
-       if (_x>=QCONST32(10,19))
+       if (_x>=QCONST32(8,19))
                return QCONST32(1.,14);
-       if (_x<=-QCONST32(10,19))
+       if (_x<=-QCONST32(8,19))
                return -QCONST32(1.,14);
        xx = EXTRACT16(SHR32(_x, 8));
        /*i = lrint(25*x);*/
@@ -60,23 +62,30 @@ static inline opus_val16 tansig_approx(opus_val32 _x) /* Q19 */
 }
 #else
 /*extern const float tansig_table[501];*/
-static inline double tansig_approx(double x)
+static inline float tansig_approx(float x)
 {
        int i;
-       double y, dy;
-       if (x>=10)
-               return 1;
-       if (x<=-10)
-               return -1;
-       i = lrint(25*x);
-       x -= .04*i;
-       y = tansig_table[250+i];
+       float y, dy;
+       float sign=1;
+    if (x>=8)
+        return 1;
+    if (x<=-8)
+        return -1;
+       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 y;
+       return sign*y;
 }
 #endif
 
+#if 0
 void mlp_process(const MLP *m, const opus_val16 *in, opus_val16 *out)
 {
        int j;
@@ -100,4 +109,28 @@ void mlp_process(const MLP *m, const opus_val16 *in, opus_val16 *out)
                out[j] = tansig_approx(EXTRACT16(PSHR32(sum,17)));
        }
 }
-
+#else
+void mlp_process(const MLP *m, const float *in, float *out)
+{
+    int j;
+    float hidden[MAX_NEURONS];
+    const float *W = m->weights;
+    /* Copy to tmp_in */
+    for (j=0;j<m->topo[1];j++)
+    {
+        int k;
+        float sum = *W++;
+        for (k=0;k<m->topo[0];k++)
+            sum = sum + in[k]**W++;
+        hidden[j] = tansig_approx(sum);
+    }
+    for (j=0;j<m->topo[2];j++)
+    {
+        int k;
+        float sum = *W++;
+        for (k=0;k<m->topo[1];k++)
+            sum = sum + hidden[k]**W++;
+        out[j] = tansig_approx(sum);
+    }
+}
+#endif