Przeglądaj źródła

move audio libs to seperate dir

Sanjay Govind 1 rok temu
rodzic
commit
883c483946
10 zmienionych plików z 270 dodań i 721 usunięć
  1. 1 0
      .gitignore
  2. 263 251
      audio/g721.c
  3. 2 21
      audio/g721.h
  4. 0 0
      audio/wav_player_hal.c
  5. 0 0
      audio/wav_player_hal.h
  6. 0 256
      g711.c
  7. 0 165
      g721.c
  8. 0 24
      test.py
  9. 3 3
      virtual_portal.c
  10. 1 1
      virtual_portal.h

+ 1 - 0
.gitignore

@@ -5,3 +5,4 @@ dist/*
 .editorconfig
 .env
 .ufbt
+scripts

+ 263 - 251
g72x.c → audio/g721.c

@@ -23,14 +23,127 @@
  * 2550 Garcia Avenue
  * Mountain View, California  94043
  */
+
+/*
+ * g721.c
+ *
+ * Description:
+ *
+ * g721_encoder(), g721_decoder()
+ *
+ * These routines comprise an implementation of the CCITT G.721 ADPCM
+ * coding algorithm.  Essentially, this implementation is identical to
+ * the bit level description except for a few deviations which
+ * take advantage of work station attributes, such as hardware 2's
+ * complement arithmetic and large memory.  Specifically, certain time
+ * consuming operations such as multiplications are replaced
+ * with lookup tables and software 2's complement operations are
+ * replaced with hardware 2's complement.
+ *
+ * The deviation from the bit level specification (lookup tables)
+ * preserves the bit level performance specifications.
+ *
+ * As outlined in the G.721 Recommendation, the algorithm is broken
+ * down into modules.  Each section of code below is preceded by
+ * the name of the module which it is implementing.
+ *
+ */
+#include "g721.h"
 #include <stdlib.h>
+
+static short qtab_721[7] = { -124, 80, 178, 246, 300, 349, 400 };
 /*
- * g72x.c
+ * Maps G.721 code word to reconstructed scale factor normalized log
+ * magnitude values.
+ */
+static short _dqlntab[16] = { -2048, 4,   135, 213, 273, 323, 373, 425,
+                              425,   373, 323, 273, 213, 135, 4,   -2048 };
+
+/* Maps G.721 code word to log of scale factor multiplier. */
+static short _witab[16] = { -12,  18,  41,  64,  112, 198, 355, 1122,
+                            1122, 355, 198, 112, 64,  41,  18,  -12 };
+/*
+ * Maps G.721 code words to a set of values whose long and short
+ * term averages are computed and then compared to give an indication
+ * how stationary (steady state) the signal is.
+ */
+static short _fitab[16] = { 0,     0,     0,     0x200, 0x200, 0x200, 0x600, 0xE00,
+                            0xE00, 0x600, 0x200, 0x200, 0x200, 0,     0,     0 };
+
+/*
+ * g721_encoder()
  *
- * Common routines for G.721 and G.723 conversions.
+ * Encodes the input vale of linear PCM, A-law or u-law data sl and returns
+ * the resulting code. -1 is returned for unknown input coding value.
  */
+int g721_encoder(int sl, struct g72x_state* state_ptr)
+{
+    short sezi, se, sez; /* ACCUM */
+    short d;             /* SUBTA */
+    short sr;            /* ADDB */
+    short y;             /* MIX */
+    short dqsez;         /* ADDC */
+    short dq, i;
+
+    sl >>= 2; /* linearize input sample to 14-bit PCM */
+
+    sezi = predictor_zero(state_ptr);
+    sez = sezi >> 1;
+    se = (sezi + predictor_pole(state_ptr)) >> 1; /* estimated signal */
+
+    d = sl - se; /* estimation difference */
+
+    /* quantize the prediction difference */
+    y = step_size(state_ptr);        /* quantizer step size */
+    i = quantize(d, y, qtab_721, 7); /* i = ADPCM code */
+
+    dq = reconstruct(i & 8, _dqlntab[i], y); /* quantized est diff */
+
+    sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconst. signal */
+
+    dqsez = sr + sez - se; /* pole prediction diff. */
+
+    update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
+
+    return (i);
+}
+
+/*
+ * g721_decoder()
+ *
+ * Description:
+ *
+ * Decodes a 4-bit code of G.721 encoded data of i and
+ * returns the resulting linear PCM
+ * return -1 for unknown out_coding value.
+ */
+int g721_decoder(int i, struct g72x_state* state_ptr)
+{
+    short sezi, sei, sez, se; /* ACCUM */
+    short y;                  /* MIX */
+    short sr;                 /* ADDB */
+    short dq;
+    short dqsez;
+
+    i &= 0x0f; /* mask to get proper bits */
+    sezi = predictor_zero(state_ptr);
+    sez = sezi >> 1;
+    sei = sezi + predictor_pole(state_ptr);
+    se = sei >> 1; /* se = estimated signal */
+
+    y = step_size(state_ptr); /* dynamic quantizer step size */
+
+    dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */
+
+    sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */
+
+    dqsez = sr - se + sez; /* pole prediction diff. */
+
+    update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
+
+    return (sr << 2);
+}
 
-#include "g72x.h"
 
 static short power2[15] = { 1,     2,     4,     8,     0x10,   0x20,   0x40,  0x80,
                             0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000 };
@@ -76,165 +189,6 @@ static int fmult(int an, int srn)
     return (((an ^ srn) < 0) ? -retval : retval);
 }
 
-/*
- * g72x_init_state()
- *
- * This routine initializes and/or resets the g72x_state structure
- * pointed to by 'state_ptr'.
- * All the initial state values are specified in the CCITT G.721 document.
- */
-void g72x_init_state(struct g72x_state* state_ptr)
-{
-    int cnta;
-
-    state_ptr->yl = 34816;
-    state_ptr->yu = 544;
-    state_ptr->dms = 0;
-    state_ptr->dml = 0;
-    state_ptr->ap = 0;
-    for (cnta = 0; cnta < 2; cnta++) {
-        state_ptr->a[cnta] = 0;
-        state_ptr->pk[cnta] = 0;
-        state_ptr->sr[cnta] = 32;
-    }
-    for (cnta = 0; cnta < 6; cnta++) {
-        state_ptr->b[cnta] = 0;
-        state_ptr->dq[cnta] = 32;
-    }
-    state_ptr->td = 0;
-}
-
-/*
- * predictor_zero()
- *
- * computes the estimated signal from 6-zero predictor.
- *
- */
-int predictor_zero(struct g72x_state* state_ptr)
-{
-    int i;
-    int sezi;
-
-    sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]);
-    for (i = 1; i < 6; i++) /* ACCUM */
-        sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]);
-    return (sezi);
-}
-/*
- * predictor_pole()
- *
- * computes the estimated signal from 2-pole predictor.
- *
- */
-int predictor_pole(struct g72x_state* state_ptr)
-{
-    return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) +
-            fmult(state_ptr->a[0] >> 2, state_ptr->sr[0]));
-}
-/*
- * step_size()
- *
- * computes the quantization step size of the adaptive quantizer.
- *
- */
-int step_size(struct g72x_state* state_ptr)
-{
-    int y;
-    int dif;
-    int al;
-
-    if (state_ptr->ap >= 256)
-        return (state_ptr->yu);
-    else {
-        y = state_ptr->yl >> 6;
-        dif = state_ptr->yu - y;
-        al = state_ptr->ap >> 2;
-        if (dif > 0)
-            y += (dif * al) >> 6;
-        else if (dif < 0)
-            y += (dif * al + 0x3F) >> 6;
-        return (y);
-    }
-}
-
-/*
- * quantize()
- *
- * Given a raw sample, 'd', of the difference signal and a
- * quantization step size scale factor, 'y', this routine returns the
- * ADPCM codeword to which that sample gets quantized.  The step
- * size scale factor division operation is done in the log base 2 domain
- * as a subtraction.
- */
-int quantize(int d,        /* Raw difference signal sample */
-             int y,        /* Step size multiplier */
-             short* table, /* quantization table */
-             int size)     /* table size of short integers */
-{
-    short dqm;  /* Magnitude of 'd' */
-    short exp;  /* Integer part of base 2 log of 'd' */
-    short mant; /* Fractional part of base 2 log */
-    short dl;   /* Log of magnitude of 'd' */
-    short dln;  /* Step size scale factor normalized log */
-    int i;
-
-    /*
-     * LOG
-     *
-     * Compute base 2 log of 'd', and store in 'dl'.
-     */
-    dqm = abs(d);
-    exp = quan(dqm >> 1, power2, 15);
-    mant = ((dqm << 7) >> exp) & 0x7F; /* Fractional portion. */
-    dl = (exp << 7) + mant;
-
-    /*
-     * SUBTB
-     *
-     * "Divide" by step size multiplier.
-     */
-    dln = dl - (y >> 2);
-
-    /*
-     * QUAN
-     *
-     * Obtain codword i for 'd'.
-     */
-    i = quan(dln, table, size);
-    if (d < 0) /* take 1's complement of i */
-        return ((size << 1) + 1 - i);
-    else if (i == 0)              /* take 1's complement of 0 */
-        return ((size << 1) + 1); /* new in 1988 */
-    else
-        return (i);
-}
-/*
- * reconstruct()
- *
- * Returns reconstructed difference signal 'dq' obtained from
- * codeword 'i' and quantization step size scale factor 'y'.
- * Multiplication is performed in log base 2 domain as addition.
- */
-int reconstruct(int sign, /* 0 for non-negative value */
-                int dqln, /* G.72x codeword */
-                int y)    /* Step size multiplier */
-{
-    short dql; /* Log of 'dq' magnitude */
-    short dex; /* Integer part of log */
-    short dqt;
-    short dq; /* Reconstructed difference signal sample */
-
-    dql = dqln + (y >> 2); /* ADDA */
-
-    if (dql < 0) {
-        return ((sign) ? -0x8000 : 0);
-    } else { /* ANTILOG */
-        dex = (dql >> 7) & 15;
-        dqt = 128 + (dql & 127);
-        dq = (dqt << 7) >> (14 - dex);
-        return ((sign) ? (dq - 0x8000) : dq);
-    }
-}
 
 
 /*
@@ -428,105 +382,163 @@ void update(int code_size,                /* distinguish 723_40 with others */
         state_ptr->ap += (-state_ptr->ap) >> 4;
 }
 
+
 /*
- * tandem_adjust(sr, se, y, i, sign)
+ * g72x_init_state()
  *
- * At the end of ADPCM decoding, it simulates an encoder which may be receiving
- * the output of this decoder as a tandem process. If the output of the
- * simulated encoder differs from the input to this decoder, the decoder output
- * is adjusted by one level of A-law or u-law codes.
+ * This routine initializes and/or resets the g72x_state structure
+ * pointed to by 'state_ptr'.
+ * All the initial state values are specified in the CCITT G.721 document.
+ */
+void g72x_init_state(struct g72x_state* state_ptr)
+{
+    int cnta;
+
+    state_ptr->yl = 34816;
+    state_ptr->yu = 544;
+    state_ptr->dms = 0;
+    state_ptr->dml = 0;
+    state_ptr->ap = 0;
+    for (cnta = 0; cnta < 2; cnta++) {
+        state_ptr->a[cnta] = 0;
+        state_ptr->pk[cnta] = 0;
+        state_ptr->sr[cnta] = 32;
+    }
+    for (cnta = 0; cnta < 6; cnta++) {
+        state_ptr->b[cnta] = 0;
+        state_ptr->dq[cnta] = 32;
+    }
+    state_ptr->td = 0;
+}
+
+/*
+ * predictor_zero()
  *
- * Input:
- *	sr	decoder output linear PCM sample,
- *	se	predictor estimate sample,
- *	y	quantizer step size,
- *	i	decoder input code,
- *	sign	sign bit of code i
+ * computes the estimated signal from 6-zero predictor.
  *
- * Return:
- *	adjusted A-law or u-law compressed sample.
  */
-int tandem_adjust_alaw(int sr, /* decoder output linear PCM sample */
-                       int se, /* predictor estimate sample */
-                       int y,  /* quantizer step size */
-                       int i,  /* decoder input code */
-                       int sign,
-                       short* qtab)
+int predictor_zero(struct g72x_state* state_ptr)
 {
-    unsigned char sp; /* A-law compressed 8-bit code */
-    short dx;         /* prediction error */
-    char id;          /* quantized prediction error */
-    int sd;           /* adjusted A-law decoded sample value */
-    int im;           /* biased magnitude of i */
-    int imx;          /* biased magnitude of id */
-
-    if (sr <= -32768)
-        sr = -1;
-    sp = linear2alaw((sr >> 1) << 3); /* short to A-law compression */
-    dx = (alaw2linear(sp) >> 2) - se; /* 16-bit prediction error */
-    id = quantize(dx, y, qtab, sign - 1);
-
-    if (id == i) { /* no adjustment on sp */
-        return (sp);
-    } else { /* sp adjustment needed */
-        /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */
-        im = i ^ sign; /* 2's complement to biased unsigned */
-        imx = id ^ sign;
-
-        if (imx > im) { /* sp adjusted to next lower value */
-            if (sp & 0x80) {
-                sd = (sp == 0xD5) ? 0x55 : ((sp ^ 0x55) - 1) ^ 0x55;
-            } else {
-                sd = (sp == 0x2A) ? 0x2A : ((sp ^ 0x55) + 1) ^ 0x55;
-            }
-        } else { /* sp adjusted to next higher value */
-            if (sp & 0x80)
-                sd = (sp == 0xAA) ? 0xAA : ((sp ^ 0x55) + 1) ^ 0x55;
-            else
-                sd = (sp == 0x55) ? 0xD5 : ((sp ^ 0x55) - 1) ^ 0x55;
-        }
-        return (sd);
+    int i;
+    int sezi;
+
+    sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]);
+    for (i = 1; i < 6; i++) /* ACCUM */
+        sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]);
+    return (sezi);
+}
+/*
+ * predictor_pole()
+ *
+ * computes the estimated signal from 2-pole predictor.
+ *
+ */
+int predictor_pole(struct g72x_state* state_ptr)
+{
+    return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) +
+            fmult(state_ptr->a[0] >> 2, state_ptr->sr[0]));
+}
+/*
+ * step_size()
+ *
+ * computes the quantization step size of the adaptive quantizer.
+ *
+ */
+int step_size(struct g72x_state* state_ptr)
+{
+    int y;
+    int dif;
+    int al;
+
+    if (state_ptr->ap >= 256)
+        return (state_ptr->yu);
+    else {
+        y = state_ptr->yl >> 6;
+        dif = state_ptr->yu - y;
+        al = state_ptr->ap >> 2;
+        if (dif > 0)
+            y += (dif * al) >> 6;
+        else if (dif < 0)
+            y += (dif * al + 0x3F) >> 6;
+        return (y);
     }
 }
 
-int tandem_adjust_ulaw(int sr, /* decoder output linear PCM sample */
-                       int se, /* predictor estimate sample */
-                       int y,  /* quantizer step size */
-                       int i,  /* decoder input code */
-                       int sign,
-                       short* qtab)
+/*
+ * quantize()
+ *
+ * Given a raw sample, 'd', of the difference signal and a
+ * quantization step size scale factor, 'y', this routine returns the
+ * ADPCM codeword to which that sample gets quantized.  The step
+ * size scale factor division operation is done in the log base 2 domain
+ * as a subtraction.
+ */
+int quantize(int d,        /* Raw difference signal sample */
+             int y,        /* Step size multiplier */
+             short* table, /* quantization table */
+             int size)     /* table size of short integers */
 {
-    unsigned char sp; /* u-law compressed 8-bit code */
-    short dx;         /* prediction error */
-    char id;          /* quantized prediction error */
-    int sd;           /* adjusted u-law decoded sample value */
-    int im;           /* biased magnitude of i */
-    int imx;          /* biased magnitude of id */
-
-    if (sr <= -32768)
-        sr = 0;
-    sp = linear2ulaw(sr << 2);        /* short to u-law compression */
-    dx = (ulaw2linear(sp) >> 2) - se; /* 16-bit prediction error */
-    id = quantize(dx, y, qtab, sign - 1);
-    if (id == i) {
-        return (sp);
-    } else {
-        /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */
-        im = i ^ sign; /* 2's complement to biased unsigned */
-        imx = id ^ sign;
-        if (imx > im) { /* sp adjusted to next lower value */
-            if (sp & 0x80)
-                sd = (sp == 0xFF) ? 0x7E : sp + 1;
-            else
-                sd = (sp == 0) ? 0 : sp - 1;
+    short dqm;  /* Magnitude of 'd' */
+    short exp;  /* Integer part of base 2 log of 'd' */
+    short mant; /* Fractional part of base 2 log */
+    short dl;   /* Log of magnitude of 'd' */
+    short dln;  /* Step size scale factor normalized log */
+    int i;
 
-        } else { /* sp adjusted to next higher value */
-            if (sp & 0x80)
-                sd = (sp == 0x80) ? 0x80 : sp - 1;
-            else
-                sd = (sp == 0x7F) ? 0xFE : sp + 1;
-        }
-        return (sd);
-    }
+    /*
+     * LOG
+     *
+     * Compute base 2 log of 'd', and store in 'dl'.
+     */
+    dqm = abs(d);
+    exp = quan(dqm >> 1, power2, 15);
+    mant = ((dqm << 7) >> exp) & 0x7F; /* Fractional portion. */
+    dl = (exp << 7) + mant;
+
+    /*
+     * SUBTB
+     *
+     * "Divide" by step size multiplier.
+     */
+    dln = dl - (y >> 2);
+
+    /*
+     * QUAN
+     *
+     * Obtain codword i for 'd'.
+     */
+    i = quan(dln, table, size);
+    if (d < 0) /* take 1's complement of i */
+        return ((size << 1) + 1 - i);
+    else if (i == 0)              /* take 1's complement of 0 */
+        return ((size << 1) + 1); /* new in 1988 */
+    else
+        return (i);
 }
+/*
+ * reconstruct()
+ *
+ * Returns reconstructed difference signal 'dq' obtained from
+ * codeword 'i' and quantization step size scale factor 'y'.
+ * Multiplication is performed in log base 2 domain as addition.
+ */
+int reconstruct(int sign, /* 0 for non-negative value */
+                int dqln, /* G.72x codeword */
+                int y)    /* Step size multiplier */
+{
+    short dql; /* Log of 'dq' magnitude */
+    short dex; /* Integer part of log */
+    short dqt;
+    short dq; /* Reconstructed difference signal sample */
+
+    dql = dqln + (y >> 2); /* ADDA */
 
+    if (dql < 0) {
+        return ((sign) ? -0x8000 : 0);
+    } else { /* ANTILOG */
+        dex = (dql >> 7) & 15;
+        dqt = 128 + (dql & 127);
+        dq = (dqt << 7) >> (14 - dex);
+        return ((sign) ? (dq - 0x8000) : dq);
+    }
+}

+ 2 - 21
g72x.h → audio/g721.h

@@ -33,10 +33,6 @@
 #ifndef _G72X_H
 #define _G72X_H
 
-#define AUDIO_ENCODING_ULAW (1)   /* ISDN u-law */
-#define AUDIO_ENCODING_ALAW (2)   /* ISDN A-law */
-#define AUDIO_ENCODING_LINEAR (3) /* PCM 2's-complement (0-center) */
-
 /*
  * The following is the definition of the state structure
  * used by the G.721/G.723 encoder and decoder to preserve their internal
@@ -75,12 +71,8 @@ struct g72x_state {
 /* External function definitions. */
 
 void g72x_init_state(struct g72x_state*);
-int g721_encoder(int sample, int in_coding, struct g72x_state* state_ptr);
-int g721_decoder(int code, int out_coding, struct g72x_state* state_ptr);
-int g723_24_encoder(int sample, int in_coding, struct g72x_state* state_ptr);
-int g723_24_decoder(int code, int out_coding, struct g72x_state* state_ptr);
-int g723_40_encoder(int sample, int in_coding, struct g72x_state* state_ptr);
-int g723_40_decoder(int code, int out_coding, struct g72x_state* state_ptr);
+int g721_encoder(int sample, struct g72x_state* state_ptr);
+int g721_decoder(int code, struct g72x_state* state_ptr);
 
 
 int quantize(int d, int y, short* table, int size);
@@ -95,17 +87,6 @@ void
                   int sr,
                   int dqsez,
                   struct g72x_state* state_ptr);
-int tandem_adjust_alaw(int sr, int se, int y, int i, int sign, short* qtab);
-
-int tandem_adjust_ulaw(int sr, int se, int y, int i, int sign, short* qtab);
-
-unsigned char linear2alaw(int pcm_val);
-
-int alaw2linear(unsigned char a_val);
-
-unsigned char linear2ulaw(int pcm_val);
-
-int ulaw2linear(unsigned char u_val);
 
 int predictor_zero(struct g72x_state* state_ptr);
 

+ 0 - 0
wav_player_hal.c → audio/wav_player_hal.c


+ 0 - 0
wav_player_hal.h → audio/wav_player_hal.h


+ 0 - 256
g711.c

@@ -1,256 +0,0 @@
-/*
- * This source code is a product of Sun Microsystems, Inc. and is provided
- * for unrestricted use.  Users may copy or modify this source code without
- * charge.
- *
- * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
- * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun source code is provided with no support and without any obligation on
- * the part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-
-/*
- * g711.c
- *
- * u-law, A-law and linear PCM conversions.
- */
-#define SIGN_BIT (0x80)  /* Sign bit for a A-law byte. */
-#define QUANT_MASK (0xf) /* Quantization field mask. */
-#define NSEGS (8)        /* Number of A-law segments. */
-#define SEG_SHIFT (4)    /* Left shift for segment number. */
-#define SEG_MASK (0x70)  /* Segment field mask. */
-
-static short seg_end[8] = { 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF };
-
-/* copy from CCITT G.711 specifications */
-unsigned char _u2a[128] = { /* u- to A-law conversions */
-                            1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,
-                            7,   7,   8,   8,   9,   10,  11,  12,  13,  14,  15,  16,
-                            17,  18,  19,  20,  21,  22,  23,  24,  25,  27,  29,  31,
-                            33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,
-                            46,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,
-                            59,  60,  61,  62,  64,  65,  66,  67,  68,  69,  70,  71,
-                            72,  73,  74,  75,  76,  77,  78,  79,  81,  82,  83,  84,
-                            85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,
-                            97,  98,  99,  100, 101, 102, 103, 104, 105, 106, 107, 108,
-                            109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
-                            121, 122, 123, 124, 125, 126, 127, 128
-};
-
-unsigned char _a2u[128] = { /* A- to u-law conversions */
-                            1,   3,   5,   7,   9,   11,  13,  15,  16,  17,  18,  19,
-                            20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,
-                            32,  32,  33,  33,  34,  34,  35,  35,  36,  37,  38,  39,
-                            40,  41,  42,  43,  44,  45,  46,  47,  48,  48,  49,  49,
-                            50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,
-                            62,  63,  64,  64,  65,  66,  67,  68,  69,  70,  71,  72,
-                            73,  74,  75,  76,  77,  78,  79,  79,  80,  81,  82,  83,
-                            84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
-                            96,  97,  98,  99,  100, 101, 102, 103, 104, 105, 106, 107,
-                            108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
-                            120, 121, 122, 123, 124, 125, 126, 127
-};
-
-static int search(int val, short* table, int size)
-{
-    int i;
-
-    for (i = 0; i < size; i++) {
-        if (val <= *table++)
-            return (i);
-    }
-    return (size);
-}
-
-/*
- * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
- *
- * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
- *
- *		Linear Input Code	Compressed Code
- *	------------------------	---------------
- *	0000000wxyza			000wxyz
- *	0000001wxyza			001wxyz
- *	000001wxyzab			010wxyz
- *	00001wxyzabc			011wxyz
- *	0001wxyzabcd			100wxyz
- *	001wxyzabcde			101wxyz
- *	01wxyzabcdef			110wxyz
- *	1wxyzabcdefg			111wxyz
- *
- * For further information see John C. Bellamy's Digital Telephony, 1982,
- * John Wiley & Sons, pps 98-111 and 472-476.
- */
-unsigned char linear2alaw(int pcm_val) /* 2's complement (16-bit range) */
-{
-    int mask;
-    int seg;
-    unsigned char aval;
-
-    if (pcm_val >= 0) {
-        mask = 0xD5; /* sign (7th) bit = 1 */
-    } else {
-        mask = 0x55; /* sign bit = 0 */
-        pcm_val = -pcm_val - 8;
-    }
-
-    /* Convert the scaled magnitude to segment number. */
-    seg = search(pcm_val, seg_end, 8);
-
-    /* Combine the sign, segment, and quantization bits. */
-
-    if (seg >= 8) /* out of range, return maximum value. */
-        return (0x7F ^ mask);
-    else {
-        aval = seg << SEG_SHIFT;
-        if (seg < 2)
-            aval |= (pcm_val >> 4) & QUANT_MASK;
-        else
-            aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
-        return (aval ^ mask);
-    }
-}
-
-/*
- * alaw2linear() - Convert an A-law value to 16-bit linear PCM
- *
- */
-int alaw2linear(unsigned char a_val)
-{
-    int t;
-    int seg;
-
-    a_val ^= 0x55;
-
-    t = (a_val & QUANT_MASK) << 4;
-    seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
-    switch (seg) {
-    case 0:
-        t += 8;
-        break;
-    case 1:
-        t += 0x108;
-        break;
-    default:
-        t += 0x108;
-        t <<= seg - 1;
-    }
-    return ((a_val & SIGN_BIT) ? t : -t);
-}
-
-#define BIAS (0x84) /* Bias for linear code. */
-
-/*
- * linear2ulaw() - Convert a linear PCM value to u-law
- *
- * In order to simplify the encoding process, the original linear magnitude
- * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
- * (33 - 8191). The result can be seen in the following encoding table:
- *
- *	Biased Linear Input Code	Compressed Code
- *	------------------------	---------------
- *	00000001wxyza			000wxyz
- *	0000001wxyzab			001wxyz
- *	000001wxyzabc			010wxyz
- *	00001wxyzabcd			011wxyz
- *	0001wxyzabcde			100wxyz
- *	001wxyzabcdef			101wxyz
- *	01wxyzabcdefg			110wxyz
- *	1wxyzabcdefgh			111wxyz
- *
- * Each biased linear code has a leading 1 which identifies the segment
- * number. The value of the segment number is equal to 7 minus the number
- * of leading 0's. The quantization interval is directly available as the
- * four bits wxyz.  * The trailing bits (a - h) are ignored.
- *
- * Ordinarily the complement of the resulting code word is used for
- * transmission, and so the code word is complemented before it is returned.
- *
- * For further information see John C. Bellamy's Digital Telephony, 1982,
- * John Wiley & Sons, pps 98-111 and 472-476.
- */
-unsigned char linear2ulaw(int pcm_val) /* 2's complement (16-bit range) */
-{
-    int mask;
-    int seg;
-    unsigned char uval;
-
-    /* Get the sign and the magnitude of the value. */
-    if (pcm_val < 0) {
-        pcm_val = BIAS - pcm_val;
-        mask = 0x7F;
-    } else {
-        pcm_val += BIAS;
-        mask = 0xFF;
-    }
-
-    /* Convert the scaled magnitude to segment number. */
-    seg = search(pcm_val, seg_end, 8);
-
-    /*
-     * Combine the sign, segment, quantization bits;
-     * and complement the code word.
-     */
-    if (seg >= 8) /* out of range, return maximum value. */
-        return (0x7F ^ mask);
-    else {
-        uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
-        return (uval ^ mask);
-    }
-}
-
-/*
- * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
- *
- * First, a biased linear code is derived from the code word. An unbiased
- * output can then be obtained by subtracting 33 from the biased code.
- *
- * Note that this function expects to be passed the complement of the
- * original code word. This is in keeping with ISDN conventions.
- */
-int ulaw2linear(unsigned char u_val)
-{
-    int t;
-
-    /* Complement to obtain normal u-law value. */
-    u_val = ~u_val;
-
-    /*
-     * Extract and bias the quantization bits. Then
-     * shift up by the segment number and subtract out the bias.
-     */
-    t = ((u_val & QUANT_MASK) << 3) + BIAS;
-    t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
-
-    return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
-}
-
-/* A-law to u-law conversion */
-unsigned char alaw2ulaw(unsigned char aval)
-{
-    aval &= 0xff;
-    return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) : (0x7F ^ _a2u[aval ^ 0x55]));
-}
-
-/* u-law to A-law conversion */
-unsigned char ulaw2alaw(unsigned char uval)
-{
-    uval &= 0xff;
-    return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1))
-                          : (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
-}

+ 0 - 165
g721.c

@@ -1,165 +0,0 @@
-/*
- * This source code is a product of Sun Microsystems, Inc. and is provided
- * for unrestricted use.  Users may copy or modify this source code without
- * charge.
- *
- * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
- * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun source code is provided with no support and without any obligation on
- * the part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-
-/*
- * g721.c
- *
- * Description:
- *
- * g721_encoder(), g721_decoder()
- *
- * These routines comprise an implementation of the CCITT G.721 ADPCM
- * coding algorithm.  Essentially, this implementation is identical to
- * the bit level description except for a few deviations which
- * take advantage of work station attributes, such as hardware 2's
- * complement arithmetic and large memory.  Specifically, certain time
- * consuming operations such as multiplications are replaced
- * with lookup tables and software 2's complement operations are
- * replaced with hardware 2's complement.
- *
- * The deviation from the bit level specification (lookup tables)
- * preserves the bit level performance specifications.
- *
- * As outlined in the G.721 Recommendation, the algorithm is broken
- * down into modules.  Each section of code below is preceded by
- * the name of the module which it is implementing.
- *
- */
-#include "g72x.h"
-
-static short qtab_721[7] = { -124, 80, 178, 246, 300, 349, 400 };
-/*
- * Maps G.721 code word to reconstructed scale factor normalized log
- * magnitude values.
- */
-static short _dqlntab[16] = { -2048, 4,   135, 213, 273, 323, 373, 425,
-                              425,   373, 323, 273, 213, 135, 4,   -2048 };
-
-/* Maps G.721 code word to log of scale factor multiplier. */
-static short _witab[16] = { -12,  18,  41,  64,  112, 198, 355, 1122,
-                            1122, 355, 198, 112, 64,  41,  18,  -12 };
-/*
- * Maps G.721 code words to a set of values whose long and short
- * term averages are computed and then compared to give an indication
- * how stationary (steady state) the signal is.
- */
-static short _fitab[16] = { 0,     0,     0,     0x200, 0x200, 0x200, 0x600, 0xE00,
-                            0xE00, 0x600, 0x200, 0x200, 0x200, 0,     0,     0 };
-
-/*
- * g721_encoder()
- *
- * Encodes the input vale of linear PCM, A-law or u-law data sl and returns
- * the resulting code. -1 is returned for unknown input coding value.
- */
-int g721_encoder(int sl, int in_coding, struct g72x_state* state_ptr)
-{
-    short sezi, se, sez; /* ACCUM */
-    short d;             /* SUBTA */
-    short sr;            /* ADDB */
-    short y;             /* MIX */
-    short dqsez;         /* ADDC */
-    short dq, i;
-
-    switch (in_coding) { /* linearize input sample to 14-bit PCM */
-    case AUDIO_ENCODING_ALAW:
-        sl = alaw2linear(sl) >> 2;
-        break;
-    case AUDIO_ENCODING_ULAW:
-        sl = ulaw2linear(sl) >> 2;
-        break;
-    case AUDIO_ENCODING_LINEAR:
-        sl >>= 2; /* 14-bit dynamic range */
-        break;
-    default:
-        return (-1);
-    }
-
-    sezi = predictor_zero(state_ptr);
-    sez = sezi >> 1;
-    se = (sezi + predictor_pole(state_ptr)) >> 1; /* estimated signal */
-
-    d = sl - se; /* estimation difference */
-
-    /* quantize the prediction difference */
-    y = step_size(state_ptr);        /* quantizer step size */
-    i = quantize(d, y, qtab_721, 7); /* i = ADPCM code */
-
-    dq = reconstruct(i & 8, _dqlntab[i], y); /* quantized est diff */
-
-    sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconst. signal */
-
-    dqsez = sr + sez - se; /* pole prediction diff. */
-
-    update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
-
-    return (i);
-}
-
-/*
- * g721_decoder()
- *
- * Description:
- *
- * Decodes a 4-bit code of G.721 encoded data of i and
- * returns the resulting linear PCM, A-law or u-law value.
- * return -1 for unknown out_coding value.
- */
-int g721_decoder(int i, int out_coding, struct g72x_state* state_ptr)
-{
-    short sezi, sei, sez, se; /* ACCUM */
-    short y;                  /* MIX */
-    short sr;                 /* ADDB */
-    short dq;
-    short dqsez;
-
-    i &= 0x0f; /* mask to get proper bits */
-    sezi = predictor_zero(state_ptr);
-    sez = sezi >> 1;
-    sei = sezi + predictor_pole(state_ptr);
-    se = sei >> 1; /* se = estimated signal */
-
-    y = step_size(state_ptr); /* dynamic quantizer step size */
-
-    dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */
-
-    sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */
-
-    dqsez = sr - se + sez; /* pole prediction diff. */
-
-    update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
-
-    switch (out_coding) {
-    case AUDIO_ENCODING_ALAW:
-        return (tandem_adjust_alaw(sr, se, y, i, 8, qtab_721));
-    case AUDIO_ENCODING_ULAW:
-        return (tandem_adjust_ulaw(sr, se, y, i, 8, qtab_721));
-    case AUDIO_ENCODING_LINEAR:
-        return (sr << 2); /* sr was 14-bit dynamic range */
-    default:
-        return (-1);
-    }
-}

+ 0 - 24
test.py

@@ -1,24 +0,0 @@
-import usb.core
-import usb.util
-import time
-
-# Find our device
-dev = usb.core.find(idVendor=0x1430, idProduct=0x0150)
-if dev is None:
-    raise ValueError('Device not found')
-try:
-    dev.detach_kernel_driver(0)
-except:
-    pass
-dev.ctrl_transfer(0x21, 9, wValue=0x0200, wIndex=0, data_or_wLength=b"C\xff\x00\x00", timeout=None)
-time.sleep(0.001)
-
-while True:
-    dev.ctrl_transfer(0x21, 9, wValue=0x0200, wIndex=0, data_or_wLength=b"J\x00\xff\x00\x00\xD0\x07", timeout=None)
-    time.sleep(3)
-    dev.ctrl_transfer(0x21, 9, wValue=0x0200, wIndex=0, data_or_wLength=b"J\x00\x00\xff\x00\xD0\x07", timeout=None)
-
-    time.sleep(3)
-    dev.ctrl_transfer(0x21, 9, wValue=0x0200, wIndex=0, data_or_wLength=b"J\x00\x00\x00\xff\xD0\x07", timeout=None)
-
-    time.sleep(3)

+ 3 - 3
virtual_portal.c

@@ -3,7 +3,7 @@
 #include <furi_hal.h>
 #include <stm32wbxx_ll_dma.h>
 #include "string.h"
-#include "wav_player_hal.h"
+#include "audio/wav_player_hal.h"
 
 #define TAG "VirtualPortal"
 
@@ -580,7 +580,7 @@ void virtual_portal_process_audio_360(
     uint8_t len) {
     for (size_t i = 0; i < len; i++) {
         
-        int16_t int_16 = (int16_t)g721_decoder(message[i],AUDIO_ENCODING_LINEAR, &virtual_portal->state);
+        int16_t int_16 = (int16_t)g721_decoder(message[i], &virtual_portal->state);
 
         float data = ((float)int_16 / 256.0);
         data /= UINT8_MAX / 2;  // scale -1..1
@@ -604,7 +604,7 @@ void virtual_portal_process_audio_360(
             virtual_portal->head = virtual_portal->current_audio_buffer;
         }
 
-        int_16 = (int16_t)g721_decoder(message[i] >> 4,AUDIO_ENCODING_LINEAR, &virtual_portal->state);
+        int_16 = (int16_t)g721_decoder(message[i] >> 4, &virtual_portal->state);
 
         data = ((float)int_16 / 256.0);
         data /= UINT8_MAX / 2;  // scale -1..1

+ 1 - 1
virtual_portal.h

@@ -4,7 +4,7 @@
 #include <notification/notification_messages.h>
 
 #include "pof_token.h"
-#include "g72x.h"
+#include "audio/g721.h"
 
 #define SAMPLE_RATE 8000
 #define POF_TOKEN_LIMIT 16