Add GSM full rate codec to LCR's source repository
authorAndreas Eversberg <jolly@eversberg.eu>
Sat, 9 Mar 2013 17:15:33 +0000 (18:15 +0100)
committerAndreas Eversberg <jolly@eversberg.eu>
Sat, 9 Mar 2013 17:15:33 +0000 (18:15 +0100)
There is no more need to download a seperate version of GSM full rate
(06.10) codec anymore.

69 files changed:
.gitignore
Makefile.am
configure.ac
gsm.cpp
gsm.h
gsm_audio.c
gsm_audio.h
libgsmfr/COPYRIGHT [new file with mode: 0644]
libgsmfr/ChangeLog [new file with mode: 0644]
libgsmfr/INSTALL [new file with mode: 0644]
libgsmfr/MACHINES [new file with mode: 0644]
libgsmfr/MANIFEST [new file with mode: 0644]
libgsmfr/Makefile [new file with mode: 0644]
libgsmfr/README [new file with mode: 0644]
libgsmfr/add-test/add_test.c [new file with mode: 0644]
libgsmfr/add-test/add_test.dta [new file with mode: 0644]
libgsmfr/inc/config.h [new file with mode: 0644]
libgsmfr/inc/gsm.h [new file with mode: 0644]
libgsmfr/inc/gsm.h.orig [new file with mode: 0644]
libgsmfr/inc/private.h [new file with mode: 0644]
libgsmfr/inc/proto.h [new file with mode: 0644]
libgsmfr/inc/toast.h [new file with mode: 0644]
libgsmfr/inc/unproto.h [new file with mode: 0644]
libgsmfr/man/bitter.1 [new file with mode: 0644]
libgsmfr/man/gsm.3 [new file with mode: 0644]
libgsmfr/man/gsm_explode.3 [new file with mode: 0644]
libgsmfr/man/gsm_option.3 [new file with mode: 0644]
libgsmfr/man/gsm_print.3 [new file with mode: 0644]
libgsmfr/man/toast.1 [new file with mode: 0644]
libgsmfr/src/add.c [new file with mode: 0644]
libgsmfr/src/code.c [new file with mode: 0644]
libgsmfr/src/debug.c [new file with mode: 0644]
libgsmfr/src/decode.c [new file with mode: 0644]
libgsmfr/src/gsm_create.c [new file with mode: 0644]
libgsmfr/src/gsm_decode.c [new file with mode: 0644]
libgsmfr/src/gsm_destroy.c [new file with mode: 0644]
libgsmfr/src/gsm_encode.c [new file with mode: 0644]
libgsmfr/src/gsm_explode.c [new file with mode: 0644]
libgsmfr/src/gsm_implode.c [new file with mode: 0644]
libgsmfr/src/gsm_option.c [new file with mode: 0644]
libgsmfr/src/gsm_print.c [new file with mode: 0644]
libgsmfr/src/long_term.c [new file with mode: 0644]
libgsmfr/src/lpc.c [new file with mode: 0644]
libgsmfr/src/preprocess.c [new file with mode: 0644]
libgsmfr/src/rpe.c [new file with mode: 0644]
libgsmfr/src/short_term.c [new file with mode: 0644]
libgsmfr/src/table.c [new file with mode: 0644]
libgsmfr/src/toast.c [new file with mode: 0644]
libgsmfr/src/toast_alaw.c [new file with mode: 0644]
libgsmfr/src/toast_audio.c [new file with mode: 0644]
libgsmfr/src/toast_lin.c [new file with mode: 0644]
libgsmfr/src/toast_ulaw.c [new file with mode: 0644]
libgsmfr/tls/bitter.c [new file with mode: 0644]
libgsmfr/tls/bitter.dta [new file with mode: 0644]
libgsmfr/tls/ginger.c [new file with mode: 0644]
libgsmfr/tls/sour.c [new file with mode: 0644]
libgsmfr/tls/sour1.dta [new file with mode: 0644]
libgsmfr/tls/sour2.dta [new file with mode: 0644]
libgsmfr/tls/sweet.c [new file with mode: 0644]
libgsmfr/tls/taste.c [new file with mode: 0644]
libgsmfr/tls/taste.h [new file with mode: 0644]
libgsmfr/tst/cod2lin.c [new file with mode: 0644]
libgsmfr/tst/cod2txt.c [new file with mode: 0644]
libgsmfr/tst/gsm2cod.c [new file with mode: 0644]
libgsmfr/tst/lin2cod.c [new file with mode: 0644]
libgsmfr/tst/lin2txt.c [new file with mode: 0644]
libgsmfr/tst/run [new file with mode: 0644]
libtool [new file with mode: 0644]
ltmain.sh [new file with mode: 0644]

index c11c990..119050e 100644 (file)
@@ -7,7 +7,9 @@ core
 conf*.dir
 stamp-h1
 .deps/
-Makefile
+include/Makefile
+libgsmfr/bin/
+libgsmfr/lib/
 config.h
 config.log
 config.status
index e802edc..e35f6f0 100644 (file)
@@ -51,22 +51,25 @@ MISDN_LIB = -lmisdn
 
 endif
 
+SUBDIRS =
+
 GSM_INCLUDE =
 GSM_SOURCE =
 GSM_LIB =
 
 if ENABLE_GSM
 
-GSM_INCLUDE +=
+#if ENABLE_GSMHR
 
-GSM_SOURCE += gsm_audio.c gsm.cpp
-  
-GSM_LIB += /usr/lib/libgsm.a
+GSM_INCLUDE += -DWITH_GSMFR
 
-#gsm_audio.po: gsm_audio.c gsm_audio.h
-#      $(CC) -D_GNU_SOURCE -fPIC -c gsm_audio.c -o gsm_audio.po
+GSM_LIB += libgsmfr/lib/libgsm.a
 
-endif
+SUBDIRS += libgsmfr
+
+#endif
+
+GSM_SOURCE += gsm_audio.c gsm.cpp
 
 if ENABLE_GSM_BS
 
@@ -83,6 +86,8 @@ GSM_INCLUDE += -DWITH_GSM_MS
 GSM_SOURCE += gsm_ms.cpp
 
 endif
+endif
+
 
 if ENABLE_SS5
 
index c36340c..8a3cba3 100644 (file)
@@ -183,15 +183,6 @@ AM_CONDITIONAL(ENABLE_GSM_MS, test "x$with_gsm_ms" == "xyes" )
 
 AM_CONDITIONAL(ENABLE_GSM, test "x$with_gsm_bs" == "xyes" -o "x$with_gsm_ms" == "xyes")
 
-AS_IF([test "x$with_gsm_bs" == xyes -o "x$with_gsm_ms" == xyes],
-       [AC_MSG_CHECKING(/usr/include/gsm/gsm.h)
-       if test -e /usr/include/gsm/gsm.h; then
-               AC_MSG_RESULT(yes)
-       else
-       AC_MSG_FAILURE([You have enabled GSM, but /usr/include/gsm/gsm.h not found! Please install the lossy GSM codec. Be sure to install it in /usr/ and not in /usr/local/. You will also find a copy on http://www.linux-call-router.de.])
-       fi
-       ])
-
 # check for ss5
 AC_ARG_WITH([ss5],
        [AS_HELP_STRING([--with-ss5],
diff --git a/gsm.cpp b/gsm.cpp
index 3157e10..b6372f5 100644 (file)
--- a/gsm.cpp
+++ b/gsm.cpp
@@ -180,12 +180,20 @@ Pgsm::Pgsm(int type, char *portname, struct port_settings *settings, struct inte
        p_g_notify_pending = NULL;
        p_g_setup_pending = NULL;
        p_g_connect_pending = NULL;
-       p_g_decoder = gsm_audio_create();
-       p_g_encoder = gsm_audio_create();
-       if (!p_g_encoder || !p_g_decoder) {
-               PERROR("Failed to create GSM audio codec instance\n");
+       p_g_fr_decoder = NULL;
+       p_g_fr_encoder = NULL;
+       p_g_hr_decoder = NULL;
+       p_g_hr_encoder = NULL;
+       p_g_amr_decoder = NULL;
+       p_g_amr_encoder = NULL;
+#ifdef WITH_GSMFR
+       p_g_fr_decoder = gsm_fr_create();
+       p_g_fr_encoder = gsm_fr_create();
+       if (!p_g_fr_encoder || !p_g_fr_decoder) {
+               PERROR("Failed to create GSM FR codec instance\n");
                trigger_work(&p_g_delete);
        }
+#endif
        p_g_rxpos = 0;
        p_g_tch_connected = 0;
        p_g_media_type = 0;
@@ -210,11 +218,13 @@ Pgsm::~Pgsm()
        if (p_g_connect_pending)
                message_free(p_g_connect_pending);
 
+//#ifdef WITH_GSMFR
        /* close codec */
-       if (p_g_encoder)
-               gsm_audio_destroy(p_g_encoder);
-       if (p_g_decoder)
-               gsm_audio_destroy(p_g_decoder);
+       if (p_g_fr_encoder)
+               gsm_fr_destroy(p_g_fr_encoder);
+       if (p_g_fr_decoder)
+               gsm_fr_destroy(p_g_fr_decoder);
+//#endif
 }
 
 
@@ -225,32 +235,41 @@ void Pgsm::frame_receive(void *arg)
        unsigned char data[160];
        int i;
 
-       if (!p_g_decoder)
+       if (!p_g_fr_decoder)
                return;
 
-       if (frame->msg_type != GSM_BAD_FRAME) {
-               if ((frame->data[0]>>4) != 0xd)
-                       PERROR("received GSM frame with wrong magig 0x%x\n", frame->data[0]>>4);
-       
-               /* decode */
-               gsm_audio_decode(p_g_decoder, frame->data, p_g_samples);
-               for (i = 0; i < 160; i++) {
-                       data[i] = audio_s16_to_law[p_g_samples[i] & 0xffff];
+       switch (frame->msg_type) {
+       case GSM_TCHF_FRAME:
+               if ((frame->data[0]>>4) != 0xd) {
+                       PDEBUG(DEBUG_GSM, "received GSM frame with wrong magig 0x%x\n", frame->data[0]>>4);
+                       goto bfi;
                }
-       } else if (p_echotest) {
-               /* beep on bad frame */
+#ifdef WITH_GSMFR
+               /* decode */
+               gsm_fr_decode(p_g_fr_decoder, frame->data, p_g_samples);
                for (i = 0; i < 160; i++) {
-                       if ((i & 3) > 2)
-                               p_g_samples[i] = 15000;
-                       else
-                               p_g_samples[i] = -15000;
                        data[i] = audio_s16_to_law[p_g_samples[i] & 0xffff];
                }
-       } else {
-               /* repeat on bad frame */
-               for (i = 0; i < 160; i++) {
-                       p_g_samples[i] = (p_g_samples[i] * 14) >> 4;
-                       data[i] = audio_s16_to_law[p_g_samples[i] & 0xffff];
+#endif
+               break;
+       case GSM_BAD_FRAME:
+       default:
+bfi:
+               if (p_echotest) {
+                       /* beep on bad frame */
+                       for (i = 0; i < 160; i++) {
+                               if ((i & 3) > 2)
+                                       p_g_samples[i] = 15000;
+                               else
+                                       p_g_samples[i] = -15000;
+                               data[i] = audio_s16_to_law[p_g_samples[i] & 0xffff];
+                       }
+               } else {
+                       /* repeat on bad frame */
+                       for (i = 0; i < 160; i++) {
+                               p_g_samples[i] = (p_g_samples[i] * 14) >> 4;
+                               data[i] = audio_s16_to_law[p_g_samples[i] & 0xffff];
+                       }
                }
        }
 
@@ -288,7 +307,7 @@ int Pgsm::audio_send(unsigned char *data, int len)
                tap(data, len, 1); // from up
 
        /* encoder init failed */
-       if (!p_g_encoder)
+       if (!p_g_fr_encoder)
                return -EINVAL;
 
        /* (currently) not connected, so don't flood tch! */
@@ -301,9 +320,11 @@ int Pgsm::audio_send(unsigned char *data, int len)
                if (p_g_rxpos == 160) {
                        p_g_rxpos = 0;
 
+#ifdef WITH_GSMFR
                        /* encode data */
-                       gsm_audio_encode(p_g_encoder, p_g_rxdata, frame);
+                       gsm_fr_encode(p_g_fr_encoder, p_g_rxdata, frame);
                        frame_send(frame);
+#endif
                }
        }
 
diff --git a/gsm.h b/gsm.h
index c152f42..57920db 100644 (file)
--- a/gsm.h
+++ b/gsm.h
@@ -48,7 +48,9 @@ class Pgsm : public Port
        struct lcr_msg *p_g_notify_pending;     /* queue for NOTIFY if not connected */
        struct lcr_msg *p_g_setup_pending;      /* queue SETUP until RTP is created */
        struct lcr_msg *p_g_connect_pending;    /* queue CONNECT until RTP is created and connected */
-       void *p_g_encoder, *p_g_decoder;        /* gsm handle */
+       void *p_g_fr_encoder, *p_g_fr_decoder;  /* gsm handle */
+       void *p_g_hr_encoder, *p_g_hr_decoder;  /* gsm handle */
+       void *p_g_amr_encoder, *p_g_amr_decoder;/* gsm handle */
        signed short p_g_rxdata[160]; /* receive audio buffer */
        int p_g_rxpos; /* position in audio buffer 0..159 */
        int p_g_tch_connected; /* indicates if audio is connected */
index 972ab39..835ac98 100644 (file)
 \*****************************************************************************/ 
 
 extern "C" {
-#include "/usr/include/gsm/gsm.h"
+#include "libgsmfr/inc/gsm.h"
 
 
 /* create gsm instance */
-void *gsm_audio_create(void)
+void *gsm_fr_create(void)
 {
        int value = 1;
        gsm handle;
@@ -27,13 +27,13 @@ void *gsm_audio_create(void)
 }
 
 /* free gsm instance */
-void gsm_audio_destroy(void *arg)
+void gsm_fr_destroy(void *arg)
 {
        gsm_destroy((gsm)arg);
 }
 
 /* decode frame into samples, return error */
-int gsm_audio_decode(void *arg, unsigned char *frame, signed short *samples)
+int gsm_fr_decode(void *arg, unsigned char *frame, signed short *samples)
 {
 //     int value = 0;
 
@@ -42,7 +42,7 @@ int gsm_audio_decode(void *arg, unsigned char *frame, signed short *samples)
 }
 
 /* encode samples into frame */
-void gsm_audio_encode(void *arg, signed short *samples, unsigned char *frame)
+void gsm_fr_encode(void *arg, signed short *samples, unsigned char *frame)
 {
 //     int value = 0;
        
index 04a6d77..74e0dbb 100644 (file)
@@ -1,6 +1,6 @@
 
-void *gsm_audio_create(void);
-void gsm_audio_destroy(void *arg);
-int gsm_audio_decode(void *arg, unsigned char *frame, signed short *samples);
-void gsm_audio_encode(void *arg, signed short *samples, unsigned char *frame);
+void *gsm_fr_create(void);
+void gsm_fr_destroy(void *arg);
+int gsm_fr_decode(void *arg, unsigned char *frame, signed short *samples);
+void gsm_fr_encode(void *arg, signed short *samples, unsigned char *frame);
 
diff --git a/libgsmfr/COPYRIGHT b/libgsmfr/COPYRIGHT
new file mode 100644 (file)
index 0000000..28fbb3c
--- /dev/null
@@ -0,0 +1,35 @@
+Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
+Technische Universitaet Berlin
+
+Any use of this software is permitted provided that this notice is not
+removed and that neither the authors nor the Technische Universitaet Berlin
+are deemed to have made any representations as to the suitability of this
+software for any purpose nor are held responsible for any defects of
+this software.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+
+As a matter of courtesy, the authors request to be informed about uses
+this software has found, about bugs in this software, and about any
+improvements that may be of general interest.
+
+Berlin, 28.11.1994
+Jutta Degener
+Carsten Bormann
+
+                                 oOo
+
+Since the original terms of 15 years ago maybe do not make our
+intentions completely clear given today's refined usage of the legal
+terms, we append this additional permission:
+
+      Permission to use, copy, modify, and distribute this software
+      for any purpose with or without fee is hereby granted,
+      provided that this notice is not removed and that neither
+      the authors nor the Technische Universitaet Berlin are
+      deemed to have made any representations as to the suitability
+      of this software for any purpose nor are held responsible
+      for any defects of this software.  THERE IS ABSOLUTELY NO
+      WARRANTY FOR THIS SOFTWARE.
+
+Berkeley/Bremen, 05.04.2009
+Jutta Degener
+Carsten Bormann
diff --git a/libgsmfr/ChangeLog b/libgsmfr/ChangeLog
new file mode 100644 (file)
index 0000000..a3e7cb6
--- /dev/null
@@ -0,0 +1,98 @@
+Sun Apr  5  04:53:07 2009       Jutta Degener (jutta@pobox.com)
+
+       * Release 1.0 Patchlevel 13
+       COPYRIGHT: exploring the deeper meaning and cultural
+       history of the word "any".
+
+Fri Jun  2 06:27:56 2006       Jutta Degener (jutta@pobox.com)
+
+       * Release 1.0 Patchlevel 12
+       src/code.c: removed modifiable static storage that made the library
+               non-reentrant.  (Thanks to Paul Gibbs for pointing out the bug.)
+
+Sat Mar 18 11:48:28 2006       Jutta Degener (jutta@pobox.com)
+
+       * Release 1.0 Patchlevel 11
+       src/gsm_implode.c: fix WAV49 implode
+       move source archive location
+
+Fri Jul  5 19:26:37 1996       Jutta Degener (jutta@cs.tu-berlin.de)
+
+       * Release 1.0 Patchlevel 10
+       src/toast_alaw.c: exchanged A-law tables for something
+               slightly more A-law.
+
+Tue Jul  2 12:18:20 1996  Jutta Degener (jutta@cs.tu-berlin.de)
+
+       * Release 1.0 Patchlevel 9
+       src/long_term.c: in FLOAT_MUL mode, an array was accessed past its end
+       src/gsm_option.c: three options related to WAV #49 packing
+       src/gsm_encode.c: support WAV #49-style encoding.
+       src/gsm_decode.c: support WAV #49-style decoding.
+       tls/sour.c: generate the WAV bit shifting code, encode
+       tls/ginger.c: generate the WAV bit shifting code, decode
+       The WAV code goes back to an inofficial patch #8 that
+       Jeff Chilton sent us (hence the jump from 7 to 9).
+       src/toast.c: add _fsetmode() calls to set stdin/stdout to
+               binary (from an OS/2 port by Arnd Gronenberg.)
+
+Tue Mar  7 01:55:10 1995  Jutta Degener (jutta@cs.tu-berlin.de)
+
+       * Release 1.0 Patchlevel 7
+       src/long_term.c: Yet another 16-bit overflow
+       src/toast.c: -C option to toast, cuts LPC time
+       src/gsm_option.c: corresponding LPC_CUT option to GSM library
+
+Fri Dec 30 23:33:50 1994  Jutta Degener (jutta@cs.tu-berlin.de)
+
+        * Release 1.0 Patchlevel 6
+        src/lpc.c: fixed 16-bit addition overflow in Autocorrelation code
+        src/add.c: gsm_L_asl should fall back on gsm_L_asr, not gsm_asr
+
+Mon Nov 28 20:49:57 1994  Jutta Degener (jutta@cs.tu-berlin.de)
+       
+       * Release 1.0 Patchlevel 5
+       src/toast_audio.c: initialization should return -1 on error
+       src/gsm_destroy.c: #include configuration header file
+       src/add.c: gsm_sub should cast its parameters to longword
+       man/*: bug reports to {jutta,cabo}@cs.tu-berlin.de, not to toast@tub
+       inc/private.h: longword long by default, not int
+       inc/toast.h: read/write fopen modes "rb" and "wb", not just "r"
+       src/toast.c: better (or different, anyway) error handling in process()
+
+Tue May 10 19:41:34 1994  Jutta Degener (jutta at kugelbus)
+       
+       * Release 1.0 Patchlevel 4
+       inc/private.h: GSM_ADD should cast to ulongword, not to unsigned.
+       src/long_term.c: missing cast to longword.
+       add-test/add_test.c: Test macros too, not only functions,
+       thanks to Simao Ferraz de Campos Neto, simao@dragon.cpqd.ansp.br
+       General cleanup: remove unused variables, add function prototypes.
+
+Tue Jan 25 22:53:40 1994  Jutta Degener (jutta at kugelbus)
+
+       * Release 1.0 Patchlevel 3
+       changed rpe.c's STEP macro to work with 16-bit integers,
+       thanks to Dr Alex Lee (alexlee@solomon.technet.sg);
+       removed non-fatal bugs from add-test.dta, private.h
+       and toast_audio.c, thanks to P. Emanuelsson.
+
+Fri Jan 29 19:02:12 1993  Jutta Degener  (jutta at kraftbus)
+       
+       * Release 1.0 Patchlevel 2
+       fixed L_add(0,-1) in src/add.c and inc/private.h,
+       thanks to Raphael Trommer at AT&T Bell Laboratories;
+       various other ANSI C compatibility details
+
+Fri Oct 30 17:58:54 1992  Jutta Degener  (jutta at kraftbus)
+
+       * Release 1.0 Patchlevel 1
+       Switched uid/gid in toast's [f]chown calls.
+
+Wed Oct 28 14:12:35 1992  Carsten Bormann  (cabo at kubus)
+
+       * Release 1.0: released
+       Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+       Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+       details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+
diff --git a/libgsmfr/INSTALL b/libgsmfr/INSTALL
new file mode 100644 (file)
index 0000000..5850304
--- /dev/null
@@ -0,0 +1,99 @@
+How to get started:
+
+   Edit the Makefile.
+
+       You should configure a few machine-dependencies and what
+       compiler you want to use.
+
+       The code works both with ANSI and K&R-C.  Use
+       -DNeedFunctionPrototypes to compile with, or
+       -UNeedFunctionPrototypes to compile without, function
+       prototypes in the header files.
+   Make addtst
+
+       The "add" program that will be compiled and run checks whether
+       the basic math functions of the gsm library work with your
+       compiler.  If it prints anything to stderr, complain (to us).
+
+   Edit inc/config.h.
+
+   Make
+
+       Local versions of the gsm library and the "compress"-like filters
+       toast, untoast and tcat will be generated.
+
+       If the compilation aborts because of a missing function,
+       declaration, or header file, see if there's something in
+       inc/config.h to work around it.  If not, complain.
+
+   Try it
+
+       Grab an audio file from somewhere (raw u-law or Sun .au is fine, 
+       linear 16-bit in host byte order will do), copy it, toast it,
+       untoast it, and listen to the result.
+    
+       The GSM-encoded and -decoded audio should have the quality
+       of a good phone line.  If the resulting audio is noisier than
+       your original, or if you hear compression artifacts, complain;
+       that's a bug in our software, not a bug in the GSM encoding
+       standard itself.
+
+Installation
+
+   You can install the gsm library interface, or the toast binaries,
+   or both.
+
+   Edit the Makefile
+       
+       Fill in the directories where you want to install the
+       library, header files, manual pages, and binaries.
+
+       Turn off the installation of one half of the distribution
+       (i.e., gsm library or toast binaries) by not setting the
+       corresponding directory root Makefile macro.
+
+   make install
+
+       will install the programs "toast" with two links named
+       "tcat" and "untoast", and the gsm library "libgsm.a" with
+       a "gsm.h" header file, and their respective manual pages.
+
+
+Optimizing
+
+   This code was developed on a machine without an integer
+   multiplication instruction, where we obtained the fastest result by
+   replacing some of the integer multiplications with floating point
+   multiplications.
+
+   If your machine does multiply integers fast enough,
+   leave USE_FLOAT_MUL undefined.  The results should be the
+   same in both cases.
+
+   On machines with fast floating point arithmetic, defining
+   both USE_FLOAT_MUL and FAST makes a run-time library
+   option available that will (in a few crucial places) use
+   ``native'' floating point operations rather than the bit-by-bit
+   defined ones of the GSM standard.  If you use this fast
+   option, the outcome will not be bitwise identical to the
+   results prescribed by the standard, but it is compatible with
+   the standard encoding, and a user is unlikely to notice a
+   difference.
+
+
+Bug Reports
+
+   Please direct bug reports, questions, and comments to
+   jutta@cs.tu-berlin.de and cabo@informatik.uni-bremen.de.
+
+
+Good luck,
+
+   Jutta Degener,
+   Carsten Bormann
+
+--
+Copyright 1992, 1993, 1994, by Jutta Degener and Carsten Bormann,
+Technische Universitaet Berlin.  See the accompanying file "COPYRIGHT"
+for details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
diff --git a/libgsmfr/MACHINES b/libgsmfr/MACHINES
new file mode 100644 (file)
index 0000000..9f9e69b
--- /dev/null
@@ -0,0 +1,11 @@
+The gsm library has been tested successfully on the following platforms:
+
+- Various Sun4s running SunOS 4.1.2
+- SPARC1 (SunOS 4.1.1)
+- Integrated Solutions 68k Optimum running 4.3BSD UNIX with a Green Hills cc
+- NeXTstation running NeXT-OS/Mach 3.0
+- No-name AT/386 with Xenix 2.3.2 (using -DSTUPID_COMPILER)
+- RS/6000-350 running AIX 3.2.0
+- RS/6000-320 running AIX 3.1.5
+- Alliant FX80 (Concentrix 5.7)
+- SGI Indigo XS4000 (IRIX 4.0.5F)
diff --git a/libgsmfr/MANIFEST b/libgsmfr/MANIFEST
new file mode 100644 (file)
index 0000000..6db3b2a
--- /dev/null
@@ -0,0 +1,59 @@
+gsm-1.0/COPYRIGHT
+gsm-1.0/ChangeLog
+gsm-1.0/INSTALL
+gsm-1.0/MACHINES
+gsm-1.0/MANIFEST
+gsm-1.0/Makefile
+gsm-1.0/README
+gsm-1.0/add-test/add_test.c
+gsm-1.0/add-test/add_test.dta
+gsm-1.0/inc/gsm.h
+gsm-1.0/inc/proto.h
+gsm-1.0/inc/unproto.h
+gsm-1.0/inc/config.h
+gsm-1.0/inc/private.h
+gsm-1.0/inc/toast.h
+gsm-1.0/man/bitter.1
+gsm-1.0/man/gsm.3
+gsm-1.0/man/gsm_explode.3
+gsm-1.0/man/gsm_print.3
+gsm-1.0/man/gsm_option.3
+gsm-1.0/man/toast.1
+gsm-1.0/src/add.c
+gsm-1.0/src/code.c
+gsm-1.0/src/debug.c
+gsm-1.0/src/decode.c
+gsm-1.0/src/gsm_destroy.c
+gsm-1.0/src/gsm_decode.c
+gsm-1.0/src/gsm_encode.c
+gsm-1.0/src/gsm_explode.c
+gsm-1.0/src/gsm_implode.c
+gsm-1.0/src/gsm_create.c
+gsm-1.0/src/gsm_print.c
+gsm-1.0/src/gsm_option.c
+gsm-1.0/src/long_term.c
+gsm-1.0/src/lpc.c
+gsm-1.0/src/preprocess.c
+gsm-1.0/src/rpe.c
+gsm-1.0/src/short_term.c
+gsm-1.0/src/table.c
+gsm-1.0/src/toast.c
+gsm-1.0/src/toast_alaw.c
+gsm-1.0/src/toast_audio.c
+gsm-1.0/src/toast_lin.c
+gsm-1.0/src/toast_ulaw.c
+gsm-1.0/tls/bitter.c
+gsm-1.0/tls/bitter.dta
+gsm-1.0/tls/taste.c
+gsm-1.0/tls/taste.h
+gsm-1.0/tls/sweet.c
+gsm-1.0/tls/sour.c
+gsm-1.0/tls/sour1.dta
+gsm-1.0/tls/sour2.dta
+gsm-1.0/tls/ginger.c
+gsm-1.0/tst/cod2lin.c
+gsm-1.0/tst/cod2txt.c
+gsm-1.0/tst/gsm2cod.c
+gsm-1.0/tst/lin2cod.c
+gsm-1.0/tst/lin2txt.c
+gsm-1.0/tst/run
diff --git a/libgsmfr/Makefile b/libgsmfr/Makefile
new file mode 100644 (file)
index 0000000..0ddac90
--- /dev/null
@@ -0,0 +1,494 @@
+# Copyright 1992-1996 by Jutta Degener and Carsten Bormann, Technische
+# Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+# details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+
+# Machine- or installation dependent flags you should configure to port
+
+SASR   = -DSASR
+######### Define SASR if >> is a signed arithmetic shift (-1 >> 1 == -1)
+
+# MULHACK = -DUSE_FLOAT_MUL
+######### Define this if your host multiplies floats faster than integers,
+######### e.g. on a SPARCstation.
+
+# FAST = -DFAST
+######### Define together with USE_FLOAT_MUL to enable the GSM library's
+######### approximation option for incorrect, but good-enough results.
+
+# LTP_CUT      = -DLTP_CUT
+LTP_CUT        =
+######### Define to enable the GSM library's long-term correlation 
+######### approximation option---faster, but worse; works for
+######### both integer and floating point multiplications.
+######### This flag is still in the experimental stage.
+
+WAV49  = -DWAV49
+# WAV49        =
+######### Define to enable the GSM library's option to pack GSM frames 
+######### in the style used by the WAV #49 format.  If you want to write
+######### a tool that produces .WAV files which contain GSM-encoded data,
+######### define this, and read about the GSM_OPT_WAV49 option in the
+######### manual page on gsm_option(3).
+
+# Choose a compiler.  The code works both with ANSI and K&R-C.
+# Use -DNeedFunctionPrototypes to compile with, -UNeedFunctionPrototypes to
+# compile without, function prototypes in the header files.
+#
+# You can use the -DSTUPID_COMPILER to circumvent some compilers'
+# static limits regarding the number of subexpressions in a statement.
+
+# CC           = cc
+# CCFLAGS      = -c -DSTUPID_COMPILER
+
+# CC           = /usr/lang/acc
+# CCFLAGS      = -c -O
+
+CC             = gcc -ansi -pedantic
+CCFLAGS        = -c -O2 -DNeedFunctionPrototypes=1
+
+LD             = $(CC)
+
+# LD           = gcc
+# LDFLAGS      =
+
+
+# If your compiler needs additional flags/libraries, regardless of
+# the source compiled, configure them here.
+
+# CCINC        = -I/usr/gnu/lib/gcc-2.1/gcc-lib/sparc-sun-sunos4.1.2/2.1/include
+######### Includes needed by $(CC)
+
+# LDINC        = -L/usr/gnu/lib/gcc-2.1/gcc-lib/sparc-sun-sunos4.1.2/2.1
+######### Library paths needed by $(LD)
+
+# LDLIB        = -lgcc
+######### Additional libraries needed by $(LD)
+
+
+# Where do you want to install libraries, binaries, a header file
+# and the manual pages?
+#
+# Leave INSTALL_ROOT empty (or just don't execute "make install") to
+# not install gsm and toast outside of this directory.
+
+INSTALL_ROOT   =
+
+# Where do you want to install the gsm library, header file, and manpages?
+#
+# Leave GSM_INSTALL_ROOT empty to not install the GSM library outside of
+# this directory.
+
+GSM_INSTALL_ROOT = $(INSTALL_ROOT)
+GSM_INSTALL_LIB = $(GSM_INSTALL_ROOT)/lib
+GSM_INSTALL_INC = $(GSM_INSTALL_ROOT)/inc
+GSM_INSTALL_MAN = $(GSM_INSTALL_ROOT)/man/man3
+
+
+# Where do you want to install the toast binaries and their manpage?
+#
+# Leave TOAST_INSTALL_ROOT empty to not install the toast binaries outside
+# of this directory.
+
+TOAST_INSTALL_ROOT       = $(INSTALL_ROOT)
+TOAST_INSTALL_BIN = $(TOAST_INSTALL_ROOT)/bin
+TOAST_INSTALL_MAN = $(TOAST_INSTALL_ROOT)/man/man1
+
+#  Other tools
+
+SHELL          = /bin/sh
+LN             = ln
+BASENAME       = basename
+AR             = ar
+ARFLAGS                = cr
+RMFLAGS                = -f
+FIND           = find
+COMPRESS       = compress
+COMPRESSFLAGS  = 
+# RANLIB       = true
+RANLIB         = ranlib
+
+#
+#    You shouldn't have to configure below this line if you're porting.
+# 
+
+
+# Local Directories
+
+ROOT   = .
+ADDTST = $(ROOT)/add-test
+TST    = $(ROOT)/tst
+MAN    = $(ROOT)/man
+BIN    = $(ROOT)/bin
+SRC    = $(ROOT)/src
+LIB    = $(ROOT)/lib
+TLS    = $(ROOT)/tls
+INC    = $(ROOT)/inc
+
+# Flags
+
+# DEBUG        = -DNDEBUG
+######### Remove -DNDEBUG to enable assertions.
+
+CFLAGS = $(CCFLAGS) $(SASR) $(DEBUG) $(MULHACK) $(FAST) $(LTP_CUT) \
+       $(WAV49) $(CCINC) -I$(INC)
+######### It's $(CC) $(CFLAGS)
+
+LFLAGS = $(LDFLAGS) $(LDINC)
+######### It's $(LD) $(LFLAGS)
+
+
+# Targets
+
+LIBGSM = $(LIB)/libgsm.a
+
+TOAST  = $(BIN)/toast
+UNTOAST        = $(BIN)/untoast
+TCAT   = $(BIN)/tcat
+
+# Headers
+
+GSM_HEADERS =  $(INC)/gsm.h
+
+HEADERS        =       $(INC)/proto.h          \
+               $(INC)/unproto.h        \
+               $(INC)/config.h         \
+               $(INC)/private.h        \
+               $(INC)/gsm.h            \
+               $(INC)/toast.h          \
+               $(TLS)/taste.h
+
+# Sources
+
+GSM_SOURCES =  $(SRC)/add.c            \
+               $(SRC)/code.c           \
+               $(SRC)/debug.c          \
+               $(SRC)/decode.c         \
+               $(SRC)/long_term.c      \
+               $(SRC)/lpc.c            \
+               $(SRC)/preprocess.c     \
+               $(SRC)/rpe.c            \
+               $(SRC)/gsm_destroy.c    \
+               $(SRC)/gsm_decode.c     \
+               $(SRC)/gsm_encode.c     \
+               $(SRC)/gsm_explode.c    \
+               $(SRC)/gsm_implode.c    \
+               $(SRC)/gsm_create.c     \
+               $(SRC)/gsm_print.c      \
+               $(SRC)/gsm_option.c     \
+               $(SRC)/short_term.c     \
+               $(SRC)/table.c
+
+TOAST_SOURCES = $(SRC)/toast.c                 \
+               $(SRC)/toast_lin.c      \
+               $(SRC)/toast_ulaw.c     \
+               $(SRC)/toast_alaw.c     \
+               $(SRC)/toast_audio.c
+
+SOURCES        =       $(GSM_SOURCES)          \
+               $(TOAST_SOURCES)        \
+               $(ADDTST)/add_test.c    \
+               $(TLS)/sour.c           \
+               $(TLS)/ginger.c         \
+               $(TLS)/sour1.dta        \
+               $(TLS)/sour2.dta        \
+               $(TLS)/bitter.c         \
+               $(TLS)/bitter.dta       \
+               $(TLS)/taste.c          \
+               $(TLS)/sweet.c          \
+               $(TST)/cod2lin.c        \
+               $(TST)/cod2txt.c        \
+               $(TST)/gsm2cod.c        \
+               $(TST)/lin2cod.c        \
+               $(TST)/lin2txt.c
+
+# Object files
+
+GSM_OBJECTS =  $(SRC)/add.o            \
+               $(SRC)/code.o           \
+               $(SRC)/debug.o          \
+               $(SRC)/decode.o         \
+               $(SRC)/long_term.o      \
+               $(SRC)/lpc.o            \
+               $(SRC)/preprocess.o     \
+               $(SRC)/rpe.o            \
+               $(SRC)/gsm_destroy.o    \
+               $(SRC)/gsm_decode.o     \
+               $(SRC)/gsm_encode.o     \
+               $(SRC)/gsm_explode.o    \
+               $(SRC)/gsm_implode.o    \
+               $(SRC)/gsm_create.o     \
+               $(SRC)/gsm_print.o      \
+               $(SRC)/gsm_option.o     \
+               $(SRC)/short_term.o     \
+               $(SRC)/table.o
+
+TOAST_OBJECTS =        $(SRC)/toast.o          \
+               $(SRC)/toast_lin.o      \
+               $(SRC)/toast_ulaw.o     \
+               $(SRC)/toast_alaw.o     \
+               $(SRC)/toast_audio.o
+
+OBJECTS =       $(GSM_OBJECTS) $(TOAST_OBJECTS)
+
+# Manuals
+
+GSM_MANUALS =  $(MAN)/gsm.3            \
+               $(MAN)/gsm_explode.3    \
+               $(MAN)/gsm_option.3     \
+               $(MAN)/gsm_print.3
+
+TOAST_MANUALS =        $(MAN)/toast.1
+
+MANUALS        =       $(GSM_MANUALS) $(TOAST_MANUALS) $(MAN)/bitter.1
+
+# Other stuff in the distribution
+
+STUFF =        ChangeLog                       \
+               INSTALL                 \
+               MACHINES                \
+               MANIFEST                \
+               Makefile                \
+               README                  \
+               $(ADDTST)/add_test.dta  \
+               $(TLS)/bitter.dta       \
+               $(TST)/run
+
+
+# Install targets
+
+GSM_INSTALL_TARGETS =  \
+               $(GSM_INSTALL_LIB)/libgsm.a             \
+               $(GSM_INSTALL_INC)/gsm.h                \
+               $(GSM_INSTALL_MAN)/gsm.3                \
+               $(GSM_INSTALL_MAN)/gsm_explode.3        \
+               $(GSM_INSTALL_MAN)/gsm_option.3         \
+               $(GSM_INSTALL_MAN)/gsm_print.3
+
+TOAST_INSTALL_TARGETS =        \
+               $(TOAST_INSTALL_BIN)/toast              \
+               $(TOAST_INSTALL_BIN)/tcat               \
+               $(TOAST_INSTALL_BIN)/untoast            \
+               $(TOAST_INSTALL_MAN)/toast.1
+
+
+# Default rules
+
+.c.o:
+               $(CC) $(CFLAGS) $?
+               @-mv `$(BASENAME) $@` $@ > /dev/null 2>&1
+
+# Target rules
+
+all:           $(LIBGSM) $(TOAST) $(TCAT) $(UNTOAST)
+               @-echo $(ROOT): Done.
+
+tst:           $(TST)/lin2cod $(TST)/cod2lin $(TOAST) $(TST)/test-result
+               @-echo tst: Done.
+
+addtst:                $(ADDTST)/add $(ADDTST)/add_test.dta
+               $(ADDTST)/add < $(ADDTST)/add_test.dta > /dev/null
+               @-echo addtst: Done.
+
+misc:          $(TLS)/sweet $(TLS)/bitter $(TLS)/sour $(TLS)/ginger    \
+                       $(TST)/lin2txt $(TST)/cod2txt $(TST)/gsm2cod
+               @-echo misc: Done.
+
+install:       toastinstall gsminstall
+               @-echo install: Done.
+
+
+# The basic API: libgsm
+
+$(LIBGSM):     $(LIB) $(GSM_OBJECTS)
+               -rm $(RMFLAGS) $(LIBGSM)
+               $(AR) $(ARFLAGS) $(LIBGSM) $(GSM_OBJECTS)
+               $(RANLIB) $(LIBGSM)
+
+
+# Toast, Untoast and Tcat -- the compress-like frontends to gsm.
+
+$(TOAST):      $(BIN) $(TOAST_OBJECTS) $(LIBGSM)
+               $(LD) $(LFLAGS) -o $(TOAST) $(TOAST_OBJECTS) $(LIBGSM) $(LDLIB)
+
+$(UNTOAST):    $(BIN) $(TOAST)
+               -rm $(RMFLAGS) $(UNTOAST)
+               $(LN) $(TOAST) $(UNTOAST)
+
+$(TCAT):       $(BIN) $(TOAST)
+               -rm $(RMFLAGS) $(TCAT)
+               $(LN) $(TOAST) $(TCAT)
+
+
+# The local bin and lib directories
+
+$(BIN):
+               if [ ! -d $(BIN) ] ; then mkdir $(BIN) ; fi
+
+$(LIB):
+               if [ ! -d $(LIB) ] ; then mkdir $(LIB) ; fi
+
+
+# Installation
+
+gsminstall:
+               -if [ x"$(GSM_INSTALL_ROOT)" != x ] ; then      \
+                       make $(GSM_INSTALL_TARGETS) ;   \
+               fi
+
+toastinstall:
+               -if [ x"$(TOAST_INSTALL_ROOT)" != x ]; then     \
+                       make $(TOAST_INSTALL_TARGETS);  \
+               fi
+
+gsmuninstall:
+               -if [ x"$(GSM_INSTALL_ROOT)" != x ] ; then      \
+                       rm $(RMFLAGS) $(GSM_INSTALL_TARGETS) ;  \
+               fi
+
+toastuninstall:
+               -if [ x"$(TOAST_INSTALL_ROOT)" != x ] ; then    \
+                       rm $(RMFLAGS) $(TOAST_INSTALL_TARGETS); \
+               fi
+
+$(TOAST_INSTALL_BIN)/toast:    $(TOAST)
+               -rm $@
+               cp $(TOAST) $@
+               chmod 755 $@
+
+$(TOAST_INSTALL_BIN)/untoast:  $(TOAST_INSTALL_BIN)/toast
+               -rm $@
+               ln $? $@
+
+$(TOAST_INSTALL_BIN)/tcat:     $(TOAST_INSTALL_BIN)/toast
+               -rm $@
+               ln $? $@
+
+$(TOAST_INSTALL_MAN)/toast.1:  $(MAN)/toast.1
+               -rm $@
+               cp $? $@
+               chmod 444 $@
+
+$(GSM_INSTALL_MAN)/gsm.3:      $(MAN)/gsm.3
+               -rm $@
+               cp $? $@
+               chmod 444 $@
+
+$(GSM_INSTALL_MAN)/gsm_option.3:       $(MAN)/gsm_option.3
+               -rm $@
+               cp $? $@
+               chmod 444 $@
+
+$(GSM_INSTALL_MAN)/gsm_explode.3:      $(MAN)/gsm_explode.3
+               -rm $@
+               cp $? $@
+               chmod 444 $@
+
+$(GSM_INSTALL_MAN)/gsm_print.3:        $(MAN)/gsm_print.3
+               -rm $@
+               cp $? $@
+               chmod 444 $@
+
+$(GSM_INSTALL_INC)/gsm.h:      $(INC)/gsm.h
+               -rm $@
+               cp $? $@
+               chmod 444 $@
+
+$(GSM_INSTALL_LIB)/libgsm.a:   $(LIBGSM)
+               -rm $@
+               cp $? $@
+               chmod 444 $@
+
+
+# Distribution
+
+dist:          gsm-1.0.tar.Z
+               @echo dist: Done.
+
+gsm-1.0.tar.Z: $(STUFF) $(SOURCES) $(HEADERS) $(MANUALS)
+               (       cd $(ROOT)/..;                          \
+                       tar cvf - `cat $(ROOT)/gsm-1.0/MANIFEST \
+                               | sed '/^#/d'`                  \
+               ) | $(COMPRESS) $(COMPRESSFLAGS) > $(ROOT)/gsm-1.0.tar.Z
+
+# Clean
+
+uninstall:     toastuninstall gsmuninstall
+               @-echo uninstall: Done.
+
+semi-clean:
+               -rm $(RMFLAGS)  */*.o                   \
+                       $(TST)/lin2cod $(TST)/lin2txt   \
+                       $(TST)/cod2lin $(TST)/cod2txt   \
+                       $(TST)/gsm2cod                  \
+                       $(TST)/*.*.*
+               -$(FIND) . \( -name core -o -name foo \) \
+                       -print | xargs rm $(RMFLAGS)
+
+clean: semi-clean
+               -rm $(RMFLAGS) $(LIBGSM) $(ADDTST)/add          \
+                       $(TOAST) $(TCAT) $(UNTOAST)     \
+                       $(ROOT)/gsm-1.0.tar.Z
+
+
+# Two tools that helped me generate gsm_encode.c and gsm_decode.c,
+# but aren't generally needed to port this.
+
+$(TLS)/sweet:  $(TLS)/sweet.o $(TLS)/taste.o
+               $(LD) $(LFLAGS) -o $(TLS)/sweet \
+                       $(TLS)/sweet.o $(TLS)/taste.o $(LDLIB)
+
+$(TLS)/bitter: $(TLS)/bitter.o $(TLS)/taste.o
+               $(LD) $(LFLAGS) -o $(TLS)/bitter \
+                       $(TLS)/bitter.o $(TLS)/taste.o $(LDLIB)
+
+# A version of the same family that Jeff Chilton used to implement
+# the WAV #49 GSM format.
+
+$(TLS)/ginger: $(TLS)/ginger.o $(TLS)/taste.o
+               $(LD) $(LFLAGS) -o $(TLS)/ginger \
+                       $(TLS)/ginger.o $(TLS)/taste.o $(LDLIB)
+
+$(TLS)/sour:   $(TLS)/sour.o $(TLS)/taste.o
+               $(LD) $(LFLAGS) -o $(TLS)/sour \
+                       $(TLS)/sour.o $(TLS)/taste.o $(LDLIB)
+
+# Run $(ADDTST)/add < $(ADDTST)/add_test.dta to make sure the
+# basic arithmetic functions work as intended.
+
+$(ADDTST)/add: $(ADDTST)/add_test.o
+               $(LD) $(LFLAGS) -o $(ADDTST)/add $(ADDTST)/add_test.o $(LDLIB)
+
+
+# Various conversion programs between linear, text, .gsm and the code
+# format used by the tests we ran (.cod).  We paid for the test data,
+# so I guess we can't just provide them with this package.  Still,
+# if you happen to have them lying around, here's the code.
+# 
+# You can use gsm2cod | cod2txt independently to look at what's
+# coded inside the compressed frames, although this shouldn't be
+# hard to roll on your own using the gsm_print() function from
+# the API.
+
+
+$(TST)/test-result:    $(TST)/lin2cod $(TST)/cod2lin $(TOAST) $(TST)/run
+                       ( cd $(TST); ./run ) 
+
+$(TST)/lin2txt:                $(TST)/lin2txt.o $(LIBGSM)
+                       $(LD) $(LFLAGS) -o $(TST)/lin2txt \
+                               $(TST)/lin2txt.o $(LIBGSM) $(LDLIB)
+
+$(TST)/lin2cod:                $(TST)/lin2cod.o $(LIBGSM)
+                       $(LD) $(LFLAGS) -o $(TST)/lin2cod \
+                               $(TST)/lin2cod.o $(LIBGSM) $(LDLIB)
+
+$(TST)/gsm2cod:                $(TST)/gsm2cod.o $(LIBGSM)
+                       $(LD) $(LFLAGS) -o $(TST)/gsm2cod \
+                               $(TST)/gsm2cod.o $(LIBGSM) $(LDLIB)
+
+$(TST)/cod2txt:                $(TST)/cod2txt.o $(LIBGSM)
+                       $(LD) $(LFLAGS) -o $(TST)/cod2txt \
+                               $(TST)/cod2txt.o $(LIBGSM) $(LDLIB)
+
+$(TST)/cod2lin:                $(TST)/cod2lin.o $(LIBGSM)
+                       $(LD) $(LFLAGS) -o $(TST)/cod2lin \
+                               $(TST)/cod2lin.o $(LIBGSM) $(LDLIB)
diff --git a/libgsmfr/README b/libgsmfr/README
new file mode 100644 (file)
index 0000000..cb6af85
--- /dev/null
@@ -0,0 +1,37 @@
+
+GSM 06.10 13 kbit/s RPE/LTP speech compression available
+--------------------------------------------------------
+
+The Communications and Operating Systems Research Group (KBS) at the
+Technische Universitaet Berlin is currently working on a set of
+UNIX-based tools for computer-mediated telecooperation that will be
+made freely available.
+
+As part of this effort we are publishing an implementation of the
+European GSM 06.10 provisional standard for full-rate speech
+transcoding, prI-ETS 300 036, which uses RPE/LTP (residual pulse
+excitation/long term prediction) coding at 13 kbit/s.
+
+GSM 06.10 compresses frames of 160 13-bit samples (8 kHz sampling
+rate, i.e. a frame rate of 50 Hz) into 260 bits; for compatibility
+with typical UNIX applications, our implementation turns frames of 160
+16-bit linear samples into 33-byte frames (1650 Bytes/s).
+The quality of the algorithm is good enough for reliable speaker
+recognition; even music often survives transcoding in recognizable 
+form (given the bandwidth limitations of 8 kHz sampling rate).
+
+The interfaces offered are a front end modelled after compress(1), and
+a library API.  Compression and decompression run faster than realtime
+on most SPARCstations.  The implementation has been verified against the
+ETSI standard test patterns.
+
+Jutta Degener (jutta@cs.tu-berlin.de)
+Carsten Bormann (cabo@cs.tu-berlin.de)
+
+Communications and Operating Systems Research Group, TU Berlin
+Fax: +49.30.31425156, Phone: +49.30.31424315
+
+--
+Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
diff --git a/libgsmfr/add-test/add_test.c b/libgsmfr/add-test/add_test.c
new file mode 100644 (file)
index 0000000..8e832df
--- /dev/null
@@ -0,0 +1,353 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/add_test.c,v 1.2 1994/05/10 20:18:17 jutta Exp $ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gsm.h"
+
+#include "../src/add.c"
+
+int            interactive = 1;
+
+char           * opname;
+longword       L_op1, L_op2, L_expect;
+word           op1, op2, expect;
+int            do_expect;
+
+word M_gsm_add P((word op1, word op2));
+word M_gsm_sub P((word op1, word op2));
+word M_gsm_mult P((word op1, word op2));
+word M_gsm_mult_r P((word op1, word op2));
+word M_gsm_abs P((word op1));
+longword M_gsm_L_mult P((word op1, word op2));
+longword M_gsm_L_add P((longword op1, longword op2));
+
+help()
+{
+puts( "  add a b      sub a b     mult a b   div    a b" );
+puts( "L_add A B    L_sub A B   L_mult A B   mult_r a b" );
+puts( "" );
+puts( "abs   a      norm  a        >> a b      << a b" );
+puts( "                          L_>> A B    L_<< A B" );
+
+}
+
+char * strtek P2((str, sep), char * str, char * sep) {
+
+       static char     * S = (char *)0;
+       char            * c, * base;
+
+       if (str) S = str;
+
+       if (!S || !*S) return (char *)0;
+
+       /*  Skip delimiters.
+        */
+       while (*S) {
+               for (c = sep; *c && *c != *S; c++) ;
+               if (*c) *S++ = 0;
+               else break;
+       }
+
+       base = S;
+
+       /*   Skip non-delimiters.
+        */
+       for (base = S; *S; S++) {
+
+               for (c = sep; *c; c++)
+                       if (*c == *S) {
+                               *S++ = 0;
+                               return base;
+                       }
+       }
+
+       return base == S ? (char *)0 : base;
+}
+
+long value P1((s), char * s)
+{
+       switch (*s) {
+       case '-': switch (s[1]) {
+                 case '\0': return MIN_WORD;
+                 case '-':  return MIN_LONGWORD;
+                 default:   break;
+                 }
+                 break;
+
+       case '+': switch (s[1]) {
+                 case '\0': return MAX_WORD;
+                 case '+':  return MAX_LONGWORD;
+                 default:   break;
+                 }
+       default:  break;
+       }
+
+       return strtol(s, (char **)0, 0);
+}
+
+char * parse P1((buf), char * buf)
+{
+       char  * s, * a;
+       long    l;
+
+       if (a = strchr(buf, '=')) *a++ = 0;
+
+       opname = s = strtek(buf, " \t("); 
+       if (!s) return (char *)0;
+
+       op1 = op2 = L_op1 = L_op2 = 0;
+
+       if (s = strtek( (char *)0, "( \t,")) {
+               op1 = L_op1 = value(s);
+               if (s = strtek( (char *)0, ", \t)")) op2 = L_op2 = value(s);
+       }
+
+       if (a) {
+               do_expect = 1;
+               while (*a == ' ' || *a == '\t') a++;
+               expect = L_expect = value(a);
+       }
+
+       return opname;
+}
+
+void fprint_word P2((f, w), FILE * f,  word w)
+{
+       if (!w) putc('0', f);
+       else fprintf(f, "0x%4.4x (%d%s)",
+               (unsigned int)w,
+               (int)w,
+               w == MIN_WORD? "/-" : (w == MAX_WORD ? "/+" : ""));
+}
+
+void print_word P1((w), word w)
+{
+       fprint_word( stdout, w );
+}
+
+void fprint_longword P2((f, w), FILE * f, longword w)
+{
+       if (!w) putc('0', f);
+       else fprintf(f, "0x%8.8x (%ld%s)",
+               w, w, w == MIN_WORD ? "/-"
+               : (w == MAX_WORD ? "/+"
+               : (w == MIN_LONGWORD ? "/--" 
+               : (w == MAX_LONGWORD ? "/++" : ""))));
+}
+
+void print_longword P1((w),longword w)
+{
+       fprint_longword(stdout, w);
+}
+
+void do_longword P1((w), longword w)
+{
+       if (interactive) print_longword(w);
+       if (do_expect) {
+               if (w != L_expect) {
+                       if (!interactive) fprint_longword(stderr, w);
+                       fprintf(stderr, " != %s (%ld, %ld) -- expected ",
+                               opname, L_op1, L_op2 );
+                       fprint_longword(stderr, L_expect);
+                       putc( '\n', stderr );
+               }
+       } else if (interactive) putchar('\n');
+}
+
+void do_word P1((w), word w )
+{
+       if (interactive) print_word(w);
+       if (do_expect) {
+               if (w != expect) {
+                       if (!interactive) fprint_word(stderr, w);
+                       fprintf(stderr, " != %s (%ld, %ld) -- expected ",
+                               opname, L_op1, L_op2 );
+                       fprint_word(stderr, expect);
+                       putc('\n', stderr);
+               }
+       } else if (interactive) putchar('\n');
+}
+
+int main(ac, av) char ** av;
+{
+       char    buf[299];
+       char    * c;
+       FILE    * in;
+
+       if (ac > 2) {
+               fprintf(stderr, "Usage: %s [filename]\n", av[0]);
+fail:
+#ifdef EXIT_FAILURE
+               exit(EXIT_FAILURE);
+#else
+               exit(1);
+#endif
+       }
+       if (ac < 2) in = stdin;
+       else if (!(in = fopen(av[1], "r"))) {
+               perror(av[1]);
+               fprintf(stderr, "%s: cannot open file \"%s\" for reading\n",
+                       av[0], av[1]);
+               goto fail;
+       }
+
+       interactive = isatty(fileno(in));
+
+       for (;;) {
+               if (interactive) fprintf(stderr, "? ");
+
+               if (!fgets(buf, sizeof(buf), in)) exit(0);
+               if (c = strchr(buf, '\n')) *c = 0;
+
+               if (*buf == ';' || *buf == '#') continue;
+               if (*buf == '\'') {
+                       puts(buf + 1);
+                       continue;
+               }
+               if (*buf == '\"') {
+                       fprintf(stderr,  "%s\n", buf + 1);
+                       continue;
+               }
+
+               c = parse(buf);
+
+               if (!c) continue;
+               if (!strcmp(c,   "add")) {
+                       do_word(    gsm_add( op1, op2 ));
+                       continue;
+               }
+               if (!strcmp(c,   "M_add")) {
+                       do_word(    M_gsm_add( op1, op2 ));
+                       continue;
+               }
+               if (!strcmp(c, "sub")) {
+                       do_word(    gsm_sub( op1, op2 ));
+                       continue;
+               }
+               if (!strcmp(c, "M_sub")) {
+                       do_word(    M_gsm_sub( op1, op2 ));
+                       continue;
+               }
+               if (!strcmp(c, "mult")) {
+                       do_word(    gsm_mult( op1, op2 ));
+                       continue;
+               }
+               if (!strcmp(c, "M_mult")) {
+                       do_word(    M_gsm_mult( op1, op2 ));
+                       continue;
+               }
+               if (!strcmp(c, "mult_r")) {
+                       do_word(    gsm_mult_r(op1, op2));
+                       continue;
+               }
+               if (!strcmp(c, "M_mult_r")) {
+                       do_word(    M_gsm_mult_r(op1, op2));
+                       continue;
+               }
+               if (!strcmp(c, "abs" )) {
+                       do_word(    gsm_abs(op1) );
+                       continue;
+               } 
+               if (!strcmp(c, "M_abs" )) {
+                       do_word(    M_gsm_abs(op1) );
+                       continue;
+               } 
+               if (!strcmp(c, "div" )) {
+                       do_word(    gsm_div( op1, op2 ));
+                       continue;
+               }
+               if (!strcmp(c,  "norm" )) {
+                       do_word(        gsm_norm(L_op1));
+                       continue;
+               } 
+               if (!strcmp(c,  "<<" )) {
+                       do_word(    gsm_asl( op1, op2));
+                       continue;
+               } 
+               if (!strcmp(c,  ">>" )) {
+                       do_word(    gsm_asr( op1, op2 ));
+                       continue;
+               }
+               if (!strcmp(c,  "L_mult")) {
+                       do_longword( gsm_L_mult( op1, op2 ));
+                       continue;
+               }
+               if (!strcmp(c,  "M_L_mult")) {
+                       do_longword( M_gsm_L_mult( op1, op2 ));
+                       continue;
+               }
+               if (!strcmp(c,  "L_add" )) {
+                       do_longword( gsm_L_add( L_op1, L_op2 ));
+                       continue;
+               } 
+               if (!strcmp(c,  "M_L_add" )) {
+                       do_longword( M_gsm_L_add( L_op1, L_op2 ));
+                       continue;
+               } 
+               if (!strcmp(c,  "L_sub" )) {
+                       do_longword( gsm_L_sub( L_op1, L_op2 ));
+                       continue;
+               } 
+               if (!strcmp(c,  "L_<<" )) {
+                       do_longword(    gsm_L_asl( L_op1, L_op2 ));
+                       continue;
+               } 
+               if (!strcmp(c,  "L_>>")) {
+                       do_longword(    gsm_L_asr( L_op1, L_op2 ));
+                       continue;
+               }
+               help();
+       }
+}
+
+#include "private.h"
+
+/*
+ * Function stubs for macro implementations of commonly used
+ * math functions
+ */
+word M_gsm_add P2((op1, op2),word op1, word op2)
+{
+       longword ltmp;
+       return GSM_ADD(op1, op2);
+}
+
+word M_gsm_sub P2((op1, op2), word op1, word op2)
+{
+       longword ltmp;
+       return GSM_SUB(op1, op2);
+}
+
+word M_gsm_mult P2((op1, op2), word op1, word op2)
+{
+       return GSM_MULT(op1, op2);
+}
+
+word M_gsm_mult_r P2((op1, op2), word op1, word op2)
+{
+       return GSM_MULT_R(op1, op2);
+}
+
+word M_gsm_abs P1((op1), word op1)
+{
+       return GSM_ABS(op1);
+}
+
+longword M_gsm_L_mult P2((op1, op2), word op1, word op2)
+{
+       return GSM_L_MULT(op1, op2);
+}
+
+longword M_gsm_L_add P2((op1, op2), longword op1, longword op2)
+{
+       ulongword utmp;
+       return GSM_L_ADD(op1, op2);
+}
diff --git a/libgsmfr/add-test/add_test.dta b/libgsmfr/add-test/add_test.dta
new file mode 100644 (file)
index 0000000..fe7402d
--- /dev/null
@@ -0,0 +1,683 @@
+;
+; Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+; Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+; details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+;
+;
+;      Lines starting with ' (in the first col) are echoed.
+;      Lines starting with " (in the first col) are echoed to stderr.
+;      Lines starting with ; or empty lines are ignored.
+;
+;      The part after (including) a trailing '=' is what you expect;
+;      there will be output if the result is different.
+;
+;      -  and +  by itself mean MIN_WORD and MAX_WORD, respectively;
+;      -- and ++ mean MIN_LONGWORD and MAX_LONGWORD.
+;
+
+'test the basic arithmetic operations used for the rpe-ltd filtering.
+'
+'add ================
+'  basic
+
+       add  0  0       =  0
+       add  7  4       = 11
+       add  4  6       = 10
+       add  1  1       =  2
+
+'  negative operands
+
+       add  -7  4      = -3
+       add   4 -6      = -2
+       add  -1 -3      = -4
+       add   7 -4      =  3
+       add  -4  6      =  2
+
+'  positive overflow
+; (max-word = 32767)
+       add  + 1        = +
+       add  + +        = +
+       add  -1 +       = 32766
+       add  32766 2    = +
+       add  1 32766    = +
+
+'  underflow
+; (min-word = 32768)
+
+       add  - -1       = -
+       add  - -        = -
+       add  1 -        = -32767  
+       add  -32767 -2  = -
+       add  -1 -32766  = -32767
+       add  -32767 -1  = -
+       add  - +        = -1
+       add  + -        = -1
+       add  0 -        = -
+       add  0 +        = +
+'
+
+'L_add ================
+'  basic 
+
+       L_add  0  0     =  0
+       L_add  7  4     = 11
+       L_add  4  6     = 10
+       L_add  1  1     =  2
+
+'  negative operands
+
+       L_add  -7  4    = -3
+       L_add   4 -6    = -2
+       L_add  -1 -3    = -4
+       L_add   7 -4    =  3
+       L_add  -4  6    =  2
+       L_add   0 -1    = -1
+
+'  positive overflow
+; (max-longword = 2147483647)
+       L_add  ++ 1     = ++
+       L_add  ++ ++    = ++
+       L_add  -1 ++    = 2147483646
+       L_add  2147483646 2 = ++
+       L_add  1 2147483645 = 2147483646
+
+'  underflow
+; (min-longword = -2147483648)
+
+       L_add  -- -1    = --
+       L_add  -- --    = --
+       L_add  1 --     = -2147483647
+       L_add  -2147483647 -2   = --
+       L_add  -1 -2147483646   = -2147483647
+       L_add  -2147483647 -1   = --
+       L_add  -- ++    = -1
+       L_add  ++ --    = -1
+       L_add  0 --     = --
+       L_add  0 ++     = ++
+'
+
+'sub ================
+'  basic 
+
+       sub  0  0       =  0
+       sub  7  4       =  3
+       sub  4  6       = -2
+       sub  1  0       =  1
+
+'  negative operands
+
+       sub  -7  4      = -11
+       sub   4 -6      =  10
+       sub  -1 -3      =  2
+       sub   7 -4      =  11
+       sub  -4  6      = -10
+
+'  positive overflow
+; (max-word = 32767)
+       sub  1 -        = +
+       sub  + +        = 0
+       sub  + 0        = +
+       sub  + -1       = +
+       sub  + 1        = 32766
+       sub  1 +        = -32766 
+       sub  0 +        = -32767
+
+'  underflow
+; (min-word = 32768)
+
+       sub  - -1       = -32767
+       sub  - 1        = -
+       sub  - -        = 0
+       sub  - +        = -
+       sub  + -        = +
+       sub  1 -        = +
+       sub  -1 -       = +
+       sub  -32767 2   = -
+       sub  0 -        = +
+' 
+
+'L_sub ================
+'  basic 
+
+       L_sub  0  0     =  0
+       L_sub  7  4     =  3
+       L_sub  4  6     = -2
+       L_sub  1  0     =  1
+
+'  negative operands
+
+       L_sub  -7  4    = -11
+       L_sub   4 -6    =  10
+       L_sub  -1 -3    =  2
+       L_sub   7 -4    =  11
+       L_sub  -4  6    = -10
+
+'  positive overflow
+       L_sub  1 --     = ++
+       L_sub  ++ ++    = 0
+       L_sub  ++ 0     = ++
+       L_sub  ++ -1    = ++
+       L_sub  ++ 1     =  2147483646
+       L_sub  1 ++     = -2147483646
+       L_sub  0 ++     = -2147483647
+
+'  underflow
+
+       L_sub  -- -1    = -2147483647
+       L_sub  -- 1     = --
+       L_sub  -- --    = 0
+       L_sub  -- ++    = --
+       L_sub  + --     = ++
+       L_sub  1 --     = ++
+       L_sub  -1 --    = ++
+       L_sub  -2147483647 2 = --
+       L_sub  0 --     = ++
+
+'
+'abs ================
+'  basic 
+
+       abs        0    =   0
+       abs        2    =   2
+       abs     -459    = 459
+
+'  overflow
+
+       abs      +      =   +
+       abs      -      =   +
+       abs     -32767  =   +
+       abs      32766  = 32766
+       abs     -32766  = 32766
+
+'
+'mult ================
+;  actually, a * b >> 15
+
+'  basic 
+       mult    0  0            = 0
+       mult    0x100 0x100     = 2
+       mult    4711 0x4000     = 2355
+
+'  negative operands
+       mult    -1  0           =  0
+
+       mult    -0x100   0x100  = -2
+       mult     0x100  -0x100  = -2
+       mult    -0x100  -0x100  =  2
+
+       mult    -4711   0x4000  = -2356
+       mult     4711  -0x4000  = -2356
+       mult    -4711  -0x4000  =  2355
+
+'  overflow
+       mult    + +      = 32766
+       mult    + 0x4000 = 0x3fff
+       mult    0x4000 + = 0x3fff
+       mult    + 1      = 0
+       mult    + 2      = 1
+       mult    + 3      = 2
+
+'  underflow
+       mult    - -      = +
+       mult    - +      = -32767
+       mult    + -      = -32767
+       mult    - 1      = -1
+       mult    - 2      = -2
+       mult    - 3      = -3
+
+'
+'mult_r ================
+;  actually, (a * b + 16384) >> 15
+
+'  basic 
+       mult_r  0  0            = 0
+       mult_r  0x100 0x100     = 2
+       mult_r  4711 0x4000     = 2356
+
+'  negative operands
+       mult_r  -1  0           =  0
+
+       mult_r  -0x100   0x100  = -2
+       mult_r   0x100  -0x100  = -2
+       mult_r  -0x100  -0x100  =  2
+
+       mult_r  -4711   0x4000  = -2355
+       mult_r   4711  -0x4000  = -2355
+       mult_r  -4711  -0x4000  =  2356
+
+'  overflow
+       mult_r  + +      = 32766
+       mult_r  + 32766  = 32765
+       mult_r  32766 +  = 32765
+       mult_r  + 0x4000 = 0x4000
+       mult_r  0x4000 + = 0x4000
+       mult_r  + 0x4001 = 0x4000
+       mult_r  0x4001 + = 0x4000
+       mult_r  + 2      = 2
+       mult_r  + 1      = 1
+       mult_r  1 +      = 1
+       mult_r  + 0      = 0
+       mult_r  0 +      = 0
+
+'  underflow
+       mult_r  - -      = +
+       mult_r  - +      = -32767
+       mult_r  + -      = -32767
+       mult_r  - 1      = -1
+       mult_r  - 2      = -2
+       mult_r  - 3      = -3
+
+'
+'L_mult ================
+;  actually, (a * b) << 1
+;  assert (a != MIN_WORD && b != MIN_WORD)
+
+'  basic 
+       L_mult  0  0    = 0
+       L_mult  2  3    = 12
+       L_mult  4711 5  = 47110
+
+'  negative operands
+
+       L_mult  -2  3   = -12
+       L_mult   2 -3   = -12
+       L_mult  -2 -3   =  12
+       L_mult -4711  5 = -47110
+       L_mult  4711 -5 = -47110
+       L_mult -4711 -5 =  47110
+
+'  overflow
+       L_mult  + +      = 2147352578
+       L_mult  + -32767 = -2147352578
+       L_mult  -32767 + = -2147352578
+       L_mult  + 2      = 131068
+       L_mult  + 1      = 65534
+       L_mult  1 +      = 65534
+       L_mult  + 0      = 0
+       L_mult  0 +      = 0
+
+'
+'div ================
+;  actually, (32767 * a) / b
+;  assert (a > 0 && b >= a)
+
+'  basic 
+       div     1 1             = +
+       div     4711 4711       = +
+       div     5 10            = 0x4000
+       div     5 20            = 0x2000
+       div     5 40            = 0x1000
+
+'  overflow
+       div     + +             = +
+       div     0x4000 +        = 0x4000
+       div     1 +             = 1
+       div     1 2             = 0x4000
+'
+'norm ================
+
+'  positive
+       norm    1               = 30
+       norm    2               = 29
+       norm    3               = 29
+       norm    4               = 28
+       norm    5               = 28
+; etc, etc...
+       norm    0x08000000      = 3
+       norm    0x10000000      = 2
+       norm    0x20000000      = 1
+       norm    0x20000001      = 1
+       norm    0x3fffffff      = 1
+       norm    0x40000000      = 0
+       norm    0x40000001      = 0
+       norm    0x4ffffffe      = 0
+       norm    ++              = 0
+
+'  negative
+       norm    -1              = 31
+       norm    -2              = 30
+       norm    -3              = 29
+       norm    -4              = 29
+       norm    -5              = 28
+; etc, etc...
+       norm    0x4fffffff      = 0
+       norm    --              = 0
+'
+'>> ================
+
+'  basic 
+       >>      1 1             = 0
+       >>      4 2             = 1
+       >>      0x1100 5        = 0x88
+
+'  negative operand
+
+       >>      1 -1            = 2
+       >>      1 -2            = 4
+       >>      0x88 -5         = 0x1100
+
+'  overflow
+       >>      -1 4711         = -1
+       >>      1  4711         = 0
+       >>      -4711 4711      = -1
+       >>      4711 4711       = 0
+       >>      + 1             =  16383
+       >>      - 1             = -16384
+'
+'L_>> ================
+
+'  basic 
+       L_>>    1 1             = 0
+       L_>>    4 2             = 1
+       L_>>    0x1100 5        = 0x88
+
+'  negative operand
+
+       L_>>    1 -1            = 2
+       L_>>    1 -2            = 4
+       L_>>    0x88 -5         = 0x1100
+
+'  overflow
+       L_>>    -1 4711         = -1
+       L_>>    1  4711         = 0
+       L_>>    -4711 4711      = -1
+       L_>>    4711 4711       = 0
+       L_>>    ++ 1            =  1073741823
+       L_>>    -- 1            = -1073741824
+
+'
+'<< ================
+
+'  basic 
+       <<      1 1             = 2
+       <<      4 2             = 16
+       <<      0x0088 5        = 0x1100
+
+'  negative operand
+
+       <<      1 -1            = 0
+       <<      4 -2            = 1
+       <<      0x1100 -5       = 0x0088
+
+'  overflow
+       <<      -1 4711         = 0
+       <<      1  4711         = 0
+       <<      -4711 4711      = 0
+       <<      4711 4711       = 0
+       <<      4711 -4711      = 0
+       <<      -4711 -4711     = -1
+       <<      + 1             = 0xfffe
+       <<      -1 1            = 0xfffe
+       <<      - 1             = 0
+'
+'L_<< ================
+
+'  basic 
+       L_<<    1 1             = 2
+       L_<<    4 2             = 16
+       L_<<    0x0088 5        = 0x1100
+
+'  negative operand
+
+       L_<<    1 -1            = 0
+       L_<<    4 -2            = 1
+       L_<<    0x1100 -5       = 0x0088
+
+'  overflow
+       L_<<    -1 4711         = 0
+       L_<<    1  4711         = 0
+       L_<<    -4711 4711      = 0
+       L_<<    4711 4711       = 0
+       L_<<    4711 -4711      = 0
+       L_<<    -4711 -4711     = -1
+       L_<<    ++ 1            = -2
+       L_<<    -1 1            = -2
+       L_<<    -- 1            = 0
+
+'macros
+'
+'add ================
+'  basic
+
+       M_add  0  0     =  0
+       M_add  7  4     = 11
+       M_add  4  6     = 10
+       M_add  1  1     =  2
+
+'  negative operands
+
+       M_add  -7  4    = -3
+       M_add   4 -6    = -2
+       M_add  -1 -3    = -4
+       M_add   7 -4    =  3
+       M_add  -4  6    =  2
+
+'  positive overflow
+; (max-word = 32767)
+       M_add  + 1      = +
+       M_add  + +      = +
+       M_add  -1 +     = 32766
+       M_add  32766 2  = +
+       M_add  1 32766          = +
+
+'  underflow
+; (min-word = 32768)
+
+       M_add  - -1     = -
+       M_add  - -      = -
+       M_add  1 -      = -32767  
+       M_add  -32767 -2 = -
+       M_add  -1 -32766 = -32767
+       M_add  -32767 -1 = -
+       M_add  - +      = -1
+       M_add  + -      = -1
+       M_add  0 -      = -
+       M_add  0 +      = +
+'
+
+'L_add ================
+'  basic 
+
+       M_L_add  0  0   =  0
+       M_L_add  7  4   = 11
+       M_L_add  4  6   = 10
+       M_L_add  1  1   =  2
+
+'  negative operands
+
+       M_L_add  -7  4  = -3
+       M_L_add   4 -6  = -2
+       M_L_add  -1 -3  = -4
+       M_L_add   7 -4  =  3
+       M_L_add  -4  6  =  2
+       M_L_add   0 -1  = -1
+
+'  positive overflow
+; (max-longword = 2147483647)
+       M_L_add  ++ 1   = ++
+       M_L_add  ++ ++  = ++
+       M_L_add  -1 ++  = 2147483646
+       M_L_add  2147483646 2 = ++
+       M_L_add  1 2147483645 = 2147483646
+
+'  underflow
+; (min-longword = -2147483648)
+
+       M_L_add  -- -1  = --
+       M_L_add  -- --  = --
+       M_L_add  1 --   = -2147483647
+       M_L_add  -2147483647 -2 = --
+       M_L_add  -1 -2147483646         = -2147483647
+       M_L_add  -2147483647 -1 = --
+       M_L_add  -- ++  = -1
+       M_L_add  ++ --  = -1
+       M_L_add  0 --   = --
+       M_L_add  0 ++   = ++
+'
+
+'sub ================
+'  basic 
+
+       M_sub  0  0     =  0
+       M_sub  7  4     =  3
+       M_sub  4  6     = -2
+       M_sub  1  0     =  1
+
+'  negative operands
+
+       M_sub  -7  4    = -11
+       M_sub   4 -6    =  10
+       M_sub  -1 -3    =  2
+       M_sub   7 -4    =  11
+       M_sub  -4  6    = -10
+
+'  positive overflow
+; (max-word = 32767)
+       M_sub  1 -      = +
+       M_sub  + +      = 0
+       M_sub  + 0      = +
+       M_sub  + -1     = +
+       M_sub  + 1      = 32766
+       M_sub  1 +      = -32766 
+       M_sub  0 +      = -32767
+
+'  underflow
+; (min-word = 32768)
+
+       M_sub  - -1     = -32767
+       M_sub  - 1      = -
+       M_sub  - -      = 0
+       M_sub  - +      = -
+       M_sub  + -      = +
+       M_sub  1 -      = +
+       M_sub  -1 -     = +
+       M_sub  -32767 2 = -
+       M_sub  0 -      = +
+' 
+'
+'abs ================
+'  basic 
+
+       M_abs      0    =   0
+       M_abs      2    =   2
+       M_abs   -459    = 459
+
+'  overflow
+
+       M_abs    +      =   +
+       M_abs    -      =   +
+       M_abs   -32767  =   +
+       M_abs    32766  = 32766
+       M_abs   -32766  = 32766
+
+'
+'mult ================
+;  actually, a * b >> 15
+
+'  basic 
+       M_mult  0  0            = 0
+       M_mult  0x100 0x100     = 2
+       M_mult  4711 0x4000     = 2355
+
+'  negative operands
+       M_mult  -1  0           =  0
+
+       M_mult  -0x100   0x100  = -2
+       M_mult   0x100  -0x100  = -2
+       M_mult  -0x100  -0x100  =  2
+
+       M_mult  -4711   0x4000  = -2356
+       M_mult   4711  -0x4000  = -2356
+       M_mult  -4711  -0x4000  =  2355
+
+'  overflow
+       M_mult  + +      = 32766
+       M_mult  + 0x4000 = 0x3fff
+       M_mult  0x4000 + = 0x3fff
+       M_mult  + 1      = 0
+       M_mult  + 2      = 1
+       M_mult  + 3      = 2
+
+'  underflow
+;      M_mult - -      = +                     assert !(a == b && b == MIN_WORD)
+       M_mult - -32767 = +
+       M_mult -32767 - = +
+       M_mult  - +     = -32767
+       M_mult  + -     = -32767
+       M_mult  - 1     = -1
+       M_mult  - 2     = -2
+       M_mult  - 3     = -3
+
+'
+'mult_r ================
+;  actually, (a * b + 16384) >> 15
+
+'  basic 
+       M_mult_r 0  0           = 0
+       M_mult_r 0x100 0x100    = 2
+       M_mult_r 4711 0x4000    = 2356
+
+'  negative operands
+       M_mult_r -1  0          =  0
+
+       M_mult_r -0x100   0x100 = -2
+       M_mult_r  0x100  -0x100 = -2
+       M_mult_r -0x100  -0x100 =  2
+
+       M_mult_r -4711   0x4000 = -2355
+       M_mult_r  4711  -0x4000 = -2355
+       M_mult_r -4711  -0x4000 =  2356
+
+'  overflow
+       M_mult_r + +     = 32766
+       M_mult_r + 32766  = 32765
+       M_mult_r 32766 +  = 32765
+       M_mult_r + 0x4000 = 0x4000
+       M_mult_r 0x4000 + = 0x4000
+       M_mult_r + 0x4001 = 0x4000
+       M_mult_r 0x4001 + = 0x4000
+       M_mult_r + 2     = 2
+       M_mult_r + 1     = 1
+       M_mult_r 1 +     = 1
+       M_mult_r + 0     = 0
+       M_mult_r 0 +     = 0
+
+'  underflow
+;      M_mult_r - -     = +                    assert !(a == b && b == MIN_WORD)
+       M_mult_r - -32767 = +
+       M_mult_r -32767 - = +
+       M_mult_r - +     = -32767
+       M_mult_r + -     = -32767
+       M_mult_r - 1     = -1
+       M_mult_r - 2     = -2
+       M_mult_r - 3     = -3
+
+'
+'L_mult ================
+;  actually, (a * b) << 1
+;  assert (a != MIN_WORD && b != MIN_WORD)
+
+'  basic 
+       M_L_mult        0  0    = 0
+       M_L_mult        2  3    = 12
+       M_L_mult        4711 5  = 47110
+
+'  negative operands
+
+       M_L_mult        -2  3   = -12
+       M_L_mult         2 -3   = -12
+       M_L_mult        -2 -3   =  12
+       M_L_mult -4711  5       = -47110
+       M_L_mult        4711 -5 = -47110
+       M_L_mult -4711 -5       =  47110
+
+'  overflow
+       M_L_mult        + +      = 2147352578
+       M_L_mult        + -32767 = -2147352578
+       M_L_mult        -32767 + = -2147352578
+       M_L_mult        + 2      = 131068
+       M_L_mult        + 1      = 65534
+       M_L_mult        1 +      = 65534
+       M_L_mult        + 0      = 0
+       M_L_mult        0 +      = 0
+
diff --git a/libgsmfr/inc/config.h b/libgsmfr/inc/config.h
new file mode 100644 (file)
index 0000000..dfb1ead
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/config.h,v 1.5 1996/07/02 11:26:20 jutta Exp $*/
+
+#ifndef        CONFIG_H
+#define        CONFIG_H
+
+/*efine        SIGHANDLER_T    int             /* signal handlers are void     */
+/*efine HAS_SYSV_SIGNAL        1               /* sigs not blocked/reset?      */
+
+#define        HAS_STDLIB_H    1               /* /usr/include/stdlib.h        */
+#define        HAS_LIMITS_H    1               /* /usr/include/limits.h        */
+#define        HAS_FCNTL_H     1               /* /usr/include/fcntl.h         */
+#define        HAS_ERRNO_DECL  1               /* errno.h declares errno       */
+
+#define        HAS_FSTAT       1               /* fstat syscall                */
+#define        HAS_FCHMOD      1               /* fchmod syscall               */
+#define        HAS_CHMOD       1               /* chmod syscall                */
+#define        HAS_FCHOWN      1               /* fchown syscall               */
+#define        HAS_CHOWN       1               /* chown syscall                */
+/*efine        HAS__FSETMODE   1               /* _fsetmode -- set file mode   */
+
+#define        HAS_STRING_H    1               /* /usr/include/string.h        */
+/*efine        HAS_STRINGS_H   1               /* /usr/include/strings.h       */
+
+#define        HAS_UNISTD_H    1               /* /usr/include/unistd.h        */
+#define        HAS_UTIME       1               /* POSIX utime(path, times)     */
+/*efine        HAS_UTIMES      1               /* use utimes() syscall instead */
+#define        HAS_UTIME_H     1               /* UTIME header file            */
+#define        HAS_UTIMBUF     1               /* struct utimbuf               */
+/*efine        HAS_UTIMEUSEC   1               /* microseconds in utimbuf?     */
+
+#endif /* CONFIG_H */
diff --git a/libgsmfr/inc/gsm.h b/libgsmfr/inc/gsm.h
new file mode 100644 (file)
index 0000000..4714ab6
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/*$Header: /home/kbs/jutta/src/gsm/gsm-1.0/inc/RCS/gsm.h,v 1.11 1996/07/05 18:02:56 jutta Exp $*/
+
+#ifndef        GSM_H
+#define        GSM_H
+
+#ifdef __cplusplus
+#      define  NeedFunctionPrototypes  1
+#endif
+
+#if __STDC__
+#      define  NeedFunctionPrototypes  1
+#endif
+
+#ifdef _NO_PROTO
+#      undef   NeedFunctionPrototypes
+#endif
+
+#ifdef NeedFunctionPrototypes
+#   include    <stdio.h>               /* for FILE *   */
+#endif
+
+#undef GSM_P
+#if NeedFunctionPrototypes
+#      define  GSM_P( protos ) protos
+#else
+#      define  GSM_P( protos ) ( /* protos */ )
+#endif
+
+/*
+ *     Interface
+ */
+
+typedef struct gsm_state *     gsm;
+typedef short                  gsm_signal;             /* signed 16 bit */
+typedef unsigned char          gsm_byte;
+typedef gsm_byte               gsm_frame[33];          /* 33 * 8 bits   */
+
+#define        GSM_MAGIC               0xD                     /* 13 kbit/s RPE-LTP */
+
+#define        GSM_PATCHLEVEL          10
+#define        GSM_MINOR               0
+#define        GSM_MAJOR               1
+
+#define        GSM_OPT_VERBOSE         1
+#define        GSM_OPT_FAST            2
+#define        GSM_OPT_LTP_CUT         3
+#define        GSM_OPT_WAV49           4
+#define        GSM_OPT_FRAME_INDEX     5
+#define        GSM_OPT_FRAME_CHAIN     6
+
+extern gsm  gsm_create         GSM_P((void));
+extern void gsm_destroy GSM_P((gsm));  
+
+extern int  gsm_print   GSM_P((FILE *, gsm, gsm_byte  *));
+extern int  gsm_option  GSM_P((gsm, int, int *));
+
+extern void gsm_encode  GSM_P((gsm, gsm_signal *, gsm_byte  *));
+extern int  gsm_decode  GSM_P((gsm, gsm_byte   *, gsm_signal *));
+
+extern int  gsm_explode GSM_P((gsm, gsm_byte   *, gsm_signal *));
+extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte   *));
+
+#undef GSM_P
+
+#endif /* GSM_H */
diff --git a/libgsmfr/inc/gsm.h.orig b/libgsmfr/inc/gsm.h.orig
new file mode 100644 (file)
index 0000000..bfb96e9
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm.h,v 1.10 1996/07/02 10:15:22 jutta Exp $*/
+
+#ifndef        GSM_H
+#define        GSM_H
+
+#ifdef __cplusplus
+#      define  NeedFunctionPrototypes  1
+#endif
+
+#if __STDC__
+#      define  NeedFunctionPrototypes  1
+#endif
+
+#ifdef _NO_PROTO
+#      undef   NeedFunctionPrototypes
+#endif
+
+#ifdef NeedFunctionPrototypes
+#   include    <stdio.h>               /* for FILE *   */
+#endif
+
+#undef GSM_P
+#if NeedFunctionPrototypes
+#      define  GSM_P( protos ) protos
+#else
+#      define  GSM_P( protos ) ( /* protos */ )
+#endif
+
+/*
+ *     Interface
+ */
+
+typedef struct gsm_state *     gsm;
+typedef short                  gsm_signal;             /* signed 16 bit */
+typedef unsigned char          gsm_byte;
+typedef gsm_byte               gsm_frame[33];          /* 33 * 8 bits   */
+
+#define        GSM_MAGIC               0xD                     /* 13 kbit/s RPE-LTP */
+
+#define        GSM_PATCHLEVEL          9
+#define        GSM_MINOR               0
+#define        GSM_MAJOR               1
+
+#define        GSM_OPT_VERBOSE         1
+#define        GSM_OPT_FAST            2
+#define        GSM_OPT_LTP_CUT         3
+#define        GSM_OPT_WAV49           4
+#define        GSM_OPT_FRAME_INDEX     5
+#define        GSM_OPT_FRAME_CHAIN     6
+
+extern gsm  gsm_create         GSM_P((void));
+extern void gsm_destroy GSM_P((gsm));  
+
+extern int  gsm_print   GSM_P((FILE *, gsm, gsm_byte  *));
+extern int  gsm_option  GSM_P((gsm, int, int *));
+
+extern void gsm_encode  GSM_P((gsm, gsm_signal *, gsm_byte  *));
+extern int  gsm_decode  GSM_P((gsm, gsm_byte   *, gsm_signal *));
+
+extern int  gsm_explode GSM_P((gsm, gsm_byte   *, gsm_signal *));
+extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte   *));
+
+#undef GSM_P
+
+#endif /* GSM_H */
diff --git a/libgsmfr/inc/private.h b/libgsmfr/inc/private.h
new file mode 100644 (file)
index 0000000..0c94255
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/private.h,v 1.6 1996/07/02 10:15:26 jutta Exp $*/
+
+#ifndef        PRIVATE_H
+#define        PRIVATE_H
+
+typedef short                  word;           /* 16 bit signed int    */
+typedef long                   longword;       /* 32 bit signed int    */
+
+typedef unsigned short         uword;          /* unsigned word        */
+typedef unsigned long          ulongword;      /* unsigned longword    */
+
+struct gsm_state {
+
+       word            dp0[ 280 ];
+       word            e[ 50 ];        /* code.c                       */
+
+       word            z1;             /* preprocessing.c, Offset_com. */
+       longword        L_z2;           /*                  Offset_com. */
+       int             mp;             /*                  Preemphasis */
+
+       word            u[8];           /* short_term_aly_filter.c      */
+       word            LARpp[2][8];    /*                              */
+       word            j;              /*                              */
+
+       word            ltp_cut;        /* long_term.c, LTP crosscorr.  */
+       word            nrp; /* 40 */   /* long_term.c, synthesis       */
+       word            v[9];           /* short_term.c, synthesis      */
+       word            msr;            /* decoder.c,   Postprocessing  */
+
+       char            verbose;        /* only used if !NDEBUG         */
+       char            fast;           /* only used if FAST            */
+
+       char            wav_fmt;        /* only used if WAV49 defined   */
+       unsigned char   frame_index;    /*            odd/even chaining */
+       unsigned char   frame_chain;    /*   half-byte to carry forward */
+};
+
+
+#define        MIN_WORD        (-32767 - 1)
+#define        MAX_WORD          32767
+
+#define        MIN_LONGWORD    (-2147483647 - 1)
+#define        MAX_LONGWORD      2147483647
+
+#ifdef SASR            /* flag: >> is a signed arithmetic shift right */
+#undef SASR
+#define        SASR(x, by)     ((x) >> (by))
+#else
+#define        SASR(x, by)     ((x) >= 0 ? (x) >> (by) : (~(-((x) + 1) >> (by))))
+#endif /* SASR */
+
+#include "proto.h"
+
+/*
+ *     Prototypes from add.c
+ */
+extern word    gsm_mult        P((word a, word b));
+extern longword gsm_L_mult     P((word a, word b));
+extern word    gsm_mult_r      P((word a, word b));
+
+extern word    gsm_div         P((word num, word denum));
+
+extern word    gsm_add         P(( word a, word b ));
+extern longword gsm_L_add      P(( longword a, longword b ));
+
+extern word    gsm_sub         P((word a, word b));
+extern longword gsm_L_sub      P((longword a, longword b));
+
+extern word    gsm_abs         P((word a));
+
+extern word    gsm_norm        P(( longword a ));
+
+extern longword gsm_L_asl      P((longword a, int n));
+extern word    gsm_asl         P((word a, int n));
+
+extern longword gsm_L_asr      P((longword a, int n));
+extern word    gsm_asr         P((word a, int n));
+
+/*
+ *  Inlined functions from add.h 
+ */
+
+/* 
+ * #define GSM_MULT_R(a, b) (* word a, word b, !(a == b == MIN_WORD) *)        \
+ *     (0x0FFFF & SASR(((longword)(a) * (longword)(b) + 16384), 15))
+ */
+#define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */   \
+       (SASR( ((longword)(a) * (longword)(b) + 16384), 15 ))
+
+# define GSM_MULT(a,b)  /* word a, word b, !(a == b == MIN_WORD) */    \
+       (SASR( ((longword)(a) * (longword)(b)), 15 ))
+
+# define GSM_L_MULT(a, b) /* word a, word b */ \
+       (((longword)(a) * (longword)(b)) << 1)
+
+# define GSM_L_ADD(a, b)       \
+       ( (a) <  0 ? ( (b) >= 0 ? (a) + (b)     \
+                : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \
+                  >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 )   \
+       : ((b) <= 0 ? (a) + (b)   \
+                 : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \
+                   ? MAX_LONGWORD : utmp))
+
+/*
+ * # define GSM_ADD(a, b)      \
+ *     ((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \
+ *     ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp)
+ */
+/* Nonportable, but faster: */
+
+#define        GSM_ADD(a, b)   \
+       ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \
+               MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp)
+
+# define GSM_SUB(a, b) \
+       ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \
+       ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp)
+
+# define GSM_ABS(a)    ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a))
+
+/* Use these if necessary:
+
+# define GSM_MULT_R(a, b)      gsm_mult_r(a, b)
+# define GSM_MULT(a, b)                gsm_mult(a, b)
+# define GSM_L_MULT(a, b)      gsm_L_mult(a, b)
+
+# define GSM_L_ADD(a, b)       gsm_L_add(a, b)
+# define GSM_ADD(a, b)         gsm_add(a, b)
+# define GSM_SUB(a, b)         gsm_sub(a, b)
+
+# define GSM_ABS(a)            gsm_abs(a)
+
+*/
+
+/*
+ *  More prototypes from implementations..
+ */
+extern void Gsm_Coder P((
+               struct gsm_state        * S,
+               word    * s,    /* [0..159] samples             IN      */
+               word    * LARc, /* [0..7] LAR coefficients      OUT     */
+               word    * Nc,   /* [0..3] LTP lag               OUT     */
+               word    * bc,   /* [0..3] coded LTP gain        OUT     */
+               word    * Mc,   /* [0..3] RPE grid selection    OUT     */
+               word    * xmaxc,/* [0..3] Coded maximum amplitude OUT   */
+               word    * xMc   /* [13*4] normalized RPE samples OUT    */));
+
+extern void Gsm_Long_Term_Predictor P((                /* 4x for 160 samples */
+               struct gsm_state * S,
+               word    * d,    /* [0..39]   residual signal    IN      */
+               word    * dp,   /* [-120..-1] d'                IN      */
+               word    * e,    /* [0..40]                      OUT     */
+               word    * dpp,  /* [0..40]                      OUT     */
+               word    * Nc,   /* correlation lag              OUT     */
+               word    * bc    /* gain factor                  OUT     */));
+
+extern void Gsm_LPC_Analysis P((
+               struct gsm_state * S,
+               word * s,        /* 0..159 signals      IN/OUT  */
+               word * LARc));   /* 0..7   LARc's       OUT     */
+
+extern void Gsm_Preprocess P((
+               struct gsm_state * S,
+               word * s, word * so));
+
+extern void Gsm_Encoding P((
+               struct gsm_state * S,
+               word    * e,    
+               word    * ep,   
+               word    * xmaxc,
+               word    * Mc,   
+               word    * xMc));
+
+extern void Gsm_Short_Term_Analysis_Filter P((
+               struct gsm_state * S,
+               word    * LARc, /* coded log area ratio [0..7]  IN      */
+               word    * d     /* st res. signal [0..159]      IN/OUT  */));
+
+extern void Gsm_Decoder P((
+               struct gsm_state * S,
+               word    * LARcr,        /* [0..7]               IN      */
+               word    * Ncr,          /* [0..3]               IN      */
+               word    * bcr,          /* [0..3]               IN      */
+               word    * Mcr,          /* [0..3]               IN      */
+               word    * xmaxcr,       /* [0..3]               IN      */
+               word    * xMcr,         /* [0..13*4]            IN      */
+               word    * s));          /* [0..159]             OUT     */
+
+extern void Gsm_Decoding P((
+               struct gsm_state * S,
+               word    xmaxcr,
+               word    Mcr,
+               word    * xMcr,         /* [0..12]              IN      */
+               word    * erp));        /* [0..39]              OUT     */
+
+extern void Gsm_Long_Term_Synthesis_Filtering P((
+               struct gsm_state* S,
+               word    Ncr,
+               word    bcr,
+               word    * erp,          /* [0..39]                IN    */
+               word    * drp));        /* [-120..-1] IN, [0..40] OUT   */
+
+void Gsm_RPE_Decoding P((
+       struct gsm_state *S,
+               word xmaxcr,
+               word Mcr,
+               word * xMcr,  /* [0..12], 3 bits             IN      */
+               word * erp)); /* [0..39]                     OUT     */
+
+void Gsm_RPE_Encoding P((
+               struct gsm_state * S,
+               word    * e,            /* -5..-1][0..39][40..44     IN/OUT  */
+               word    * xmaxc,        /*                              OUT */
+               word    * Mc,           /*                              OUT */
+               word    * xMc));        /* [0..12]                      OUT */
+
+extern void Gsm_Short_Term_Synthesis_Filter P((
+               struct gsm_state * S,
+               word    * LARcr,        /* log area ratios [0..7]  IN   */
+               word    * drp,          /* received d [0...39]     IN   */
+               word    * s));          /* signal   s [0..159]    OUT   */
+
+extern void Gsm_Update_of_reconstructed_short_time_residual_signal P((
+               word    * dpp,          /* [0...39]     IN      */
+               word    * ep,           /* [0...39]     IN      */
+               word    * dp));         /* [-120...-1]  IN/OUT  */
+
+/*
+ *  Tables from table.c
+ */
+#ifndef        GSM_TABLE_C
+
+extern word gsm_A[8], gsm_B[8], gsm_MIC[8], gsm_MAC[8];
+extern word gsm_INVA[8];
+extern word gsm_DLB[4], gsm_QLB[4];
+extern word gsm_H[11];
+extern word gsm_NRFAC[8];
+extern word gsm_FAC[8];
+
+#endif /* GSM_TABLE_C */
+
+/*
+ *  Debugging
+ */
+#ifdef NDEBUG
+
+#      define  gsm_debug_words(a, b, c, d)             /* nil */
+#      define  gsm_debug_longwords(a, b, c, d)         /* nil */
+#      define  gsm_debug_word(a, b)                    /* nil */
+#      define  gsm_debug_longword(a, b)                /* nil */
+
+#else  /* !NDEBUG => DEBUG */
+
+       extern void  gsm_debug_words     P((char * name, int, int, word *));
+       extern void  gsm_debug_longwords P((char * name, int, int, longword *));
+       extern void  gsm_debug_longword  P((char * name, longword));
+       extern void  gsm_debug_word      P((char * name, word));
+
+#endif /* !NDEBUG */
+
+#include "unproto.h"
+
+#endif /* PRIVATE_H */
diff --git a/libgsmfr/inc/proto.h b/libgsmfr/inc/proto.h
new file mode 100644 (file)
index 0000000..2851c08
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/proto.h,v 1.1 1992/10/28 00:11:08 jutta Exp $*/
+
+#ifndef        PROTO_H
+#define        PROTO_H
+
+#if __cplusplus
+#      define  NeedFunctionPrototypes  1
+#endif
+
+#if __STDC__
+#      define  NeedFunctionPrototypes  1
+#endif
+
+#ifdef _NO_PROTO
+#      undef   NeedFunctionPrototypes
+#endif
+
+#undef P       /* gnu stdio.h actually defines this...         */
+#undef P0
+#undef P1
+#undef P2
+#undef P3
+#undef P4
+#undef P5
+#undef P6
+#undef P7
+#undef P8
+
+#if NeedFunctionPrototypes
+
+#      define  P( protos )     protos
+
+#      define  P0()                            (void)
+#      define  P1(x, a)                        (a)
+#      define  P2(x, a, b)                     (a, b)
+#      define  P3(x, a, b, c)                  (a, b, c)
+#      define  P4(x, a, b, c, d)               (a, b, c, d)    
+#      define  P5(x, a, b, c, d, e)            (a, b, c, d, e)
+#      define  P6(x, a, b, c, d, e, f)         (a, b, c, d, e, f)
+#      define  P7(x, a, b, c, d, e, f, g)      (a, b, c, d, e, f, g)
+#      define  P8(x, a, b, c, d, e, f, g, h)   (a, b, c, d, e, f, g, h)
+
+#else /* !NeedFunctionPrototypes */
+
+#      define  P( protos )     ( /* protos */ )
+
+#      define  P0()                            ()
+#      define  P1(x, a)                        x a;
+#      define  P2(x, a, b)                     x a; b;
+#      define  P3(x, a, b, c)                  x a; b; c;
+#      define  P4(x, a, b, c, d)               x a; b; c; d;
+#      define  P5(x, a, b, c, d, e)            x a; b; c; d; e;
+#      define  P6(x, a, b, c, d, e, f)         x a; b; c; d; e; f;
+#      define  P7(x, a, b, c, d, e, f, g)      x a; b; c; d; e; f; g;
+#      define  P8(x, a, b, c, d, e, f, g, h)   x a; b; c; d; e; f; g; h;
+
+#endif  /* !NeedFunctionPrototypes */
+
+#endif /* PROTO_H */
diff --git a/libgsmfr/inc/toast.h b/libgsmfr/inc/toast.h
new file mode 100644 (file)
index 0000000..b42d9ae
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/toast.h,v 1.4 1995/03/07 21:26:16 jutta Exp $ */
+
+#ifndef        TOAST_H
+#define        TOAST_H                         /* Guard against multiple includes */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+
+#include <errno.h>
+#ifndef        HAS_ERRNO_DECL
+        extern int     errno;
+#endif
+
+#ifdef HAS_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifdef HAS_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#ifdef HAS_UTIME
+# ifdef        HAS_UTIME_H
+#  include <utime.h>
+# endif
+#endif
+
+#include "gsm.h"
+
+#ifndef        S_ISREG
+#define        S_ISREG(x)      ((x) & S_IFREG)
+#endif /* S_ISREG */
+
+
+# define       READ    "rb"
+# define       WRITE   "wb"
+#ifdef  O_BINARY
+# define       O_WRITE_EXCL    O_WRONLY|O_CREAT|O_EXCL|O_BINARY
+#else
+# define       O_WRITE_EXCL    O_WRONLY|O_CREAT|O_EXCL
+#endif
+
+#ifndef SIGHANDLER_T
+#define SIGHANDLER_T   void    /* what does a signal handler return? */
+#endif
+
+
+#ifdef HAS_STRING_H
+#include       <string.h>
+#else
+#      ifdef HAS_STRINGS_H
+#      include <strings.h>
+#      else
+#              include "proto.h"
+
+               extern int      strlen  P((char *));
+               extern char *   strcpy  P((char *, char *));
+               extern char *   strcat  P((char *,  char *));
+               extern char *   strrchr P((char *, int));
+
+#              include "unproto.h"
+#      endif
+#endif
+
+
+#ifdef HAS_STDLIB_H
+#include       <stdlib.h>
+#else
+#      include "proto.h"
+#      ifdef   HAS_MALLOC_H
+#      include <malloc.h>
+#      else
+               extern char     * malloc P((unsigned));
+#      endif
+       extern int      exit P((int));
+#      include "unproto.h"
+#endif
+
+
+#ifdef HAS_UNISTD_H
+#      include <unistd.h>
+#endif
+
+/*
+ *     This suffix is tacked onto/removed from filenames
+ *     similar to the way freeze and compress do it.
+ */
+#define        SUFFIX_TOASTED          ".gsm"
+
+#include       "proto.h"
+
+extern int     audio_init_input P((void)), audio_init_output P((void));
+extern int     ulaw_input   P((gsm_signal*)), ulaw_output   P((gsm_signal *));
+extern int     alaw_input   P((gsm_signal*)), alaw_output   P((gsm_signal *));
+extern int     linear_input P((gsm_signal*)), linear_output P((gsm_signal *));
+
+#endif         /* TOAST_H */
diff --git a/libgsmfr/inc/unproto.h b/libgsmfr/inc/unproto.h
new file mode 100644 (file)
index 0000000..eaf866f
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/unproto.h,v 1.1 1992/10/28 00:11:08 jutta Exp $*/
+
+#ifdef PROTO_H         /* sic */
+#undef PROTO_H
+
+#undef P
+#undef P0
+#undef P1
+#undef P2
+#undef P3
+#undef P4
+#undef P5
+#undef P6
+#undef P7
+#undef P8
+
+#endif /* PROTO_H */
diff --git a/libgsmfr/man/bitter.1 b/libgsmfr/man/bitter.1
new file mode 100644 (file)
index 0000000..2dad78b
--- /dev/null
@@ -0,0 +1,70 @@
+.\"
+.\" Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+.\" Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+.\" details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+.\"
+.PU
+.TH BITTER 1 
+.SH NAME
+bitter, sweet \(em code-generators for packing bits
+.SH SYNOPSIS
+bitter < input > output
+.br
+sweet < input > output
+.SH "DESCRIPTION"
+Bitter and sweet are two filters which turn a description of the
+form 
+.nf
+       name    number-of-bits
+       name    number-of-bits
+       ...
+.nf
+into code.
+.PP
+Bitter generates code that packs the specified bits from their
+variables into an array of unsigned char referenced by an
+advancing pointer c.
+.PP
+Sweet generates code that unpacks the specified bits from an array
+of unsigned char referenced by a mutable pointer c into the
+named variables.
+.\" .SH OPTIONS
+.\" .SH "RETURN VALUE"
+.\" .SH ERRORS
+.SH EXAMPLES
+.nf
+% cat in
+amaretto 1
+banana 2
+cherry 3
+strawberry 4
+vanilla 15
+walnut 15
+
+% bitter < in
+       *c++ =   ((amaretto & 0x1) << 7)
+              | ((banana & 0x3) << 5)
+              | ((cherry & 0x7) << 2)
+              | ((strawberry >> 2) & 0x3);
+       *c++ =   ((strawberry & 0x3) << 6)
+              | ((vanilla >> 9) & 0x3F);
+       *c++ =   ((vanilla >> 1) & 0xFF);
+       *c++ =   ((vanilla & 0x1) << 7)
+              | ((walnut >> 8) & 0x7F);
+       *c++ =   walnut & 0xFF;
+
+% sweet < in
+       amaretto  = (*c >> 7) & 0x1;
+       banana  = (*c >> 5) & 0x3;
+       cherry  = (*c >> 2) & 0x7;
+       strawberry  = (*c++ & 0x3) << 2;
+       strawberry |= (*c >> 6) & 0x3;
+       vanilla  = (*c++ & 0x3F) << 9;
+       vanilla |= (*c++ & 0xFF) << 1;
+       vanilla |= (*c >> 7) & 0x1;
+       walnut  = (*c++ & 0x7F) << 8;
+       walnut |= *c++;
+.SH NOTES
+This is a quick hack for the gsm_encode() and gsm_decode() routines.
+.SH BUGS
+Please direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de.
diff --git a/libgsmfr/man/gsm.3 b/libgsmfr/man/gsm.3
new file mode 100644 (file)
index 0000000..e465762
--- /dev/null
@@ -0,0 +1,105 @@
+.\"
+.\" Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+.\" Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+.\" details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+.\"
+.PU
+.TH GSM 3 
+.SH NAME
+gsm_create, gsm_destroy, gsm_encode, gsm_decode \(em GSM\ 06.10 lossy sound compression
+.SH SYNOPSIS
+.PP
+#include "gsm.h"
+.PP
+gsm gsm_create();
+.PP
+void gsm_encode(handle, src, dst)
+.br
+gsm handle;
+.br
+gsm_signal src[160];
+.br
+gsm_frame dst;
+.PP
+int gsm_decode(handle, src, dst)
+.br
+gsm handle;
+.br
+gsm_frame src;
+.br
+gsm_signal dst[160];
+.PP
+void gsm_destroy(handle)
+.br
+gsm handle;
+.br
+.SH "DESCRIPTION"
+Gsm is an implementation of the final draft GSM 06.10
+standard for full-rate speech transcoding.
+.PP
+gsm_create() initializes a gsm pass and returns a 'gsm' object
+which can be used as a handle in subsequent calls to gsm_decode(),
+gsm_encode() or gsm_destroy().
+.PP
+gsm_encode() encodes an array of 160 13-bit samples (given as
+gsm_signal's, signed integral values of at least 16 bits) into
+a gsm_frame of 33 bytes.
+(gsm_frame is a type defined as an array of 33 gsm_bytes in gsm.h.)
+.PP
+gsm_decode() decodes a gsm_frame into an array of 160 13-bit samples
+(given as gsm_signals), which sound rather like what you handed to
+gsm_encode() on the other side of the wire.
+.PP
+gsm_destroy() finishes a gsm pass and frees all storage associated
+with it.
+.SS "Sample format"
+The following scaling is assumed for input to the algorithm:
+.br
+.nf
+   0  1                             11 12
+   S..v..v..v..v..v..v..v..v..v..v..v..v..*..*..*
+.nf
+.br
+Only the top 13 bits are used as a signed input value.
+The output of gsm_decode() has the three lower bits set to zero.
+.\" .SH OPTIONS
+.SH "RETURN VALUE"
+gsm_create() returns an opaque handle object of type gsm, or 0 on error.
+gsm_decode() returns -1 if the passed frame is invalid, else 0.
+.SH EXAMPLE
+.nf
+#include "gsm.h"
+
+gsm handle;
+gsm_frame buf;
+gsm_signal sample[160];
+int cc, soundfd;
+
+play() {       /* read compressed data from standard input, write to soundfd */
+
+       if (!(handle = gsm_create())) error...
+       while (cc = read(0, (char *)buf, sizeof buf)) {
+               if (cc != sizeof buf) error...
+               if (gsm_decode(handle, buf, sample) < 0) error... 
+               if (write(soundfd, sample, sizeof sample) != sizeof sample)
+                       error...
+       }
+       gsm_destroy(handle);
+}
+
+record() {     /* read from soundfd, write compressed to standard output */
+
+       if (!(handle = gsm_create())) error...
+       while (cc = read(soundfd, sample, sizeof sample)) {
+               if (cc != sizeof sample) error...
+               gsm_encode(handle, sample, buf);
+               if (write(1, (char *)buf, sizeof buf) != sizeof sample) 
+                       error...
+       }
+       gsm_destroy(handle);
+}
+.nf
+.SH BUGS
+Please direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de.
+.SH "SEE ALSO"
+toast(1), gsm_print(3), gsm_explode(3), gsm_option(3)
diff --git a/libgsmfr/man/gsm_explode.3 b/libgsmfr/man/gsm_explode.3
new file mode 100644 (file)
index 0000000..ef89984
--- /dev/null
@@ -0,0 +1,47 @@
+.\"
+.\" Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+.\" Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+.\" details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+.\"
+.PU
+.TH GSM_EXPLODE 3 
+.SH NAME
+gsm_explode, gsm_implode \(em GSM\ 06.10 supplementary
+functions for testing
+.SH SYNOPSIS
+#include "gsm.h"
+.PP
+void gsm_explode(g, frame, xframe)
+.br
+gsm        g;
+.br
+gsm_frame  frame;
+.br
+gsm_signal xframe[ 76 ];
+.PP
+void gsm_implode(g, xframe, frame)
+.br
+gsm        g;
+.br
+gsm_signal xframe[ 76 ];
+.br
+gsm_frame  frame;
+.SH "DESCRIPTION"
+Gsm is an implementation of the final draft GSM 06.10
+standard for full-rate speech transcoding.
+Test data for implementations of this particular document
+can be bought and used to verify an implementation.
+.PP
+The encoded test data uses a format different from what
+one would use to transmit frames with the least number
+of bits.
+Gsm_explode() and gsm_implode() convert between the
+internal, small, 33-byte format and the 76-word format
+used by the test data.
+.PP
+.SH "RETURN VALUE"
+gsm_explode() returns -1 if the passed frame is invalid, else 0.
+.SH BUGS
+Please direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de.
+.SH "SEE ALSO"
+gsm(3)
diff --git a/libgsmfr/man/gsm_option.3 b/libgsmfr/man/gsm_option.3
new file mode 100644 (file)
index 0000000..8df7da0
--- /dev/null
@@ -0,0 +1,183 @@
+.\"
+.\" Copyright 1992-1995 by Jutta Degener and Carsten Bormann, Technische
+.\" Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+.\" details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+.\"
+.PU
+.TH GSM_OPTION 3 
+.SH NAME
+gsm_option \(em customizing the GSM 06.10 implementation
+.SH SYNOPSIS
+#include "gsm.h"
+.PP
+int gsm_option(handle, option, valueP);
+.br
+gsm handle;
+.br
+int option;
+.br
+int * valueP;
+.SH "DESCRIPTION"
+The gsm library is an implementation of the final draft GSM 06.10
+standard for full-rate speech transcoding, a lossy
+speech compression algorithm.
+.PP
+The gsm_option() function can be used to set and query various
+options or flags that are not needed for regular GSM 06.10 encoding
+or decoding, but might be of interest in special cases.
+.PP
+The second argument to gsm_option specifies what parameter
+should be changed or queried.
+The third argument is either a null pointer, in which case
+the current value of that parameter is returned;
+or it is a pointer to an integer containing the value
+you want to set, in which case the previous value will
+be returned.
+.PP
+The following options are defined:
+.PP
+.I GSM_OPT_VERBOSE
+Verbosity level.
+.br
+.in+5
+This option is only supported if the library was compiled
+with debugging turned on, and may be used by developers of
+compression algorithms to aid debugging.
+.br
+The verbosity level can be changed at any time during encoding or decoding.
+.in-5
+.sp
+.PP
+.I GSM_OPT_FAST
+Faster compression algorithm.
+.br
+.in+5
+This implementation offers a not strictly standard-compliant, but
+faster compression algorithm that is compatible with the regular
+method and does not noticably degrade audio quality.
+.br
+The value passed to 
+.br
+.nf
+       gsm_option(handle, GSM_OPT_FAST, & value)
+.fi
+.br 
+functions as a boolean flag; if it is zero, the regular algorithm
+will be used, if not, the faster version will be used.
+.br
+The availability of this option depends on the hardware used;
+if it is not available, gsm_option will return -1 on an attempt
+to set or query it.
+.br
+This option can be set any time during encoding or decoding.
+.in-5
+.ne 5
+.sp
+.PP
+.I GSM_OPT_LTP_CUT
+Enable, disable, or query the LTP cut-off optimization.
+.br
+.in+5
+During encoding, the search for the long-term correlation
+lag forms the bottleneck of the algorithm. 
+The ltp-cut option enables an approximation that disregards most
+of the samples for purposes of finding that correlation,
+and hence speeds up the encoding at a noticable loss in quality.
+.br
+The value passed to 
+.br
+.nf
+       gsm_option(handle, GSM_OPT_LTP_CUT, & value)
+.fi
+.br 
+turns the optimization on if nonzero, and off if zero.
+.br
+This option can be set any time during encoding
+or decoding; it will only affect the encoding pass, not
+the decoding.
+.sp
+.PP
+.I GSM_OPT_WAV49
+WAV-style byte ordering.
+.br
+.in+5
+A WAV file of type #49 contains GSM 06.10-encoded frames.
+Unfortunately, the framing and code ordering of the WAV version
+are incompatible with the native ones of this GSM 06.10 library.
+The GSM_OPT_WAV49 option turns on a different packing
+algorithm that produces alternating frames of 32 and 33 bytes
+(or makes it consume alternating frames of 33 and 32 bytes, note
+the opposite order of the two numbers) which, when concatenated,
+can be used in the body of a WAV #49 frame.
+It is up to the user program to write a WAV header, if any;
+neither the library itself nor the toast program produce
+complete WAV files.
+.br
+The value passed to 
+.br
+.nf
+       gsm_option(handle, GSM_OPT_WAV49, & value)
+.fi
+.br 
+functions as a boolean flag; if it is zero, the library's native
+framing algorithm will be used, if nonzero, WAV-type packing is in effect.
+.br
+This option should be used before any frames are encoded.
+Whether or not it is supported at all depends on a
+compile-time switch, WAV49.
+Both option and compile time switch are new to the library
+as of patchlevel 9, and are considerably less tested than the
+well-worn rest of the it.
+.br
+Thanks to Jeff Chilton for the detective work and first free
+implementation of this version of the GSM 06.10 encoding.
+.sp
+.PP
+.I GSM_OPT_FRAME_CHAIN
+Query or set the chaining byte.
+.br
+.in+5
+Between the two frames of a WAV-style encoding, the GSM 06.10 library
+must keep track of one half-byte that is technically part of the first
+frame, but will be written as the first four bits of the second.
+This half-byte are the lowest four bits of the value returned by,
+and optionally set by,
+.br
+.nf
+       gsm_option(handle, GSM_OPT_FRAME_CHAIN, & value)
+.fi
+.br 
+This option can be queried and set at any time.
+.sp
+.PP
+.I GSM_OPT_FRAME_INDEX
+Query or set the current frame's index in a format's
+alternating list of frames.
+.br
+.in+5
+The WAV #49 framing uses two alternating types of frames.
+Which type the next GSM-coded frame belongs to can be queried, or,
+when decoding, announced, using
+.br
+.nf
+       gsm_option(handle, GSM_OPT_FRAME_INDEX, & value)
+.fi
+.br 
+For WAV-style framing, the value should be 0 or 1; the first frame
+of an encoding has an index of 0. 
+At library initialization, the index is set to zero.
+.br 
+The frame index can be queried and set at any time.
+Used in combination with the
+.IR GSM_OPT_FRAME_CHAIN ,
+option, it can be used to position on arbitrary GSM frames
+within a format like WAV #49 (not accounting for the lost
+internal GSM state).
+.in-5
+.SH "RETURN VALUE"
+gsm_option() returns -1 if an option is not supported, the
+previous value of the option otherwise.
+.SH BUGS
+Please direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de.
+.SH "SEE ALSO"
+toast(1), gsm(3), gsm_explode(3), gsm_print(3)
diff --git a/libgsmfr/man/gsm_print.3 b/libgsmfr/man/gsm_print.3
new file mode 100644 (file)
index 0000000..48d6883
--- /dev/null
@@ -0,0 +1,52 @@
+.\"
+.\" Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+.\" Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+.\" details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+.\"
+.PU
+.TH GSM_PRINT 3 
+.SH NAME
+gsm_print \(em GSM\ 06.10 supplementary function for debugging
+.SH SYNOPSIS
+#include "gsm.h"
+#include <stdio.h>
+
+int gsm_print(f, g, frame);
+.br
+FILE * f;
+.br
+gsm    g;
+.br
+gsm_frame frame;
+.SH "DESCRIPTION"
+Gsm is an implementation of the final draft GSM 06.10
+standard for full-rate speech transcoding, a lossy
+speech compression algorithm.
+The compressed form involves 76 variables with different numbers
+of significant bits packed into 33 bytes.
+.PP
+If you are interested in investigating the details of this
+coding scheme, gsm_print() can be used to dump the contents
+of individual gsm_frames to a file pointer provided by
+the application.
+.PP
+.SH "RETURN VALUE"
+gsm_print() returns -1 if the frame is invalid, else 0.
+.SH EXAMPLE
+A single frame looks like this:
+.br
+.nf
+LARc:   29  32  20  11  08  05  06  07
+#1:     Nc 0040    bc 0    Mc 1    xmaxc 60
+        06 04 00 03 03 06 04 02 02 04 05 04 01
+#2:     Nc 0045    bc 1    Mc 1    xmaxc 48
+        03 07 01 03 04 04 07 01 03 02 04 05 03
+#3:     Nc 0091    bc 1    Mc 1    xmaxc 46
+        00 03 03 07 01 06 02 04 05 03 03 02 04
+#4:     Nc 0120    bc 0    Mc 1    xmaxc 47
+        07 03 06 00 03 03 06 05 00 03 02 07 04
+.nf
+.SH BUGS
+Please direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de.
+.SH "SEE ALSO"
+gsm(3), gsm_explode(3) 
diff --git a/libgsmfr/man/toast.1 b/libgsmfr/man/toast.1
new file mode 100644 (file)
index 0000000..e54647b
--- /dev/null
@@ -0,0 +1,156 @@
+.\"
+.\" Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+.\" Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+.\" details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+.\"
+.if n .ds mU u
+.if t .ds mU \(*m
+.\"
+.TH TOAST 1 local
+.SH NAME
+toast \(em GSM\ 06.10 lossy sound compression
+.SH SYNOPSIS
+.ll +8
+.B toast
+[
+.B \-cdfpvhualsFC
+] [
+.I "filename...\&"
+]
+.LP
+.B untoast
+[
+.B \-cfpvhuaslF
+] [
+.I "filename...\&"
+]
+.LP
+.B tcat
+[
+.B \-vhuaslF
+] [
+.I "filename...\&"
+]
+.ll -8
+.SH DESCRIPTION
+Toast compresses the sound files given on its command line.
+Each file is replaced by a file with the extension
+.I \&.gsm .
+If no files are specified, the compression is applied to the
+standard input, and its result is written to standard output.
+.PP
+Toasted files can be restored to something not quite unlike
+their original form by running toast
+.I "\-d"
+, or 
+.I untoast
+, on the \&.gsm-files or standard input.
+.PP
+The program 
+.I tcat
+(the same as running
+.I "untoast \-c"
+)  uncompresses its input on standard output,
+but leaves the compressed .gsm\-files alone.
+.PP
+When files are compressed or uncompressed into other files,
+the ownership (if run by root), modes, accessed and modified times
+are maintained between both versions.
+.SH OPTIONS
+.TP
+.B \-c
+(cat)
+Write to the standard output; no files are changed.
+.TP
+.B \-d
+(decode)
+Decode, rather than encode, the files.
+.TP
+.B \-f
+(force)
+Force replacement of output files if they exist.
+If \-f is omitted and toast (or untoast) is run interactively from
+a terminal, the user is prompted as to whether the file should be replaced.
+.TP
+.B \-p
+(precious)
+Do not delete the source files.
+Source files are implicitly left alone whenever \-c is
+specified or tcat is run.
+.TP
+.B \-C
+(LTP cut-off)
+Ignore most sample values when calculating the GSM long-term
+correlation lag during encoding.
+(The multiplications that do this are a bottleneck
+of the algorithm.)
+The resulting encoding process will not produce
+exactly the same results as GSM 06.10 would,
+but remains close enough to be compatible.
+.br
+The
+.B \-C
+option applies only to the encoder and is silently
+ignored by the decoder.
+.TP
+.B \-F
+(fast)
+On systems with a floating point processor, but without
+a multiplication instruction, \-F sacrifices standard conformance to
+performance and nearly doubles the speed of the algorithm.
+.br
+The resulting encoding and decoding process will not produce
+exactly the same results as GSM 06.10 would, but remains close
+enough to be compatible.
+.br
+The default is standard-conforming operation.
+.TP
+.B \-v
+(version)\ 
+outputs the version of toast (or untoast or tcat) to stdout and exits.
+.TP
+.B \-h
+(help)\ 
+prints a short overview of the options.
+.PP
+Toast, untoast and tcat try to guess the appropriate audio data 
+format from the file suffix.
+Command line options can also specify a format to be used for 
+all files.
+.br
+The following formats are supported:
+.TP
+.B "\-u"
+(\(*mU-law)
+8 kHz, 8 bit \(*mU-law encoding (file suffix .u)
+.TP
+.B "\-a"
+(A-law)
+8 kHz, 8 bit A-law encoding (file suffix .A)
+.TP
+.B "\-s"
+(Sun audio)
+8 kHz, 8 bit \(*mU-law encoding with audio header (file suffix .au)
+.TP
+.B "-l"
+(linear)
+8 kHz, 16 bit signed linear encoding in host byte order
+with 13 significant bits (file suffix .l)
+.PP
+In absence of options or suffixes to specify a format, 
+\(*mU-law encoding as forced by \-u is assumed.
+.PP
+.SH PECULIARITIES
+A four bit magic number is prefixed to each 32 1/2-byte GSM frame,
+mainly because 32 1/2-bytes are rather clumsy to handle.
+.SH WARNING
+The compression algorithm used is a lossy compression algorithm
+devised especially for speech; on no account should it be used
+for text, pictures or any other non-speech-data you consider
+valuable.
+.SH BUGS
+Please direct bug reports to jutta@cs.tu-berlin.de.
+.SH "SEE ALSO"
+gsm(3)
+.\"
+.\" Toast is dedicated to Bill Sienkiewicz, author of "Stray Toasters".
diff --git a/libgsmfr/src/add.c b/libgsmfr/src/add.c
new file mode 100644 (file)
index 0000000..258a6fc
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/add.c,v 1.6 1996/07/02 09:57:33 jutta Exp $ */
+
+/*
+ *  See private.h for the more commonly used macro versions.
+ */
+
+#include       <stdio.h>
+#include       <assert.h>
+
+#include       "private.h"
+#include       "gsm.h"
+#include       "proto.h"
+
+#define        saturate(x)     \
+       ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x))
+
+word gsm_add P2((a,b), word a, word b)
+{
+       longword sum = (longword)a + (longword)b;
+       return saturate(sum);
+}
+
+word gsm_sub P2((a,b), word a, word b)
+{
+       longword diff = (longword)a - (longword)b;
+       return saturate(diff);
+}
+
+word gsm_mult P2((a,b), word a, word b)
+{
+       if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD;
+       else return SASR( (longword)a * (longword)b, 15 );
+}
+
+word gsm_mult_r P2((a,b), word a, word b)
+{
+       if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD;
+       else {
+               longword prod = (longword)a * (longword)b + 16384;
+               prod >>= 15;
+               return prod & 0xFFFF;
+       }
+}
+
+word gsm_abs P1((a), word a)
+{
+       return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;
+}
+
+longword gsm_L_mult P2((a,b),word a, word b)
+{
+       assert( a != MIN_WORD || b != MIN_WORD );
+       return ((longword)a * (longword)b) << 1;
+}
+
+longword gsm_L_add P2((a,b), longword a, longword b)
+{
+       if (a < 0) {
+               if (b >= 0) return a + b;
+               else {
+                       ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1);
+                       return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2;
+               }
+       }
+       else if (b <= 0) return a + b;
+       else {
+               ulongword A = (ulongword)a + (ulongword)b;
+               return A > MAX_LONGWORD ? MAX_LONGWORD : A;
+       }
+}
+
+longword gsm_L_sub P2((a,b), longword a, longword b)
+{
+       if (a >= 0) {
+               if (b >= 0) return a - b;
+               else {
+                       /* a>=0, b<0 */
+
+                       ulongword A = (ulongword)a + -(b + 1);
+                       return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1);
+               }
+       }
+       else if (b <= 0) return a - b;
+       else {
+               /* a<0, b>0 */  
+
+               ulongword A = (ulongword)-(a + 1) + b;
+               return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1;
+       }
+}
+
+static unsigned char const bitoff[ 256 ] = {
+        8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+word gsm_norm P1((a), longword a )
+/*
+ * the number of left shifts needed to normalize the 32 bit
+ * variable L_var1 for positive values on the interval
+ *
+ * with minimum of
+ * minimum of 1073741824  (01000000000000000000000000000000) and 
+ * maximum of 2147483647  (01111111111111111111111111111111)
+ *
+ *
+ * and for negative values on the interval with
+ * minimum of -2147483648 (-10000000000000000000000000000000) and
+ * maximum of -1073741824 ( -1000000000000000000000000000000).
+ *
+ * in order to normalize the result, the following
+ * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 );
+ *
+ * (That's 'ffs', only from the left, not the right..)
+ */
+{
+       assert(a != 0);
+
+       if (a < 0) {
+               if (a <= -1073741824) return 0;
+               a = ~a;
+       }
+
+       return    a & 0xffff0000 
+               ? ( a & 0xff000000
+                 ?  -1 + bitoff[ 0xFF & (a >> 24) ]
+                 :   7 + bitoff[ 0xFF & (a >> 16) ] )
+               : ( a & 0xff00
+                 ?  15 + bitoff[ 0xFF & (a >> 8) ]
+                 :  23 + bitoff[ 0xFF & a ] );
+}
+
+longword gsm_L_asl P2((a,n), longword a, int n)
+{
+       if (n >= 32) return 0;
+       if (n <= -32) return -(a < 0);
+       if (n < 0) return gsm_L_asr(a, -n);
+       return a << n;
+}
+
+word gsm_asl P2((a,n), word a, int n)
+{
+       if (n >= 16) return 0;
+       if (n <= -16) return -(a < 0);
+       if (n < 0) return gsm_asr(a, -n);
+       return a << n;
+}
+
+longword gsm_L_asr P2((a,n), longword a, int n)
+{
+       if (n >= 32) return -(a < 0);
+       if (n <= -32) return 0;
+       if (n < 0) return a << -n;
+
+#      ifdef   SASR
+               return a >> n;
+#      else
+               if (a >= 0) return a >> n;
+               else return -(longword)( -(ulongword)a >> n );
+#      endif
+}
+
+word gsm_asr P2((a,n), word a, int n)
+{
+       if (n >= 16) return -(a < 0);
+       if (n <= -16) return 0;
+       if (n < 0) return a << -n;
+
+#      ifdef   SASR
+               return a >> n;
+#      else
+               if (a >= 0) return a >> n;
+               else return -(word)( -(uword)a >> n );
+#      endif
+}
+
+/* 
+ *  (From p. 46, end of section 4.2.5)
+ *
+ *  NOTE: The following lines gives [sic] one correct implementation
+ *       of the div(num, denum) arithmetic operation.  Compute div
+ *        which is the integer division of num by denum: with denum
+ *       >= num > 0
+ */
+
+word gsm_div P2((num,denum), word num, word denum)
+{
+       longword        L_num   = num;
+       longword        L_denum = denum;
+       word            div     = 0;
+       int             k       = 15;
+
+       /* The parameter num sometimes becomes zero.
+        * Although this is explicitly guarded against in 4.2.5,
+        * we assume that the result should then be zero as well.
+        */
+
+       /* assert(num != 0); */
+
+       assert(num >= 0 && denum >= num);
+       if (num == 0)
+           return 0;
+
+       while (k--) {
+               div   <<= 1;
+               L_num <<= 1;
+
+               if (L_num >= L_denum) {
+                       L_num -= L_denum;
+                       div++;
+               }
+       }
+
+       return div;
+}
diff --git a/libgsmfr/src/code.c b/libgsmfr/src/code.c
new file mode 100644 (file)
index 0000000..65dd0a3
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/code.c,v 1.3 1996/07/02 09:59:05 jutta Exp $ */
+
+#include       "config.h"
+
+
+#ifdef HAS_STDLIB_H
+#include       <stdlib.h>
+#else
+#      include "proto.h"
+       extern char     * memcpy P((char *, char *, int));
+#endif
+
+#include       "private.h"
+#include       "gsm.h"
+#include       "proto.h"
+
+/* 
+ *  4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER 
+ */
+
+void Gsm_Coder P8((S,s,LARc,Nc,bc,Mc,xmaxc,xMc),
+
+       struct gsm_state        * S,
+
+       word    * s,    /* [0..159] samples                     IN      */
+
+/*
+ * The RPE-LTD coder works on a frame by frame basis.  The length of
+ * the frame is equal to 160 samples.  Some computations are done
+ * once per frame to produce at the output of the coder the
+ * LARc[1..8] parameters which are the coded LAR coefficients and 
+ * also to realize the inverse filtering operation for the entire
+ * frame (160 samples of signal d[0..159]).  These parts produce at
+ * the output of the coder:
+ */
+
+       word    * LARc, /* [0..7] LAR coefficients              OUT     */
+
+/*
+ * Procedure 4.2.11 to 4.2.18 are to be executed four times per
+ * frame.  That means once for each sub-segment RPE-LTP analysis of
+ * 40 samples.  These parts produce at the output of the coder:
+ */
+
+       word    * Nc,   /* [0..3] LTP lag                       OUT     */
+       word    * bc,   /* [0..3] coded LTP gain                OUT     */
+       word    * Mc,   /* [0..3] RPE grid selection            OUT     */
+       word    * xmaxc,/* [0..3] Coded maximum amplitude       OUT     */
+       word    * xMc   /* [13*4] normalized RPE samples        OUT     */
+)
+{
+       int     k;
+       word    * dp  = S->dp0 + 120;   /* [ -120...-1 ] */
+       word    * dpp = dp;             /* [ 0...39 ]    */
+
+       word    so[160];
+
+       Gsm_Preprocess                  (S, s, so);
+       Gsm_LPC_Analysis                (S, so, LARc);
+       Gsm_Short_Term_Analysis_Filter  (S, LARc, so);
+
+       for (k = 0; k <= 3; k++, xMc += 13) {
+
+               Gsm_Long_Term_Predictor ( S,
+                                        so+k*40, /* d      [0..39] IN  */
+                                        dp,      /* dp  [-120..-1] IN  */
+                                       S->e + 5, /* e      [0..39] OUT */
+                                       dpp,      /* dpp    [0..39] OUT */
+                                        Nc++,
+                                        bc++);
+
+               Gsm_RPE_Encoding        ( S,
+                                       S->e + 5,/* e     ][0..39][ IN/OUT */
+                                         xmaxc++, Mc++, xMc );
+               /*
+                * Gsm_Update_of_reconstructed_short_time_residual_signal
+                *                      ( dpp, S->e + 5, dp );
+                */
+
+               { register int i;
+                 register longword ltmp;
+                 for (i = 0; i <= 39; i++)
+                       dp[ i ] = GSM_ADD( S->e[5 + i], dpp[i] );
+               }
+               dp  += 40;
+               dpp += 40;
+
+       }
+       (void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160),
+               120 * sizeof(*S->dp0) );
+}
diff --git a/libgsmfr/src/debug.c b/libgsmfr/src/debug.c
new file mode 100644 (file)
index 0000000..04c3907
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/debug.c,v 1.2 1993/01/29 18:22:20 jutta Exp $ */
+
+#include "private.h"
+
+#ifndef        NDEBUG
+
+/* If NDEBUG _is_ defined and no debugging should be performed,
+ * calls to functions in this module are #defined to nothing
+ * in private.h.
+ */
+
+#include <stdio.h>
+#include "proto.h"
+
+void gsm_debug_words P4( (name, from, to, ptr), 
+       char          * name,
+       int             from,
+       int             to,
+       word            * ptr)
+{
+       int     nprinted = 0;
+
+       fprintf( stderr, "%s [%d .. %d]: ", name, from, to );
+       while (from <= to) {
+               fprintf(stderr, "%d ", ptr[ from ] );
+               from++;
+               if (nprinted++ >= 7) {
+                       nprinted = 0;
+                       if (from < to) putc('\n', stderr);
+               }
+       }
+       putc('\n', stderr);
+}
+
+void gsm_debug_longwords P4( (name, from, to, ptr),
+       char          * name,
+       int             from,
+       int             to,
+       longword      * ptr)
+{
+       int     nprinted = 0;
+
+       fprintf( stderr, "%s [%d .. %d]: ", name, from, to );
+       while (from <= to) {
+
+               fprintf(stderr, "%d ", ptr[ from ] );
+               from++;
+               if (nprinted++ >= 7) {
+                       nprinted = 0;
+                       if (from < to) putc('\n', stderr);
+               }
+       }
+       putc('\n', stderr);
+}
+
+void gsm_debug_longword P2(  (name, value),
+       char            * name,
+       longword          value )
+{
+       fprintf(stderr, "%s: %d\n", name, (long)value );
+}
+
+void gsm_debug_word P2(  (name, value),
+       char    * name,
+       word      value )
+{
+       fprintf(stderr, "%s: %d\n", name, (long)value);
+}
+
+#endif
diff --git a/libgsmfr/src/decode.c b/libgsmfr/src/decode.c
new file mode 100644 (file)
index 0000000..d51c54a
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/decode.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */
+
+#include <stdio.h>
+
+#include       "private.h"
+#include       "gsm.h"
+#include       "proto.h"
+
+/*
+ *  4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER
+ */
+
+static void Postprocessing P2((S,s),
+       struct gsm_state        * S,
+       register word           * s)
+{
+       register int            k;
+       register word           msr = S->msr;
+       register longword       ltmp;   /* for GSM_ADD */
+       register word           tmp;
+
+       for (k = 160; k--; s++) {
+               tmp = GSM_MULT_R( msr, 28180 );
+               msr = GSM_ADD(*s, tmp);            /* Deemphasis             */
+               *s  = GSM_ADD(msr, msr) & 0xFFF8;  /* Truncation & Upscaling */
+       }
+       S->msr = msr;
+}
+
+void Gsm_Decoder P8((S,LARcr, Ncr,bcr,Mcr,xmaxcr,xMcr,s),
+       struct gsm_state        * S,
+
+       word            * LARcr,        /* [0..7]               IN      */
+
+       word            * Ncr,          /* [0..3]               IN      */
+       word            * bcr,          /* [0..3]               IN      */
+       word            * Mcr,          /* [0..3]               IN      */
+       word            * xmaxcr,       /* [0..3]               IN      */
+       word            * xMcr,         /* [0..13*4]            IN      */
+
+       word            * s)            /* [0..159]             OUT     */
+{
+       int             j, k;
+       word            erp[40], wt[160];
+       word            * drp = S->dp0 + 120;
+
+       for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) {
+
+               Gsm_RPE_Decoding( S, *xmaxcr, *Mcr, xMcr, erp );
+               Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp );
+
+               for (k = 0; k <= 39; k++) wt[ j * 40 + k ] =  drp[ k ];
+       }
+
+       Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s );
+       Postprocessing(S, s);
+}
diff --git a/libgsmfr/src/gsm_create.c b/libgsmfr/src/gsm_create.c
new file mode 100644 (file)
index 0000000..a0bf634
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+static char const      ident[] = "$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_create.c,v 1.4 1996/07/02 09:59:05 jutta Exp $";
+
+#include       "config.h"
+
+#ifdef HAS_STRING_H
+#include       <string.h>
+#else
+#      include "proto.h"
+       extern char     * memset P((char *, int, int));
+#endif
+
+#ifdef HAS_STDLIB_H
+#      include <stdlib.h>
+#else
+#      ifdef   HAS_MALLOC_H
+#              include         <malloc.h>
+#      else
+               extern char * malloc();
+#      endif
+#endif
+
+#include <stdio.h>
+
+#include "gsm.h"
+#include "private.h"
+#include "proto.h"
+
+gsm gsm_create P0()
+{
+       gsm  r;
+
+       r = (gsm)malloc(sizeof(struct gsm_state));
+       if (!r) return r;
+
+       memset((char *)r, 0, sizeof(*r));
+       r->nrp = 40;
+
+       return r;
+}
diff --git a/libgsmfr/src/gsm_decode.c b/libgsmfr/src/gsm_decode.c
new file mode 100644 (file)
index 0000000..973c08b
--- /dev/null
@@ -0,0 +1,361 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_decode.c,v 1.2 1996/07/02 09:59:05 jutta Exp $ */
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_decode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target)
+{
+       word    LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
+
+#ifdef WAV49
+       if (s->wav_fmt) {
+
+               uword sr = 0;
+
+               s->frame_index = !s->frame_index;
+               if (s->frame_index) {
+
+                       sr = *c++;
+                       LARc[0] = sr & 0x3f;  sr >>= 6;
+                       sr |= (uword)*c++ << 2;
+                       LARc[1] = sr & 0x3f;  sr >>= 6;
+                       sr |= (uword)*c++ << 4;
+                       LARc[2] = sr & 0x1f;  sr >>= 5;
+                       LARc[3] = sr & 0x1f;  sr >>= 5;
+                       sr |= (uword)*c++ << 2;
+                       LARc[4] = sr & 0xf;  sr >>= 4;
+                       LARc[5] = sr & 0xf;  sr >>= 4;
+                       sr |= (uword)*c++ << 2;                 /* 5 */
+                       LARc[6] = sr & 0x7;  sr >>= 3;
+                       LARc[7] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[0] = sr & 0x7f;  sr >>= 7;
+                       bc[0] = sr & 0x3;  sr >>= 2;
+                       Mc[0] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[0] = sr & 0x3f;  sr >>= 6;
+                       xmc[0] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[1] = sr & 0x7;  sr >>= 3;
+                       xmc[2] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[3] = sr & 0x7;  sr >>= 3;
+                       xmc[4] = sr & 0x7;  sr >>= 3;
+                       xmc[5] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 10 */
+                       xmc[6] = sr & 0x7;  sr >>= 3;
+                       xmc[7] = sr & 0x7;  sr >>= 3;
+                       xmc[8] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[9] = sr & 0x7;  sr >>= 3;
+                       xmc[10] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[11] = sr & 0x7;  sr >>= 3;
+                       xmc[12] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[1] = sr & 0x7f;  sr >>= 7;
+                       bc[1] = sr & 0x3;  sr >>= 2;
+                       Mc[1] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[1] = sr & 0x3f;  sr >>= 6;
+                       xmc[13] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 15 */
+                       xmc[14] = sr & 0x7;  sr >>= 3;
+                       xmc[15] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[16] = sr & 0x7;  sr >>= 3;
+                       xmc[17] = sr & 0x7;  sr >>= 3;
+                       xmc[18] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[19] = sr & 0x7;  sr >>= 3;
+                       xmc[20] = sr & 0x7;  sr >>= 3;
+                       xmc[21] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[22] = sr & 0x7;  sr >>= 3;
+                       xmc[23] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[24] = sr & 0x7;  sr >>= 3;
+                       xmc[25] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;                 /* 20 */
+                       Nc[2] = sr & 0x7f;  sr >>= 7;
+                       bc[2] = sr & 0x3;  sr >>= 2;
+                       Mc[2] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[2] = sr & 0x3f;  sr >>= 6;
+                       xmc[26] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[27] = sr & 0x7;  sr >>= 3;
+                       xmc[28] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[29] = sr & 0x7;  sr >>= 3;
+                       xmc[30] = sr & 0x7;  sr >>= 3;
+                       xmc[31] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[32] = sr & 0x7;  sr >>= 3;
+                       xmc[33] = sr & 0x7;  sr >>= 3;
+                       xmc[34] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 25 */
+                       xmc[35] = sr & 0x7;  sr >>= 3;
+                       xmc[36] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[37] = sr & 0x7;  sr >>= 3;
+                       xmc[38] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[3] = sr & 0x7f;  sr >>= 7;
+                       bc[3] = sr & 0x3;  sr >>= 2;
+                       Mc[3] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[3] = sr & 0x3f;  sr >>= 6;
+                       xmc[39] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[40] = sr & 0x7;  sr >>= 3;
+                       xmc[41] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;                 /* 30 */
+                       xmc[42] = sr & 0x7;  sr >>= 3;
+                       xmc[43] = sr & 0x7;  sr >>= 3;
+                       xmc[44] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[45] = sr & 0x7;  sr >>= 3;
+                       xmc[46] = sr & 0x7;  sr >>= 3;
+                       xmc[47] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[48] = sr & 0x7;  sr >>= 3;
+                       xmc[49] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[50] = sr & 0x7;  sr >>= 3;
+                       xmc[51] = sr & 0x7;  sr >>= 3;
+
+                       s->frame_chain = sr & 0xf;
+               }
+               else {
+                       sr = s->frame_chain;
+                       sr |= (uword)*c++ << 4;                 /* 1 */
+                       LARc[0] = sr & 0x3f;  sr >>= 6;
+                       LARc[1] = sr & 0x3f;  sr >>= 6;
+                       sr = *c++;
+                       LARc[2] = sr & 0x1f;  sr >>= 5;
+                       sr |= (uword)*c++ << 3;
+                       LARc[3] = sr & 0x1f;  sr >>= 5;
+                       LARc[4] = sr & 0xf;  sr >>= 4;
+                       sr |= (uword)*c++ << 2;
+                       LARc[5] = sr & 0xf;  sr >>= 4;
+                       LARc[6] = sr & 0x7;  sr >>= 3;
+                       LARc[7] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 5 */
+                       Nc[0] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;
+                       bc[0] = sr & 0x3;  sr >>= 2;
+                       Mc[0] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[0] = sr & 0x3f;  sr >>= 6;
+                       xmc[0] = sr & 0x7;  sr >>= 3;
+                       xmc[1] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[2] = sr & 0x7;  sr >>= 3;
+                       xmc[3] = sr & 0x7;  sr >>= 3;
+                       xmc[4] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[5] = sr & 0x7;  sr >>= 3;
+                       xmc[6] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;                 /* 10 */
+                       xmc[7] = sr & 0x7;  sr >>= 3;
+                       xmc[8] = sr & 0x7;  sr >>= 3;
+                       xmc[9] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[10] = sr & 0x7;  sr >>= 3;
+                       xmc[11] = sr & 0x7;  sr >>= 3;
+                       xmc[12] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[1] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;
+                       bc[1] = sr & 0x3;  sr >>= 2;
+                       Mc[1] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[1] = sr & 0x3f;  sr >>= 6;
+                       xmc[13] = sr & 0x7;  sr >>= 3;
+                       xmc[14] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 15 */
+                       xmc[15] = sr & 0x7;  sr >>= 3;
+                       xmc[16] = sr & 0x7;  sr >>= 3;
+                       xmc[17] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[18] = sr & 0x7;  sr >>= 3;
+                       xmc[19] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[20] = sr & 0x7;  sr >>= 3;
+                       xmc[21] = sr & 0x7;  sr >>= 3;
+                       xmc[22] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[23] = sr & 0x7;  sr >>= 3;
+                       xmc[24] = sr & 0x7;  sr >>= 3;
+                       xmc[25] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[2] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;                 /* 20 */
+                       bc[2] = sr & 0x3;  sr >>= 2;
+                       Mc[2] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[2] = sr & 0x3f;  sr >>= 6;
+                       xmc[26] = sr & 0x7;  sr >>= 3;
+                       xmc[27] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1; 
+                       xmc[28] = sr & 0x7;  sr >>= 3;
+                       xmc[29] = sr & 0x7;  sr >>= 3;
+                       xmc[30] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[31] = sr & 0x7;  sr >>= 3;
+                       xmc[32] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[33] = sr & 0x7;  sr >>= 3;
+                       xmc[34] = sr & 0x7;  sr >>= 3;
+                       xmc[35] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 25 */
+                       xmc[36] = sr & 0x7;  sr >>= 3;
+                       xmc[37] = sr & 0x7;  sr >>= 3;
+                       xmc[38] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[3] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;         
+                       bc[3] = sr & 0x3;  sr >>= 2;
+                       Mc[3] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[3] = sr & 0x3f;  sr >>= 6;
+                       xmc[39] = sr & 0x7;  sr >>= 3;
+                       xmc[40] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[41] = sr & 0x7;  sr >>= 3;
+                       xmc[42] = sr & 0x7;  sr >>= 3;
+                       xmc[43] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 30 */
+                       xmc[44] = sr & 0x7;  sr >>= 3;
+                       xmc[45] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[46] = sr & 0x7;  sr >>= 3;
+                       xmc[47] = sr & 0x7;  sr >>= 3;
+                       xmc[48] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[49] = sr & 0x7;  sr >>= 3;
+                       xmc[50] = sr & 0x7;  sr >>= 3;
+                       xmc[51] = sr & 0x7;  sr >>= 3;
+               }
+       }
+       else
+#endif
+       {
+               /* GSM_MAGIC  = (*c >> 4) & 0xF; */
+
+               if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
+
+               LARc[0]  = (*c++ & 0xF) << 2;           /* 1 */
+               LARc[0] |= (*c >> 6) & 0x3;
+               LARc[1]  = *c++ & 0x3F;
+               LARc[2]  = (*c >> 3) & 0x1F;
+               LARc[3]  = (*c++ & 0x7) << 2;
+               LARc[3] |= (*c >> 6) & 0x3;
+               LARc[4]  = (*c >> 2) & 0xF;
+               LARc[5]  = (*c++ & 0x3) << 2;
+               LARc[5] |= (*c >> 6) & 0x3;
+               LARc[6]  = (*c >> 3) & 0x7;
+               LARc[7]  = *c++ & 0x7;
+               Nc[0]  = (*c >> 1) & 0x7F;
+               bc[0]  = (*c++ & 0x1) << 1;
+               bc[0] |= (*c >> 7) & 0x1;
+               Mc[0]  = (*c >> 5) & 0x3;
+               xmaxc[0]  = (*c++ & 0x1F) << 1;
+               xmaxc[0] |= (*c >> 7) & 0x1;
+               xmc[0]  = (*c >> 4) & 0x7;
+               xmc[1]  = (*c >> 1) & 0x7;
+               xmc[2]  = (*c++ & 0x1) << 2;
+               xmc[2] |= (*c >> 6) & 0x3;
+               xmc[3]  = (*c >> 3) & 0x7;
+               xmc[4]  = *c++ & 0x7;
+               xmc[5]  = (*c >> 5) & 0x7;
+               xmc[6]  = (*c >> 2) & 0x7;
+               xmc[7]  = (*c++ & 0x3) << 1;            /* 10 */
+               xmc[7] |= (*c >> 7) & 0x1;
+               xmc[8]  = (*c >> 4) & 0x7;
+               xmc[9]  = (*c >> 1) & 0x7;
+               xmc[10]  = (*c++ & 0x1) << 2;
+               xmc[10] |= (*c >> 6) & 0x3;
+               xmc[11]  = (*c >> 3) & 0x7;
+               xmc[12]  = *c++ & 0x7;
+               Nc[1]  = (*c >> 1) & 0x7F;
+               bc[1]  = (*c++ & 0x1) << 1;
+               bc[1] |= (*c >> 7) & 0x1;
+               Mc[1]  = (*c >> 5) & 0x3;
+               xmaxc[1]  = (*c++ & 0x1F) << 1;
+               xmaxc[1] |= (*c >> 7) & 0x1;
+               xmc[13]  = (*c >> 4) & 0x7;
+               xmc[14]  = (*c >> 1) & 0x7;
+               xmc[15]  = (*c++ & 0x1) << 2;
+               xmc[15] |= (*c >> 6) & 0x3;
+               xmc[16]  = (*c >> 3) & 0x7;
+               xmc[17]  = *c++ & 0x7;
+               xmc[18]  = (*c >> 5) & 0x7;
+               xmc[19]  = (*c >> 2) & 0x7;
+               xmc[20]  = (*c++ & 0x3) << 1;
+               xmc[20] |= (*c >> 7) & 0x1;
+               xmc[21]  = (*c >> 4) & 0x7;
+               xmc[22]  = (*c >> 1) & 0x7;
+               xmc[23]  = (*c++ & 0x1) << 2;
+               xmc[23] |= (*c >> 6) & 0x3;
+               xmc[24]  = (*c >> 3) & 0x7;
+               xmc[25]  = *c++ & 0x7;
+               Nc[2]  = (*c >> 1) & 0x7F;
+               bc[2]  = (*c++ & 0x1) << 1;             /* 20 */
+               bc[2] |= (*c >> 7) & 0x1;
+               Mc[2]  = (*c >> 5) & 0x3;
+               xmaxc[2]  = (*c++ & 0x1F) << 1;
+               xmaxc[2] |= (*c >> 7) & 0x1;
+               xmc[26]  = (*c >> 4) & 0x7;
+               xmc[27]  = (*c >> 1) & 0x7;
+               xmc[28]  = (*c++ & 0x1) << 2;
+               xmc[28] |= (*c >> 6) & 0x3;
+               xmc[29]  = (*c >> 3) & 0x7;
+               xmc[30]  = *c++ & 0x7;
+               xmc[31]  = (*c >> 5) & 0x7;
+               xmc[32]  = (*c >> 2) & 0x7;
+               xmc[33]  = (*c++ & 0x3) << 1;
+               xmc[33] |= (*c >> 7) & 0x1;
+               xmc[34]  = (*c >> 4) & 0x7;
+               xmc[35]  = (*c >> 1) & 0x7;
+               xmc[36]  = (*c++ & 0x1) << 2;
+               xmc[36] |= (*c >> 6) & 0x3;
+               xmc[37]  = (*c >> 3) & 0x7;
+               xmc[38]  = *c++ & 0x7;
+               Nc[3]  = (*c >> 1) & 0x7F;
+               bc[3]  = (*c++ & 0x1) << 1;
+               bc[3] |= (*c >> 7) & 0x1;
+               Mc[3]  = (*c >> 5) & 0x3;
+               xmaxc[3]  = (*c++ & 0x1F) << 1;
+               xmaxc[3] |= (*c >> 7) & 0x1;
+               xmc[39]  = (*c >> 4) & 0x7;
+               xmc[40]  = (*c >> 1) & 0x7;
+               xmc[41]  = (*c++ & 0x1) << 2;
+               xmc[41] |= (*c >> 6) & 0x3;
+               xmc[42]  = (*c >> 3) & 0x7;
+               xmc[43]  = *c++ & 0x7;                  /* 30  */
+               xmc[44]  = (*c >> 5) & 0x7;
+               xmc[45]  = (*c >> 2) & 0x7;
+               xmc[46]  = (*c++ & 0x3) << 1;
+               xmc[46] |= (*c >> 7) & 0x1;
+               xmc[47]  = (*c >> 4) & 0x7;
+               xmc[48]  = (*c >> 1) & 0x7;
+               xmc[49]  = (*c++ & 0x1) << 2;
+               xmc[49] |= (*c >> 6) & 0x3;
+               xmc[50]  = (*c >> 3) & 0x7;
+               xmc[51]  = *c & 0x7;                    /* 33 */
+       }
+
+       Gsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target);
+
+       return 0;
+}
diff --git a/libgsmfr/src/gsm_destroy.c b/libgsmfr/src/gsm_destroy.c
new file mode 100644 (file)
index 0000000..03c8659
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_destroy.c,v 1.3 1994/11/28 19:52:25 jutta Exp $ */
+
+#include "gsm.h"
+#include "config.h"
+#include "proto.h"
+
+#ifdef HAS_STDLIB_H
+#      include <stdlib.h>
+#else
+#      ifdef   HAS_MALLOC_H
+#              include         <malloc.h>
+#      else
+               extern void free();
+#      endif
+#endif
+
+void gsm_destroy P1((S), gsm S)
+{
+       if (S) free((char *)S);
+}
diff --git a/libgsmfr/src/gsm_encode.c b/libgsmfr/src/gsm_encode.c
new file mode 100644 (file)
index 0000000..51bc556
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_encode.c,v 1.2 1996/07/02 09:59:05 jutta Exp $ */
+
+#include "private.h"
+#include "gsm.h"
+#include "proto.h"
+
+void gsm_encode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c)
+{
+       word            LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
+
+       Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc);
+
+
+       /*      variable        size
+
+               GSM_MAGIC       4
+
+               LARc[0]         6
+               LARc[1]         6
+               LARc[2]         5
+               LARc[3]         5
+               LARc[4]         4
+               LARc[5]         4
+               LARc[6]         3
+               LARc[7]         3
+
+               Nc[0]           7
+               bc[0]           2
+               Mc[0]           2
+               xmaxc[0]        6
+               xmc[0]          3
+               xmc[1]          3
+               xmc[2]          3
+               xmc[3]          3
+               xmc[4]          3
+               xmc[5]          3
+               xmc[6]          3
+               xmc[7]          3
+               xmc[8]          3
+               xmc[9]          3
+               xmc[10]         3
+               xmc[11]         3
+               xmc[12]         3
+
+               Nc[1]           7
+               bc[1]           2
+               Mc[1]           2
+               xmaxc[1]        6
+               xmc[13]         3
+               xmc[14]         3
+               xmc[15]         3
+               xmc[16]         3
+               xmc[17]         3
+               xmc[18]         3
+               xmc[19]         3
+               xmc[20]         3
+               xmc[21]         3
+               xmc[22]         3
+               xmc[23]         3
+               xmc[24]         3
+               xmc[25]         3
+
+               Nc[2]           7
+               bc[2]           2
+               Mc[2]           2
+               xmaxc[2]        6
+               xmc[26]         3
+               xmc[27]         3
+               xmc[28]         3
+               xmc[29]         3
+               xmc[30]         3
+               xmc[31]         3
+               xmc[32]         3
+               xmc[33]         3
+               xmc[34]         3
+               xmc[35]         3
+               xmc[36]         3
+               xmc[37]         3
+               xmc[38]         3
+
+               Nc[3]           7
+               bc[3]           2
+               Mc[3]           2
+               xmaxc[3]        6
+               xmc[39]         3
+               xmc[40]         3
+               xmc[41]         3
+               xmc[42]         3
+               xmc[43]         3
+               xmc[44]         3
+               xmc[45]         3
+               xmc[46]         3
+               xmc[47]         3
+               xmc[48]         3
+               xmc[49]         3
+               xmc[50]         3
+               xmc[51]         3
+       */
+
+#ifdef WAV49
+
+       if (s->wav_fmt) {
+               s->frame_index = !s->frame_index;
+               if (s->frame_index) {
+
+                       uword sr;
+
+                       sr = 0;
+                       sr = sr >> 6 | LARc[0] << 10;
+                       sr = sr >> 6 | LARc[1] << 10;
+                       *c++ = sr >> 4;
+                       sr = sr >> 5 | LARc[2] << 11;
+                       *c++ = sr >> 7;
+                       sr = sr >> 5 | LARc[3] << 11;
+                       sr = sr >> 4 | LARc[4] << 12;
+                       *c++ = sr >> 6;
+                       sr = sr >> 4 | LARc[5] << 12;
+                       sr = sr >> 3 | LARc[6] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | LARc[7] << 13;
+                       sr = sr >> 7 | Nc[0] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[0] << 14;
+                       sr = sr >> 2 | Mc[0] << 14;
+                       sr = sr >> 6 | xmaxc[0] << 10;
+                       *c++ = sr >> 3;
+                       sr = sr >> 3 | xmc[0] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[1] << 13;
+                       sr = sr >> 3 | xmc[2] << 13;
+                       sr = sr >> 3 | xmc[3] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[4] << 13;
+                       sr = sr >> 3 | xmc[5] << 13;
+                       sr = sr >> 3 | xmc[6] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[7] << 13;
+                       sr = sr >> 3 | xmc[8] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[9] << 13;
+                       sr = sr >> 3 | xmc[10] << 13;
+                       sr = sr >> 3 | xmc[11] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[12] << 13;
+                       sr = sr >> 7 | Nc[1] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[1] << 14;
+                       sr = sr >> 2 | Mc[1] << 14;
+                       sr = sr >> 6 | xmaxc[1] << 10;
+                       *c++ = sr >> 3;
+                       sr = sr >> 3 | xmc[13] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[14] << 13;
+                       sr = sr >> 3 | xmc[15] << 13;
+                       sr = sr >> 3 | xmc[16] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[17] << 13;
+                       sr = sr >> 3 | xmc[18] << 13;
+                       sr = sr >> 3 | xmc[19] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[20] << 13;
+                       sr = sr >> 3 | xmc[21] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[22] << 13;
+                       sr = sr >> 3 | xmc[23] << 13;
+                       sr = sr >> 3 | xmc[24] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[25] << 13;
+                       sr = sr >> 7 | Nc[2] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[2] << 14;
+                       sr = sr >> 2 | Mc[2] << 14;
+                       sr = sr >> 6 | xmaxc[2] << 10;
+                       *c++ = sr >> 3;
+                       sr = sr >> 3 | xmc[26] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[27] << 13;
+                       sr = sr >> 3 | xmc[28] << 13;
+                       sr = sr >> 3 | xmc[29] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[30] << 13;
+                       sr = sr >> 3 | xmc[31] << 13;
+                       sr = sr >> 3 | xmc[32] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[33] << 13;
+                       sr = sr >> 3 | xmc[34] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[35] << 13;
+                       sr = sr >> 3 | xmc[36] << 13;
+                       sr = sr >> 3 | xmc[37] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[38] << 13;
+                       sr = sr >> 7 | Nc[3] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[3] << 14;
+                       sr = sr >> 2 | Mc[3] << 14;
+                       sr = sr >> 6 | xmaxc[3] << 10;
+                       *c++ = sr >> 3;
+                       sr = sr >> 3 | xmc[39] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[40] << 13;
+                       sr = sr >> 3 | xmc[41] << 13;
+                       sr = sr >> 3 | xmc[42] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[43] << 13;
+                       sr = sr >> 3 | xmc[44] << 13;
+                       sr = sr >> 3 | xmc[45] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[46] << 13;
+                       sr = sr >> 3 | xmc[47] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[48] << 13;
+                       sr = sr >> 3 | xmc[49] << 13;
+                       sr = sr >> 3 | xmc[50] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[51] << 13;
+                       sr = sr >> 4;
+                       *c = sr >> 8;
+                       s->frame_chain = *c;
+               }
+               else {
+                       uword sr;
+
+                       sr = 0;
+                       sr = sr >> 4 | s->frame_chain << 12;
+                       sr = sr >> 6 | LARc[0] << 10;
+                       *c++ = sr >> 6;
+                       sr = sr >> 6 | LARc[1] << 10;
+                       *c++ = sr >> 8;
+                       sr = sr >> 5 | LARc[2] << 11;
+                       sr = sr >> 5 | LARc[3] << 11;
+                       *c++ = sr >> 6;
+                       sr = sr >> 4 | LARc[4] << 12;
+                       sr = sr >> 4 | LARc[5] << 12;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | LARc[6] << 13;
+                       sr = sr >> 3 | LARc[7] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[0] << 9;
+                       sr = sr >> 2 | bc[0] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[0] << 14;
+                       sr = sr >> 6 | xmaxc[0] << 10;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[0] << 13;
+                       sr = sr >> 3 | xmc[1] << 13;
+                       sr = sr >> 3 | xmc[2] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[3] << 13;
+                       sr = sr >> 3 | xmc[4] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[5] << 13;
+                       sr = sr >> 3 | xmc[6] << 13;
+                       sr = sr >> 3 | xmc[7] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[8] << 13;
+                       sr = sr >> 3 | xmc[9] << 13;
+                       sr = sr >> 3 | xmc[10] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[11] << 13;
+                       sr = sr >> 3 | xmc[12] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[1] << 9;
+                       sr = sr >> 2 | bc[1] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[1] << 14;
+                       sr = sr >> 6 | xmaxc[1] << 10;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[13] << 13;
+                       sr = sr >> 3 | xmc[14] << 13;
+                       sr = sr >> 3 | xmc[15] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[16] << 13;
+                       sr = sr >> 3 | xmc[17] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[18] << 13;
+                       sr = sr >> 3 | xmc[19] << 13;
+                       sr = sr >> 3 | xmc[20] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[21] << 13;
+                       sr = sr >> 3 | xmc[22] << 13;
+                       sr = sr >> 3 | xmc[23] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[24] << 13;
+                       sr = sr >> 3 | xmc[25] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[2] << 9;
+                       sr = sr >> 2 | bc[2] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[2] << 14;
+                       sr = sr >> 6 | xmaxc[2] << 10;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[26] << 13;
+                       sr = sr >> 3 | xmc[27] << 13;
+                       sr = sr >> 3 | xmc[28] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[29] << 13;
+                       sr = sr >> 3 | xmc[30] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[31] << 13;
+                       sr = sr >> 3 | xmc[32] << 13;
+                       sr = sr >> 3 | xmc[33] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[34] << 13;
+                       sr = sr >> 3 | xmc[35] << 13;
+                       sr = sr >> 3 | xmc[36] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[37] << 13;
+                       sr = sr >> 3 | xmc[38] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[3] << 9;
+                       sr = sr >> 2 | bc[3] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[3] << 14;
+                       sr = sr >> 6 | xmaxc[3] << 10;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[39] << 13;
+                       sr = sr >> 3 | xmc[40] << 13;
+                       sr = sr >> 3 | xmc[41] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[42] << 13;
+                       sr = sr >> 3 | xmc[43] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[44] << 13;
+                       sr = sr >> 3 | xmc[45] << 13;
+                       sr = sr >> 3 | xmc[46] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[47] << 13;
+                       sr = sr >> 3 | xmc[48] << 13;
+                       sr = sr >> 3 | xmc[49] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[50] << 13;
+                       sr = sr >> 3 | xmc[51] << 13;
+                       *c++ = sr >> 8;
+               }
+       }
+
+       else
+
+#endif /* WAV49 */
+       {
+
+               *c++ =   ((GSM_MAGIC & 0xF) << 4)               /* 1 */
+                      | ((LARc[0] >> 2) & 0xF);
+               *c++ =   ((LARc[0] & 0x3) << 6)
+                      | (LARc[1] & 0x3F);
+               *c++ =   ((LARc[2] & 0x1F) << 3)
+                      | ((LARc[3] >> 2) & 0x7);
+               *c++ =   ((LARc[3] & 0x3) << 6)
+                      | ((LARc[4] & 0xF) << 2)
+                      | ((LARc[5] >> 2) & 0x3);
+               *c++ =   ((LARc[5] & 0x3) << 6)
+                      | ((LARc[6] & 0x7) << 3)
+                      | (LARc[7] & 0x7);
+               *c++ =   ((Nc[0] & 0x7F) << 1)
+                      | ((bc[0] >> 1) & 0x1);
+               *c++ =   ((bc[0] & 0x1) << 7)
+                      | ((Mc[0] & 0x3) << 5)
+                      | ((xmaxc[0] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[0] & 0x1) << 7)
+                      | ((xmc[0] & 0x7) << 4)
+                      | ((xmc[1] & 0x7) << 1)
+                      | ((xmc[2] >> 2) & 0x1);
+               *c++ =   ((xmc[2] & 0x3) << 6)
+                      | ((xmc[3] & 0x7) << 3)
+                      | (xmc[4] & 0x7);
+               *c++ =   ((xmc[5] & 0x7) << 5)                  /* 10 */
+                      | ((xmc[6] & 0x7) << 2)
+                      | ((xmc[7] >> 1) & 0x3);
+               *c++ =   ((xmc[7] & 0x1) << 7)
+                      | ((xmc[8] & 0x7) << 4)
+                      | ((xmc[9] & 0x7) << 1)
+                      | ((xmc[10] >> 2) & 0x1);
+               *c++ =   ((xmc[10] & 0x3) << 6)
+                      | ((xmc[11] & 0x7) << 3)
+                      | (xmc[12] & 0x7);
+               *c++ =   ((Nc[1] & 0x7F) << 1)
+                      | ((bc[1] >> 1) & 0x1);
+               *c++ =   ((bc[1] & 0x1) << 7)
+                      | ((Mc[1] & 0x3) << 5)
+                      | ((xmaxc[1] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[1] & 0x1) << 7)
+                      | ((xmc[13] & 0x7) << 4)
+                      | ((xmc[14] & 0x7) << 1)
+                      | ((xmc[15] >> 2) & 0x1);
+               *c++ =   ((xmc[15] & 0x3) << 6)
+                      | ((xmc[16] & 0x7) << 3)
+                      | (xmc[17] & 0x7);
+               *c++ =   ((xmc[18] & 0x7) << 5)
+                      | ((xmc[19] & 0x7) << 2)
+                      | ((xmc[20] >> 1) & 0x3);
+               *c++ =   ((xmc[20] & 0x1) << 7)
+                      | ((xmc[21] & 0x7) << 4)
+                      | ((xmc[22] & 0x7) << 1)
+                      | ((xmc[23] >> 2) & 0x1);
+               *c++ =   ((xmc[23] & 0x3) << 6)
+                      | ((xmc[24] & 0x7) << 3)
+                      | (xmc[25] & 0x7);
+               *c++ =   ((Nc[2] & 0x7F) << 1)                  /* 20 */
+                      | ((bc[2] >> 1) & 0x1);
+               *c++ =   ((bc[2] & 0x1) << 7)
+                      | ((Mc[2] & 0x3) << 5)
+                      | ((xmaxc[2] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[2] & 0x1) << 7)
+                      | ((xmc[26] & 0x7) << 4)
+                      | ((xmc[27] & 0x7) << 1)
+                      | ((xmc[28] >> 2) & 0x1);
+               *c++ =   ((xmc[28] & 0x3) << 6)
+                      | ((xmc[29] & 0x7) << 3)
+                      | (xmc[30] & 0x7);
+               *c++ =   ((xmc[31] & 0x7) << 5)
+                      | ((xmc[32] & 0x7) << 2)
+                      | ((xmc[33] >> 1) & 0x3);
+               *c++ =   ((xmc[33] & 0x1) << 7)
+                      | ((xmc[34] & 0x7) << 4)
+                      | ((xmc[35] & 0x7) << 1)
+                      | ((xmc[36] >> 2) & 0x1);
+               *c++ =   ((xmc[36] & 0x3) << 6)
+                      | ((xmc[37] & 0x7) << 3)
+                      | (xmc[38] & 0x7);
+               *c++ =   ((Nc[3] & 0x7F) << 1)
+                      | ((bc[3] >> 1) & 0x1);
+               *c++ =   ((bc[3] & 0x1) << 7)
+                      | ((Mc[3] & 0x3) << 5)
+                      | ((xmaxc[3] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[3] & 0x1) << 7)
+                      | ((xmc[39] & 0x7) << 4)
+                      | ((xmc[40] & 0x7) << 1)
+                      | ((xmc[41] >> 2) & 0x1);
+               *c++ =   ((xmc[41] & 0x3) << 6)                 /* 30 */
+                      | ((xmc[42] & 0x7) << 3)
+                      | (xmc[43] & 0x7);
+               *c++ =   ((xmc[44] & 0x7) << 5)
+                      | ((xmc[45] & 0x7) << 2)
+                      | ((xmc[46] >> 1) & 0x3);
+               *c++ =   ((xmc[46] & 0x1) << 7)
+                      | ((xmc[47] & 0x7) << 4)
+                      | ((xmc[48] & 0x7) << 1)
+                      | ((xmc[49] >> 2) & 0x1);
+               *c++ =   ((xmc[49] & 0x3) << 6)
+                      | ((xmc[50] & 0x7) << 3)
+                      | (xmc[51] & 0x7);
+
+       }
+}
diff --git a/libgsmfr/src/gsm_explode.c b/libgsmfr/src/gsm_explode.c
new file mode 100644 (file)
index 0000000..ca48f9b
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_explode.c,v 1.2 1996/07/02 14:32:42 jutta Exp jutta $ */
+
+#include "private.h"
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_explode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target)
+{
+#      define  LARc    target
+#      define  Nc      *((gsm_signal (*) [17])(target + 8))
+#      define  bc      *((gsm_signal (*) [17])(target + 9))
+#      define  Mc      *((gsm_signal (*) [17])(target + 10))
+#      define  xmaxc   *((gsm_signal (*) [17])(target + 11))
+
+
+#ifdef WAV49
+       if (s->wav_fmt) {
+
+               uword sr = 0;
+
+               if (s->frame_index == 1) {
+
+                       sr = *c++;
+                       LARc[0] = sr & 0x3f;  sr >>= 6;
+                       sr |= (uword)*c++ << 2;
+                       LARc[1] = sr & 0x3f;  sr >>= 6;
+                       sr |= (uword)*c++ << 4;
+                       LARc[2] = sr & 0x1f;  sr >>= 5;
+                       LARc[3] = sr & 0x1f;  sr >>= 5;
+                       sr |= (uword)*c++ << 2;
+                       LARc[4] = sr & 0xf;  sr >>= 4;
+                       LARc[5] = sr & 0xf;  sr >>= 4;
+                       sr |= (uword)*c++ << 2;                 /* 5 */
+                       LARc[6] = sr & 0x7;  sr >>= 3;
+                       LARc[7] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[0] = sr & 0x7f;  sr >>= 7;
+                       bc[0] = sr & 0x3;  sr >>= 2;
+                       Mc[0] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[0] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (target + 12)
+                       xmc[0] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[1] = sr & 0x7;  sr >>= 3;
+                       xmc[2] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[3] = sr & 0x7;  sr >>= 3;
+                       xmc[4] = sr & 0x7;  sr >>= 3;
+                       xmc[5] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 10 */
+                       xmc[6] = sr & 0x7;  sr >>= 3;
+                       xmc[7] = sr & 0x7;  sr >>= 3;
+                       xmc[8] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[9] = sr & 0x7;  sr >>= 3;
+                       xmc[10] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[11] = sr & 0x7;  sr >>= 3;
+                       xmc[12] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[1] = sr & 0x7f;  sr >>= 7;
+                       bc[1] = sr & 0x3;  sr >>= 2;
+                       Mc[1] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[1] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (target + 29 - 13)
+
+                       xmc[13] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 15 */
+                       xmc[14] = sr & 0x7;  sr >>= 3;
+                       xmc[15] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[16] = sr & 0x7;  sr >>= 3;
+                       xmc[17] = sr & 0x7;  sr >>= 3;
+                       xmc[18] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[19] = sr & 0x7;  sr >>= 3;
+                       xmc[20] = sr & 0x7;  sr >>= 3;
+                       xmc[21] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[22] = sr & 0x7;  sr >>= 3;
+                       xmc[23] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[24] = sr & 0x7;  sr >>= 3;
+                       xmc[25] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;                 /* 20 */
+                       Nc[2] = sr & 0x7f;  sr >>= 7;
+                       bc[2] = sr & 0x3;  sr >>= 2;
+                       Mc[2] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[2] = sr & 0x3f;  sr >>= 6;
+
+#undef xmc
+#define        xmc     (target + 46 - 26)
+
+                       xmc[26] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[27] = sr & 0x7;  sr >>= 3;
+                       xmc[28] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[29] = sr & 0x7;  sr >>= 3;
+                       xmc[30] = sr & 0x7;  sr >>= 3;
+                       xmc[31] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[32] = sr & 0x7;  sr >>= 3;
+                       xmc[33] = sr & 0x7;  sr >>= 3;
+                       xmc[34] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 25 */
+                       xmc[35] = sr & 0x7;  sr >>= 3;
+                       xmc[36] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[37] = sr & 0x7;  sr >>= 3;
+                       xmc[38] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[3] = sr & 0x7f;  sr >>= 7;
+                       bc[3] = sr & 0x3;  sr >>= 2;
+                       Mc[3] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[3] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (target + 63 - 39)
+
+                       xmc[39] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[40] = sr & 0x7;  sr >>= 3;
+                       xmc[41] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;                 /* 30 */
+                       xmc[42] = sr & 0x7;  sr >>= 3;
+                       xmc[43] = sr & 0x7;  sr >>= 3;
+                       xmc[44] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[45] = sr & 0x7;  sr >>= 3;
+                       xmc[46] = sr & 0x7;  sr >>= 3;
+                       xmc[47] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[48] = sr & 0x7;  sr >>= 3;
+                       xmc[49] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[50] = sr & 0x7;  sr >>= 3;
+                       xmc[51] = sr & 0x7;  sr >>= 3;
+
+                       s->frame_chain = sr & 0xf;
+               }
+               else {
+                       sr = s->frame_chain;
+                       sr |= (uword)*c++ << 4;                 /* 1 */
+                       LARc[0] = sr & 0x3f;  sr >>= 6;
+                       LARc[1] = sr & 0x3f;  sr >>= 6;
+                       sr = *c++;
+                       LARc[2] = sr & 0x1f;  sr >>= 5;
+                       sr |= (uword)*c++ << 3;
+                       LARc[3] = sr & 0x1f;  sr >>= 5;
+                       LARc[4] = sr & 0xf;  sr >>= 4;
+                       sr |= (uword)*c++ << 2;
+                       LARc[5] = sr & 0xf;  sr >>= 4;
+                       LARc[6] = sr & 0x7;  sr >>= 3;
+                       LARc[7] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 5 */
+                       Nc[0] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;
+                       bc[0] = sr & 0x3;  sr >>= 2;
+                       Mc[0] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[0] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (target + 12)
+                       xmc[0] = sr & 0x7;  sr >>= 3;
+                       xmc[1] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[2] = sr & 0x7;  sr >>= 3;
+                       xmc[3] = sr & 0x7;  sr >>= 3;
+                       xmc[4] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[5] = sr & 0x7;  sr >>= 3;
+                       xmc[6] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;                 /* 10 */
+                       xmc[7] = sr & 0x7;  sr >>= 3;
+                       xmc[8] = sr & 0x7;  sr >>= 3;
+                       xmc[9] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[10] = sr & 0x7;  sr >>= 3;
+                       xmc[11] = sr & 0x7;  sr >>= 3;
+                       xmc[12] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[1] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;
+                       bc[1] = sr & 0x3;  sr >>= 2;
+                       Mc[1] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[1] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (target + 29 - 13)
+
+                       xmc[13] = sr & 0x7;  sr >>= 3;
+                       xmc[14] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 15 */
+                       xmc[15] = sr & 0x7;  sr >>= 3;
+                       xmc[16] = sr & 0x7;  sr >>= 3;
+                       xmc[17] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[18] = sr & 0x7;  sr >>= 3;
+                       xmc[19] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[20] = sr & 0x7;  sr >>= 3;
+                       xmc[21] = sr & 0x7;  sr >>= 3;
+                       xmc[22] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[23] = sr & 0x7;  sr >>= 3;
+                       xmc[24] = sr & 0x7;  sr >>= 3;
+                       xmc[25] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[2] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;                 /* 20 */
+                       bc[2] = sr & 0x3;  sr >>= 2;
+                       Mc[2] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[2] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (target + 46 - 26)
+                       xmc[26] = sr & 0x7;  sr >>= 3;
+                       xmc[27] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1; 
+                       xmc[28] = sr & 0x7;  sr >>= 3;
+                       xmc[29] = sr & 0x7;  sr >>= 3;
+                       xmc[30] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[31] = sr & 0x7;  sr >>= 3;
+                       xmc[32] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[33] = sr & 0x7;  sr >>= 3;
+                       xmc[34] = sr & 0x7;  sr >>= 3;
+                       xmc[35] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 25 */
+                       xmc[36] = sr & 0x7;  sr >>= 3;
+                       xmc[37] = sr & 0x7;  sr >>= 3;
+                       xmc[38] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[3] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;         
+                       bc[3] = sr & 0x3;  sr >>= 2;
+                       Mc[3] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[3] = sr & 0x3f;  sr >>= 6;
+
+#undef xmc
+#define        xmc     (target + 63 - 39)
+
+                       xmc[39] = sr & 0x7;  sr >>= 3;
+                       xmc[40] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[41] = sr & 0x7;  sr >>= 3;
+                       xmc[42] = sr & 0x7;  sr >>= 3;
+                       xmc[43] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 30 */
+                       xmc[44] = sr & 0x7;  sr >>= 3;
+                       xmc[45] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[46] = sr & 0x7;  sr >>= 3;
+                       xmc[47] = sr & 0x7;  sr >>= 3;
+                       xmc[48] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[49] = sr & 0x7;  sr >>= 3;
+                       xmc[50] = sr & 0x7;  sr >>= 3;
+                       xmc[51] = sr & 0x7;  sr >>= 3;
+               }
+       }
+       else 
+#endif
+       {
+       /* GSM_MAGIC  = (*c >> 4) & 0xF; */
+
+       if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
+
+       LARc[0]  = (*c++ & 0xF) << 2;           /* 1 */
+       LARc[0] |= (*c >> 6) & 0x3;
+       LARc[1]  = *c++ & 0x3F;
+       LARc[2]  = (*c >> 3) & 0x1F;
+       LARc[3]  = (*c++ & 0x7) << 2;
+       LARc[3] |= (*c >> 6) & 0x3;
+       LARc[4]  = (*c >> 2) & 0xF;
+       LARc[5]  = (*c++ & 0x3) << 2;
+       LARc[5] |= (*c >> 6) & 0x3;
+       LARc[6]  = (*c >> 3) & 0x7;
+       LARc[7]  = *c++ & 0x7;
+
+       Nc[0]  = (*c >> 1) & 0x7F;
+
+       bc[0]  = (*c++ & 0x1) << 1;
+       bc[0] |= (*c >> 7) & 0x1;
+
+       Mc[0]  = (*c >> 5) & 0x3;
+
+       xmaxc[0]  = (*c++ & 0x1F) << 1;
+       xmaxc[0] |= (*c >> 7) & 0x1;
+
+#undef xmc
+#define        xmc     (target + 12)
+
+       xmc[0]  = (*c >> 4) & 0x7;
+       xmc[1]  = (*c >> 1) & 0x7;
+       xmc[2]  = (*c++ & 0x1) << 2;
+       xmc[2] |= (*c >> 6) & 0x3;
+       xmc[3]  = (*c >> 3) & 0x7;
+       xmc[4]  = *c++ & 0x7;
+       xmc[5]  = (*c >> 5) & 0x7;
+       xmc[6]  = (*c >> 2) & 0x7;
+       xmc[7]  = (*c++ & 0x3) << 1;            /* 10 */
+       xmc[7] |= (*c >> 7) & 0x1;
+       xmc[8]  = (*c >> 4) & 0x7;
+       xmc[9]  = (*c >> 1) & 0x7;
+       xmc[10]  = (*c++ & 0x1) << 2;
+       xmc[10] |= (*c >> 6) & 0x3;
+       xmc[11]  = (*c >> 3) & 0x7;
+       xmc[12]  = *c++ & 0x7;
+
+       Nc[1]  = (*c >> 1) & 0x7F;
+
+       bc[1]  = (*c++ & 0x1) << 1;
+       bc[1] |= (*c >> 7) & 0x1;
+
+       Mc[1]  = (*c >> 5) & 0x3;
+
+       xmaxc[1]  = (*c++ & 0x1F) << 1;
+       xmaxc[1] |= (*c >> 7) & 0x1;
+
+#undef xmc
+#define        xmc     (target + 29 - 13)
+
+       xmc[13]  = (*c >> 4) & 0x7;
+       xmc[14]  = (*c >> 1) & 0x7;
+       xmc[15]  = (*c++ & 0x1) << 2;
+       xmc[15] |= (*c >> 6) & 0x3;
+       xmc[16]  = (*c >> 3) & 0x7;
+       xmc[17]  = *c++ & 0x7;
+       xmc[18]  = (*c >> 5) & 0x7;
+       xmc[19]  = (*c >> 2) & 0x7;
+       xmc[20]  = (*c++ & 0x3) << 1;
+       xmc[20] |= (*c >> 7) & 0x1;
+       xmc[21]  = (*c >> 4) & 0x7;
+       xmc[22]  = (*c >> 1) & 0x7;
+       xmc[23]  = (*c++ & 0x1) << 2;
+       xmc[23] |= (*c >> 6) & 0x3;
+       xmc[24]  = (*c >> 3) & 0x7;
+       xmc[25]  = *c++ & 0x7;
+
+       Nc[2]  = (*c >> 1) & 0x7F;
+
+       bc[2]  = (*c++ & 0x1) << 1;             /* 20 */
+       bc[2] |= (*c >> 7) & 0x1;
+
+       Mc[2]  = (*c >> 5) & 0x3;
+
+       xmaxc[2]  = (*c++ & 0x1F) << 1;
+       xmaxc[2] |= (*c >> 7) & 0x1;
+
+#undef xmc
+#define        xmc     (target + 46 - 26)
+
+       xmc[26]  = (*c >> 4) & 0x7;
+       xmc[27]  = (*c >> 1) & 0x7;
+       xmc[28]  = (*c++ & 0x1) << 2;
+       xmc[28] |= (*c >> 6) & 0x3;
+       xmc[29]  = (*c >> 3) & 0x7;
+       xmc[30]  = *c++ & 0x7;
+       xmc[31]  = (*c >> 5) & 0x7;
+       xmc[32]  = (*c >> 2) & 0x7;
+       xmc[33]  = (*c++ & 0x3) << 1;
+       xmc[33] |= (*c >> 7) & 0x1;
+       xmc[34]  = (*c >> 4) & 0x7;
+       xmc[35]  = (*c >> 1) & 0x7;
+       xmc[36]  = (*c++ & 0x1) << 2;
+       xmc[36] |= (*c >> 6) & 0x3;
+       xmc[37]  = (*c >> 3) & 0x7;
+       xmc[38]  = *c++ & 0x7;
+
+       Nc[3]  = (*c >> 1) & 0x7F;
+
+       bc[3]  = (*c++ & 0x1) << 1;
+       bc[3] |= (*c >> 7) & 0x1;
+
+       Mc[3]  = (*c >> 5) & 0x3;
+
+       xmaxc[3]  = (*c++ & 0x1F) << 1;
+       xmaxc[3] |= (*c >> 7) & 0x1;
+
+#undef xmc
+#define        xmc     (target + 63 - 39)
+
+       xmc[39]  = (*c >> 4) & 0x7;
+       xmc[40]  = (*c >> 1) & 0x7;
+       xmc[41]  = (*c++ & 0x1) << 2;
+       xmc[41] |= (*c >> 6) & 0x3;
+       xmc[42]  = (*c >> 3) & 0x7;
+       xmc[43]  = *c++ & 0x7;                  /* 30  */
+       xmc[44]  = (*c >> 5) & 0x7;
+       xmc[45]  = (*c >> 2) & 0x7;
+       xmc[46]  = (*c++ & 0x3) << 1;
+       xmc[46] |= (*c >> 7) & 0x1;
+       xmc[47]  = (*c >> 4) & 0x7;
+       xmc[48]  = (*c >> 1) & 0x7;
+       xmc[49]  = (*c++ & 0x1) << 2;
+       xmc[49] |= (*c >> 6) & 0x3;
+       xmc[50]  = (*c >> 3) & 0x7;
+       xmc[51]  = *c & 0x7;                    /* 33 */
+       }
+
+       return 0;
+}
diff --git a/libgsmfr/src/gsm_implode.c b/libgsmfr/src/gsm_implode.c
new file mode 100644 (file)
index 0000000..6c5672b
--- /dev/null
@@ -0,0 +1,521 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_implode.c,v 1.2 1996/07/02 14:32:43 jutta Exp jutta $ */
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+void gsm_implode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c)
+{
+       /*      variable        size    index
+
+               GSM_MAGIC       4       -
+
+               LARc[0]         6       0
+               LARc[1]         6       1
+               LARc[2]         5       2
+               LARc[3]         5       3
+               LARc[4]         4       4
+               LARc[5]         4       5
+               LARc[6]         3       6
+               LARc[7]         3       7
+
+               Nc[0]           7       8
+               bc[0]           2       9
+               Mc[0]           2       10
+               xmaxc[0]        6       11
+               xmc[0]          3       12
+               xmc[1]          3       13
+               xmc[2]          3       14
+               xmc[3]          3       15
+               xmc[4]          3       16
+               xmc[5]          3       17
+               xmc[6]          3       18
+               xmc[7]          3       19
+               xmc[8]          3       20
+               xmc[9]          3       21
+               xmc[10]         3       22
+               xmc[11]         3       23
+               xmc[12]         3       24
+
+               Nc[1]           7       25
+               bc[1]           2       26
+               Mc[1]           2       27
+               xmaxc[1]        6       28
+               xmc[13]         3       29
+               xmc[14]         3       30
+               xmc[15]         3       31
+               xmc[16]         3       32
+               xmc[17]         3       33
+               xmc[18]         3       34
+               xmc[19]         3       35
+               xmc[20]         3       36
+               xmc[21]         3       37
+               xmc[22]         3       38
+               xmc[23]         3       39
+               xmc[24]         3       40
+               xmc[25]         3       41
+
+               Nc[2]           7       42
+               bc[2]           2       43
+               Mc[2]           2       44
+               xmaxc[2]        6       45
+               xmc[26]         3       46
+               xmc[27]         3       47
+               xmc[28]         3       48
+               xmc[29]         3       49
+               xmc[30]         3       50
+               xmc[31]         3       51
+               xmc[32]         3       52
+               xmc[33]         3       53
+               xmc[34]         3       54
+               xmc[35]         3       55
+               xmc[36]         3       56
+               xmc[37]         3       57
+               xmc[38]         3       58
+
+               Nc[3]           7       59
+               bc[3]           2       60
+               Mc[3]           2       61
+               xmaxc[3]        6       62
+               xmc[39]         3       63
+               xmc[40]         3       64
+               xmc[41]         3       65
+               xmc[42]         3       66
+               xmc[43]         3       67
+               xmc[44]         3       68
+               xmc[45]         3       69
+               xmc[46]         3       70
+               xmc[47]         3       71
+               xmc[48]         3       72
+               xmc[49]         3       73
+               xmc[50]         3       74
+               xmc[51]         3       75
+       */
+
+       /*      There are 76 parameters per frame.  The first eight are
+        *      unique.  The remaining 68 are four identical subframes of
+        *      17 parameters each.  gsm_implode converts from a representation
+        *      of these parameters as values in one array of signed words
+        *      to the "packed" version of a GSM frame.
+        */
+
+#      define  LARc    source
+#      define  Nc      *((gsm_signal (*) [17])(source + 8))
+#      define  bc      *((gsm_signal (*) [17])(source + 9))
+#      define  Mc      *((gsm_signal (*) [17])(source + 10))
+#      define  xmaxc   *((gsm_signal (*) [17])(source + 11))
+
+#ifdef WAV49
+       if (s->wav_fmt) {
+
+               uword sr = 0;
+               if (s->frame_index) {
+                       sr = sr >> 6 | LARc[0] << 10;
+                       sr = sr >> 6 | LARc[1] << 10;
+                       *c++ = sr >> 4;
+                       sr = sr >> 5 | LARc[2] << 11;
+                       *c++ = sr >> 7;
+                       sr = sr >> 5 | LARc[3] << 11;
+                       sr = sr >> 4 | LARc[4] << 12;
+                       *c++ = sr >> 6;
+                       sr = sr >> 4 | LARc[5] << 12;
+                       sr = sr >> 3 | LARc[6] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | LARc[7] << 13;
+                       sr = sr >> 7 | Nc[0] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[0] << 14;
+                       sr = sr >> 2 | Mc[0] << 14;
+                       sr = sr >> 6 | xmaxc[0] << 10;
+                       *c++ = sr >> 3;
+#undef xmc
+#define        xmc     (source + 12)
+
+                       sr = sr >> 3 | xmc[0] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[1] << 13;
+                       sr = sr >> 3 | xmc[2] << 13;
+                       sr = sr >> 3 | xmc[3] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[4] << 13;
+                       sr = sr >> 3 | xmc[5] << 13;
+                       sr = sr >> 3 | xmc[6] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[7] << 13;
+                       sr = sr >> 3 | xmc[8] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[9] << 13;
+                       sr = sr >> 3 | xmc[10] << 13;
+                       sr = sr >> 3 | xmc[11] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[12] << 13;
+                       sr = sr >> 7 | Nc[1] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[1] << 14;
+                       sr = sr >> 2 | Mc[1] << 14;
+                       sr = sr >> 6 | xmaxc[1] << 10;
+                       *c++ = sr >> 3;
+#undef xmc
+#define        xmc     (source + 29 - 13)
+
+                       sr = sr >> 3 | xmc[13] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[14] << 13;
+                       sr = sr >> 3 | xmc[15] << 13;
+                       sr = sr >> 3 | xmc[16] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[17] << 13;
+                       sr = sr >> 3 | xmc[18] << 13;
+                       sr = sr >> 3 | xmc[19] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[20] << 13;
+                       sr = sr >> 3 | xmc[21] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[22] << 13;
+                       sr = sr >> 3 | xmc[23] << 13;
+                       sr = sr >> 3 | xmc[24] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[25] << 13;
+                       sr = sr >> 7 | Nc[2] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[2] << 14;
+                       sr = sr >> 2 | Mc[2] << 14;
+                       sr = sr >> 6 | xmaxc[2] << 10;
+                       *c++ = sr >> 3;
+#undef xmc
+#define        xmc     (source + 46 - 26)
+
+                       sr = sr >> 3 | xmc[26] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[27] << 13;
+                       sr = sr >> 3 | xmc[28] << 13;
+                       sr = sr >> 3 | xmc[29] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[30] << 13;
+                       sr = sr >> 3 | xmc[31] << 13;
+                       sr = sr >> 3 | xmc[32] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[33] << 13;
+                       sr = sr >> 3 | xmc[34] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[35] << 13;
+                       sr = sr >> 3 | xmc[36] << 13;
+                       sr = sr >> 3 | xmc[37] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[38] << 13;
+                       sr = sr >> 7 | Nc[3] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[3] << 14;
+                       sr = sr >> 2 | Mc[3] << 14;
+                       sr = sr >> 6 | xmaxc[3] << 10;
+                       *c++ = sr >> 3;
+#undef xmc
+#define        xmc     (source + 63 - 39)
+
+                       sr = sr >> 3 | xmc[39] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[40] << 13;
+                       sr = sr >> 3 | xmc[41] << 13;
+                       sr = sr >> 3 | xmc[42] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[43] << 13;
+                       sr = sr >> 3 | xmc[44] << 13;
+                       sr = sr >> 3 | xmc[45] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[46] << 13;
+                       sr = sr >> 3 | xmc[47] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[48] << 13;
+                       sr = sr >> 3 | xmc[49] << 13;
+                       sr = sr >> 3 | xmc[50] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[51] << 13;
+                       sr = sr >> 4;
+                       *c = sr >> 8;
+                       s->frame_chain = *c;
+               }
+               else {
+                       sr = sr >> 4 | s->frame_chain << 12;
+                       sr = sr >> 6 | LARc[0] << 10;
+                       *c++ = sr >> 6;
+                       sr = sr >> 6 | LARc[1] << 10;
+                       *c++ = sr >> 8;
+                       sr = sr >> 5 | LARc[2] << 11;
+                       sr = sr >> 5 | LARc[3] << 11;
+                       *c++ = sr >> 6;
+                       sr = sr >> 4 | LARc[4] << 12;
+                       sr = sr >> 4 | LARc[5] << 12;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | LARc[6] << 13;
+                       sr = sr >> 3 | LARc[7] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[0] << 9;
+                       sr = sr >> 2 | bc[0] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[0] << 14;
+                       sr = sr >> 6 | xmaxc[0] << 10;
+                       *c++ = sr >> 7;
+#undef xmc
+#define        xmc     (source + 12)
+
+                       sr = sr >> 3 | xmc[0] << 13;
+                       sr = sr >> 3 | xmc[1] << 13;
+                       sr = sr >> 3 | xmc[2] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[3] << 13;
+                       sr = sr >> 3 | xmc[4] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[5] << 13;
+                       sr = sr >> 3 | xmc[6] << 13;
+                       sr = sr >> 3 | xmc[7] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[8] << 13;
+                       sr = sr >> 3 | xmc[9] << 13;
+                       sr = sr >> 3 | xmc[10] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[11] << 13;
+                       sr = sr >> 3 | xmc[12] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[1] << 9;
+                       sr = sr >> 2 | bc[1] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[1] << 14;
+                       sr = sr >> 6 | xmaxc[1] << 10;
+                       *c++ = sr >> 7;
+#undef xmc
+#define        xmc     (source + 29 - 13)
+
+                       sr = sr >> 3 | xmc[13] << 13;
+                       sr = sr >> 3 | xmc[14] << 13;
+                       sr = sr >> 3 | xmc[15] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[16] << 13;
+                       sr = sr >> 3 | xmc[17] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[18] << 13;
+                       sr = sr >> 3 | xmc[19] << 13;
+                       sr = sr >> 3 | xmc[20] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[21] << 13;
+                       sr = sr >> 3 | xmc[22] << 13;
+                       sr = sr >> 3 | xmc[23] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[24] << 13;
+                       sr = sr >> 3 | xmc[25] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[2] << 9;
+                       sr = sr >> 2 | bc[2] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[2] << 14;
+                       sr = sr >> 6 | xmaxc[2] << 10;
+                       *c++ = sr >> 7;
+#undef xmc
+#define        xmc     (source + 46 - 26)
+
+                       sr = sr >> 3 | xmc[26] << 13;
+                       sr = sr >> 3 | xmc[27] << 13;
+                       sr = sr >> 3 | xmc[28] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[29] << 13;
+                       sr = sr >> 3 | xmc[30] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[31] << 13;
+                       sr = sr >> 3 | xmc[32] << 13;
+                       sr = sr >> 3 | xmc[33] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[34] << 13;
+                       sr = sr >> 3 | xmc[35] << 13;
+                       sr = sr >> 3 | xmc[36] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[37] << 13;
+                       sr = sr >> 3 | xmc[38] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[3] << 9;
+                       sr = sr >> 2 | bc[3] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[3] << 14;
+                       sr = sr >> 6 | xmaxc[3] << 10;
+                       *c++ = sr >> 7;
+#undef xmc
+#define        xmc     (source + 63 - 39)
+
+                       sr = sr >> 3 | xmc[39] << 13;
+                       sr = sr >> 3 | xmc[40] << 13;
+                       sr = sr >> 3 | xmc[41] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[42] << 13;
+                       sr = sr >> 3 | xmc[43] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[44] << 13;
+                       sr = sr >> 3 | xmc[45] << 13;
+                       sr = sr >> 3 | xmc[46] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[47] << 13;
+                       sr = sr >> 3 | xmc[48] << 13;
+                       sr = sr >> 3 | xmc[49] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[50] << 13;
+                       sr = sr >> 3 | xmc[51] << 13;
+                       *c++ = sr >> 8;
+               }
+       }
+       else
+#endif 
+       {
+
+               *c++ =   ((GSM_MAGIC & 0xF) << 4)               /* 1 */
+                      | ((LARc[0] >> 2) & 0xF);
+               *c++ =   ((LARc[0] & 0x3) << 6)
+                      | (LARc[1] & 0x3F);
+               *c++ =   ((LARc[2] & 0x1F) << 3)
+                      | ((LARc[3] >> 2) & 0x7);
+               *c++ =   ((LARc[3] & 0x3) << 6)
+                      | ((LARc[4] & 0xF) << 2)
+                      | ((LARc[5] >> 2) & 0x3);
+               *c++ =   ((LARc[5] & 0x3) << 6)
+                      | ((LARc[6] & 0x7) << 3)
+                      | (LARc[7] & 0x7);
+
+
+               *c++ =   ((Nc[0] & 0x7F) << 1)
+
+
+                      | ((bc[0] >> 1) & 0x1);
+               *c++ =   ((bc[0] & 0x1) << 7)
+
+
+                      | ((Mc[0] & 0x3) << 5)
+
+                      | ((xmaxc[0] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[0] & 0x1) << 7)
+
+#undef xmc
+#define        xmc     (source + 12)
+
+                      | ((xmc[0] & 0x7) << 4)
+                      | ((xmc[1] & 0x7) << 1)
+                      | ((xmc[2] >> 2) & 0x1);
+               *c++ =   ((xmc[2] & 0x3) << 6)
+                      | ((xmc[3] & 0x7) << 3)
+                      | (xmc[4] & 0x7);
+               *c++ =   ((xmc[5] & 0x7) << 5)                  /* 10 */
+                      | ((xmc[6] & 0x7) << 2)
+                      | ((xmc[7] >> 1) & 0x3);
+               *c++ =   ((xmc[7] & 0x1) << 7)
+                      | ((xmc[8] & 0x7) << 4)
+                      | ((xmc[9] & 0x7) << 1)
+                      | ((xmc[10] >> 2) & 0x1);
+               *c++ =   ((xmc[10] & 0x3) << 6)
+                      | ((xmc[11] & 0x7) << 3)
+                      | (xmc[12] & 0x7);
+
+
+               *c++ =   ((Nc[1] & 0x7F) << 1)
+
+
+                      | ((bc[1] >> 1) & 0x1);
+               *c++ =   ((bc[1] & 0x1) << 7)
+
+
+                      | ((Mc[1] & 0x3) << 5)
+
+
+                      | ((xmaxc[1] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[1] & 0x1) << 7)
+
+#undef xmc
+#define        xmc     (source + 29 - 13)
+
+                      | ((xmc[13] & 0x7) << 4)
+                      | ((xmc[14] & 0x7) << 1)
+                      | ((xmc[15] >> 2) & 0x1);
+               *c++ =   ((xmc[15] & 0x3) << 6)
+                      | ((xmc[16] & 0x7) << 3)
+                      | (xmc[17] & 0x7);
+               *c++ =   ((xmc[18] & 0x7) << 5)
+                      | ((xmc[19] & 0x7) << 2)
+                      | ((xmc[20] >> 1) & 0x3);
+               *c++ =   ((xmc[20] & 0x1) << 7)
+                      | ((xmc[21] & 0x7) << 4)
+                      | ((xmc[22] & 0x7) << 1)
+                      | ((xmc[23] >> 2) & 0x1);
+               *c++ =   ((xmc[23] & 0x3) << 6)
+                      | ((xmc[24] & 0x7) << 3)
+                      | (xmc[25] & 0x7);
+
+
+               *c++ =   ((Nc[2] & 0x7F) << 1)                  /* 20 */
+
+
+                      | ((bc[2] >> 1) & 0x1);
+               *c++ =   ((bc[2] & 0x1) << 7)
+
+
+                      | ((Mc[2] & 0x3) << 5)
+
+
+                      | ((xmaxc[2] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[2] & 0x1) << 7)
+
+#undef xmc
+#define        xmc     (source + 46 - 26)
+
+                      | ((xmc[26] & 0x7) << 4)
+                      | ((xmc[27] & 0x7) << 1)
+                      | ((xmc[28] >> 2) & 0x1);
+               *c++ =   ((xmc[28] & 0x3) << 6)
+                      | ((xmc[29] & 0x7) << 3)
+                      | (xmc[30] & 0x7);
+               *c++ =   ((xmc[31] & 0x7) << 5)
+                      | ((xmc[32] & 0x7) << 2)
+                      | ((xmc[33] >> 1) & 0x3);
+               *c++ =   ((xmc[33] & 0x1) << 7)
+                      | ((xmc[34] & 0x7) << 4)
+                      | ((xmc[35] & 0x7) << 1)
+                      | ((xmc[36] >> 2) & 0x1);
+               *c++ =   ((xmc[36] & 0x3) << 6)
+                      | ((xmc[37] & 0x7) << 3)
+                      | (xmc[38] & 0x7);
+
+
+               *c++ =   ((Nc[3] & 0x7F) << 1)
+
+
+                      | ((bc[3] >> 1) & 0x1);
+               *c++ =   ((bc[3] & 0x1) << 7)
+
+
+                      | ((Mc[3] & 0x3) << 5)
+
+
+                      | ((xmaxc[3] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[3] & 0x1) << 7)
+
+#undef xmc
+#define        xmc     (source + 63 - 39)
+
+                      | ((xmc[39] & 0x7) << 4)
+                      | ((xmc[40] & 0x7) << 1)
+                      | ((xmc[41] >> 2) & 0x1);
+               *c++ =   ((xmc[41] & 0x3) << 6)                 /* 30 */
+                      | ((xmc[42] & 0x7) << 3)
+                      | (xmc[43] & 0x7);
+               *c++ =   ((xmc[44] & 0x7) << 5)
+                      | ((xmc[45] & 0x7) << 2)
+                      | ((xmc[46] >> 1) & 0x3);
+               *c++ =   ((xmc[46] & 0x1) << 7)
+                      | ((xmc[47] & 0x7) << 4)
+                      | ((xmc[48] & 0x7) << 1)
+                      | ((xmc[49] >> 2) & 0x1);
+               *c++ =   ((xmc[49] & 0x3) << 6)
+                      | ((xmc[50] & 0x7) << 3)
+                      | (xmc[51] & 0x7);
+       }
+}
diff --git a/libgsmfr/src/gsm_option.c b/libgsmfr/src/gsm_option.c
new file mode 100644 (file)
index 0000000..274b7b1
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_option.c,v 1.3 1996/07/02 09:59:05 jutta Exp $ */
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_option P3((r, opt, val), gsm r, int opt, int * val)
+{
+       int     result = -1;
+
+       switch (opt) {
+       case GSM_OPT_LTP_CUT:
+#ifdef         LTP_CUT
+               result = r->ltp_cut;
+               if (val) r->ltp_cut = *val;
+#endif
+               break;
+
+       case GSM_OPT_VERBOSE:
+#ifndef        NDEBUG
+               result = r->verbose;
+               if (val) r->verbose = *val;
+#endif
+               break;
+
+       case GSM_OPT_FAST:
+
+#if    defined(FAST) && defined(USE_FLOAT_MUL)
+               result = r->fast;
+               if (val) r->fast = !!*val;
+#endif
+               break;
+
+       case GSM_OPT_FRAME_CHAIN:
+
+#ifdef WAV49
+               result = r->frame_chain;
+               if (val) r->frame_chain = *val;
+#endif
+               break;
+
+       case GSM_OPT_FRAME_INDEX:
+
+#ifdef WAV49
+               result = r->frame_index;
+               if (val) r->frame_index = *val;
+#endif
+               break;
+
+       case GSM_OPT_WAV49:
+
+#ifdef WAV49 
+               result = r->wav_fmt;
+               if (val) r->wav_fmt = !!*val;
+#endif
+               break;
+
+       default:
+               break;
+       }
+       return result;
+}
diff --git a/libgsmfr/src/gsm_print.c b/libgsmfr/src/gsm_print.c
new file mode 100644 (file)
index 0000000..47f753b
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_print.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */
+
+#include       <stdio.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_print P3((f, s, c), FILE * f, gsm s, gsm_byte * c)
+{
+       word    LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
+
+       /* GSM_MAGIC  = (*c >> 4) & 0xF; */
+
+       if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
+
+       LARc[0]  = (*c++ & 0xF) << 2;           /* 1 */
+       LARc[0] |= (*c >> 6) & 0x3;
+       LARc[1]  = *c++ & 0x3F;
+       LARc[2]  = (*c >> 3) & 0x1F;
+       LARc[3]  = (*c++ & 0x7) << 2;
+       LARc[3] |= (*c >> 6) & 0x3;
+       LARc[4]  = (*c >> 2) & 0xF;
+       LARc[5]  = (*c++ & 0x3) << 2;
+       LARc[5] |= (*c >> 6) & 0x3;
+       LARc[6]  = (*c >> 3) & 0x7;
+       LARc[7]  = *c++ & 0x7;
+
+
+       Nc[0]  = (*c >> 1) & 0x7F;
+       bc[0]  = (*c++ & 0x1) << 1;
+       bc[0] |= (*c >> 7) & 0x1;
+       Mc[0]  = (*c >> 5) & 0x3;
+       xmaxc[0]  = (*c++ & 0x1F) << 1;
+       xmaxc[0] |= (*c >> 7) & 0x1;
+       xmc[0]  = (*c >> 4) & 0x7;
+       xmc[1]  = (*c >> 1) & 0x7;
+       xmc[2]  = (*c++ & 0x1) << 2;
+       xmc[2] |= (*c >> 6) & 0x3;
+       xmc[3]  = (*c >> 3) & 0x7;
+       xmc[4]  = *c++ & 0x7;
+       xmc[5]  = (*c >> 5) & 0x7;
+       xmc[6]  = (*c >> 2) & 0x7;
+       xmc[7]  = (*c++ & 0x3) << 1;            /* 10 */
+       xmc[7] |= (*c >> 7) & 0x1;
+       xmc[8]  = (*c >> 4) & 0x7;
+       xmc[9]  = (*c >> 1) & 0x7;
+       xmc[10]  = (*c++ & 0x1) << 2;
+       xmc[10] |= (*c >> 6) & 0x3;
+       xmc[11]  = (*c >> 3) & 0x7;
+       xmc[12]  = *c++ & 0x7;
+
+       Nc[1]  = (*c >> 1) & 0x7F;
+       bc[1]  = (*c++ & 0x1) << 1;
+       bc[1] |= (*c >> 7) & 0x1;
+       Mc[1]  = (*c >> 5) & 0x3;
+       xmaxc[1]  = (*c++ & 0x1F) << 1;
+       xmaxc[1] |= (*c >> 7) & 0x1;
+       xmc[13]  = (*c >> 4) & 0x7;
+       xmc[14]  = (*c >> 1) & 0x7;
+       xmc[15]  = (*c++ & 0x1) << 2;
+       xmc[15] |= (*c >> 6) & 0x3;
+       xmc[16]  = (*c >> 3) & 0x7;
+       xmc[17]  = *c++ & 0x7;
+       xmc[18]  = (*c >> 5) & 0x7;
+       xmc[19]  = (*c >> 2) & 0x7;
+       xmc[20]  = (*c++ & 0x3) << 1;
+       xmc[20] |= (*c >> 7) & 0x1;
+       xmc[21]  = (*c >> 4) & 0x7;
+       xmc[22]  = (*c >> 1) & 0x7;
+       xmc[23]  = (*c++ & 0x1) << 2;
+       xmc[23] |= (*c >> 6) & 0x3;
+       xmc[24]  = (*c >> 3) & 0x7;
+       xmc[25]  = *c++ & 0x7;
+
+
+       Nc[2]  = (*c >> 1) & 0x7F;
+       bc[2]  = (*c++ & 0x1) << 1;             /* 20 */
+       bc[2] |= (*c >> 7) & 0x1;
+       Mc[2]  = (*c >> 5) & 0x3;
+       xmaxc[2]  = (*c++ & 0x1F) << 1;
+       xmaxc[2] |= (*c >> 7) & 0x1;
+       xmc[26]  = (*c >> 4) & 0x7;
+       xmc[27]  = (*c >> 1) & 0x7;
+       xmc[28]  = (*c++ & 0x1) << 2;
+       xmc[28] |= (*c >> 6) & 0x3;
+       xmc[29]  = (*c >> 3) & 0x7;
+       xmc[30]  = *c++ & 0x7;
+       xmc[31]  = (*c >> 5) & 0x7;
+       xmc[32]  = (*c >> 2) & 0x7;
+       xmc[33]  = (*c++ & 0x3) << 1;
+       xmc[33] |= (*c >> 7) & 0x1;
+       xmc[34]  = (*c >> 4) & 0x7;
+       xmc[35]  = (*c >> 1) & 0x7;
+       xmc[36]  = (*c++ & 0x1) << 2;
+       xmc[36] |= (*c >> 6) & 0x3;
+       xmc[37]  = (*c >> 3) & 0x7;
+       xmc[38]  = *c++ & 0x7;
+
+       Nc[3]  = (*c >> 1) & 0x7F;
+       bc[3]  = (*c++ & 0x1) << 1;
+       bc[3] |= (*c >> 7) & 0x1;
+       Mc[3]  = (*c >> 5) & 0x3;
+       xmaxc[3]  = (*c++ & 0x1F) << 1;
+       xmaxc[3] |= (*c >> 7) & 0x1;
+
+       xmc[39]  = (*c >> 4) & 0x7;
+       xmc[40]  = (*c >> 1) & 0x7;
+       xmc[41]  = (*c++ & 0x1) << 2;
+       xmc[41] |= (*c >> 6) & 0x3;
+       xmc[42]  = (*c >> 3) & 0x7;
+       xmc[43]  = *c++ & 0x7;                  /* 30  */
+       xmc[44]  = (*c >> 5) & 0x7;
+       xmc[45]  = (*c >> 2) & 0x7;
+       xmc[46]  = (*c++ & 0x3) << 1;
+       xmc[46] |= (*c >> 7) & 0x1;
+       xmc[47]  = (*c >> 4) & 0x7;
+       xmc[48]  = (*c >> 1) & 0x7;
+       xmc[49]  = (*c++ & 0x1) << 2;
+       xmc[49] |= (*c >> 6) & 0x3;
+       xmc[50]  = (*c >> 3) & 0x7;
+       xmc[51]  = *c & 0x7;                    /* 33 */
+
+       fprintf(f,
+             "LARc:\t%2.2d  %2.2d  %2.2d  %2.2d  %2.2d  %2.2d  %2.2d  %2.2d\n",
+              LARc[0],LARc[1],LARc[2],LARc[3],LARc[4],LARc[5],LARc[6],LARc[7]);
+
+       fprintf(f, "#1:         Nc %4.4d    bc %d    Mc %d    xmaxc %d\n",
+               Nc[0], bc[0], Mc[0], xmaxc[0]);
+       fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+               xmc[0],xmc[1],xmc[2],xmc[3],xmc[4],xmc[5],xmc[6],
+               xmc[7],xmc[8],xmc[9],xmc[10],xmc[11],xmc[12] );
+
+       fprintf(f, "#2:         Nc %4.4d    bc %d    Mc %d    xmaxc %d\n",
+               Nc[1], bc[1], Mc[1], xmaxc[1]);
+       fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+               xmc[13+0],xmc[13+1],xmc[13+2],xmc[13+3],xmc[13+4],xmc[13+5],
+               xmc[13+6], xmc[13+7],xmc[13+8],xmc[13+9],xmc[13+10],xmc[13+11],
+               xmc[13+12] );
+
+       fprintf(f, "#3:         Nc %4.4d    bc %d    Mc %d    xmaxc %d\n",
+               Nc[2], bc[2], Mc[2], xmaxc[2]);
+       fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+               xmc[26+0],xmc[26+1],xmc[26+2],xmc[26+3],xmc[26+4],xmc[26+5],
+               xmc[26+6], xmc[26+7],xmc[26+8],xmc[26+9],xmc[26+10],xmc[26+11],
+               xmc[26+12] );
+
+       fprintf(f, "#4:         Nc %4.4d    bc %d    Mc %d    xmaxc %d\n",
+               Nc[3], bc[3], Mc[3], xmaxc[3]);
+       fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+               xmc[39+0],xmc[39+1],xmc[39+2],xmc[39+3],xmc[39+4],xmc[39+5],
+               xmc[39+6], xmc[39+7],xmc[39+8],xmc[39+9],xmc[39+10],xmc[39+11],
+               xmc[39+12] );
+
+       return 0;
+}
diff --git a/libgsmfr/src/long_term.c b/libgsmfr/src/long_term.c
new file mode 100644 (file)
index 0000000..b2d2d3f
--- /dev/null
@@ -0,0 +1,949 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/long_term.c,v 1.6 1996/07/02 12:33:19 jutta Exp $ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+/*
+ *  4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION
+ */
+
+
+/*
+ * This module computes the LTP gain (bc) and the LTP lag (Nc)
+ * for the long term analysis filter.   This is done by calculating a
+ * maximum of the cross-correlation function between the current
+ * sub-segment short term residual signal d[0..39] (output of
+ * the short term analysis filter; for simplification the index
+ * of this array begins at 0 and ends at 39 for each sub-segment of the
+ * RPE-LTP analysis) and the previous reconstructed short term
+ * residual signal dp[ -120 .. -1 ].  A dynamic scaling must be
+ * performed to avoid overflow.
+ */
+
+ /* The next procedure exists in six versions.  First two integer
+  * version (if USE_FLOAT_MUL is not defined); then four floating
+  * point versions, twice with proper scaling (USE_FLOAT_MUL defined),
+  * once without (USE_FLOAT_MUL and FAST defined, and fast run-time
+  * option used).  Every pair has first a Cut version (see the -C
+  * option to toast or the LTP_CUT option to gsm_option()), then the
+  * uncut one.  (For a detailed explanation of why this is altogether
+  * a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered
+  * Harmful''.)
+  */
+
+#ifndef  USE_FLOAT_MUL
+
+#ifdef LTP_CUT
+
+static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out),
+
+       struct gsm_state * st,
+
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       word            Nc, bc;
+       word            wt[40];
+
+       longword        L_result;
+       longword        L_max, L_power;
+       word            R, S, dmax, scal, best_k;
+       word            ltp_cut;
+
+       register word   temp, wt_k;
+
+       /*  Search of the optimum scaling of d[0..39].
+        */
+       dmax = 0;
+       for (k = 0; k <= 39; k++) {
+               temp = d[k];
+               temp = GSM_ABS( temp );
+               if (temp > dmax) {
+                       dmax = temp;
+                       best_k = k;
+               }
+       }
+       temp = 0;
+       if (dmax == 0) scal = 0;
+       else {
+               assert(dmax > 0);
+               temp = gsm_norm( (longword)dmax << 16 );
+       }
+       if (temp > 6) scal = 0;
+       else scal = 6 - temp;
+       assert(scal >= 0);
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+       wt_k  = SASR(d[best_k], scal);
+
+       for (lambda = 40; lambda <= 120; lambda++) {
+               L_result = (longword)wt_k * dp[best_k - lambda];
+               if (L_result > L_max) {
+                       Nc    = lambda;
+                       L_max = L_result;
+               }
+       }
+       *Nc_out = Nc;
+       L_max <<= 1;
+
+       /*  Rescaling of L_max
+        */
+       assert(scal <= 100 && scal >= -100);
+       L_max = L_max >> (6 - scal);    /* sub(6, scal) */
+
+       assert( Nc <= 120 && Nc >= 40);
+
+       /*   Compute the power of the reconstructed short term residual
+        *   signal dp[..]
+        */
+       L_power = 0;
+       for (k = 0; k <= 39; k++) {
+
+               register longword L_temp;
+
+               L_temp   = SASR( dp[k - Nc], 3 );
+               L_power += L_temp * L_temp;
+       }
+       L_power <<= 1;  /* from L_MULT */
+
+       /*  Normalization of L_max and L_power
+        */
+
+       if (L_max <= 0)  {
+               *bc_out = 0;
+               return;
+       }
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       temp = gsm_norm( L_power );
+
+       R = SASR( L_max   << temp, 16 );
+       S = SASR( L_power << temp, 16 );
+
+       /*  Coding of the LTP gain
+        */
+
+       /*  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+       *bc_out = bc;
+}
+
+#endif         /* LTP_CUT */
+
+static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       word            Nc, bc;
+       word            wt[40];
+
+       longword        L_max, L_power;
+       word            R, S, dmax, scal;
+       register word   temp;
+
+       /*  Search of the optimum scaling of d[0..39].
+        */
+       dmax = 0;
+
+       for (k = 0; k <= 39; k++) {
+               temp = d[k];
+               temp = GSM_ABS( temp );
+               if (temp > dmax) dmax = temp;
+       }
+
+       temp = 0;
+       if (dmax == 0) scal = 0;
+       else {
+               assert(dmax > 0);
+               temp = gsm_norm( (longword)dmax << 16 );
+       }
+
+       if (temp > 6) scal = 0;
+       else scal = 6 - temp;
+
+       assert(scal >= 0);
+
+       /*  Initialization of a working array wt
+        */
+
+       for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal );
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+
+       for (lambda = 40; lambda <= 120; lambda++) {
+
+# undef STEP
+#              define STEP(k)  (longword)wt[k] * dp[k - lambda]
+
+               register longword L_result;
+
+               L_result  = STEP(0)  ; L_result += STEP(1) ;
+               L_result += STEP(2)  ; L_result += STEP(3) ;
+               L_result += STEP(4)  ; L_result += STEP(5)  ;
+               L_result += STEP(6)  ; L_result += STEP(7)  ;
+               L_result += STEP(8)  ; L_result += STEP(9)  ;
+               L_result += STEP(10) ; L_result += STEP(11) ;
+               L_result += STEP(12) ; L_result += STEP(13) ;
+               L_result += STEP(14) ; L_result += STEP(15) ;
+               L_result += STEP(16) ; L_result += STEP(17) ;
+               L_result += STEP(18) ; L_result += STEP(19) ;
+               L_result += STEP(20) ; L_result += STEP(21) ;
+               L_result += STEP(22) ; L_result += STEP(23) ;
+               L_result += STEP(24) ; L_result += STEP(25) ;
+               L_result += STEP(26) ; L_result += STEP(27) ;
+               L_result += STEP(28) ; L_result += STEP(29) ;
+               L_result += STEP(30) ; L_result += STEP(31) ;
+               L_result += STEP(32) ; L_result += STEP(33) ;
+               L_result += STEP(34) ; L_result += STEP(35) ;
+               L_result += STEP(36) ; L_result += STEP(37) ;
+               L_result += STEP(38) ; L_result += STEP(39) ;
+
+               if (L_result > L_max) {
+
+                       Nc    = lambda;
+                       L_max = L_result;
+               }
+       }
+
+       *Nc_out = Nc;
+
+       L_max <<= 1;
+
+       /*  Rescaling of L_max
+        */
+       assert(scal <= 100 && scal >=  -100);
+       L_max = L_max >> (6 - scal);    /* sub(6, scal) */
+
+       assert( Nc <= 120 && Nc >= 40);
+
+       /*   Compute the power of the reconstructed short term residual
+        *   signal dp[..]
+        */
+       L_power = 0;
+       for (k = 0; k <= 39; k++) {
+
+               register longword L_temp;
+
+               L_temp   = SASR( dp[k - Nc], 3 );
+               L_power += L_temp * L_temp;
+       }
+       L_power <<= 1;  /* from L_MULT */
+
+       /*  Normalization of L_max and L_power
+        */
+
+       if (L_max <= 0)  {
+               *bc_out = 0;
+               return;
+       }
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       temp = gsm_norm( L_power );
+
+       R = SASR( L_max   << temp, 16 );
+       S = SASR( L_power << temp, 16 );
+
+       /*  Coding of the LTP gain
+        */
+
+       /*  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+       *bc_out = bc;
+}
+
+#else  /* USE_FLOAT_MUL */
+
+#ifdef LTP_CUT
+
+static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out),
+       struct gsm_state * st,          /*              IN      */
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       word            Nc, bc;
+       word            ltp_cut;
+
+       float           wt_float[40];
+       float           dp_float_base[120], * dp_float = dp_float_base + 120;
+
+       longword        L_max, L_power;
+       word            R, S, dmax, scal;
+       register word   temp;
+
+       /*  Search of the optimum scaling of d[0..39].
+        */
+       dmax = 0;
+
+       for (k = 0; k <= 39; k++) {
+               temp = d[k];
+               temp = GSM_ABS( temp );
+               if (temp > dmax) dmax = temp;
+       }
+
+       temp = 0;
+       if (dmax == 0) scal = 0;
+       else {
+               assert(dmax > 0);
+               temp = gsm_norm( (longword)dmax << 16 );
+       }
+
+       if (temp > 6) scal = 0;
+       else scal = 6 - temp;
+
+       assert(scal >= 0);
+       ltp_cut = (longword)SASR(dmax, scal) * st->ltp_cut / 100; 
+
+
+       /*  Initialization of a working array wt
+        */
+
+       for (k = 0; k < 40; k++) {
+               register word w = SASR( d[k], scal );
+               if (w < 0 ? w > -ltp_cut : w < ltp_cut) {
+                       wt_float[k] = 0.0;
+               }
+               else {
+                       wt_float[k] =  w;
+               }
+       }
+       for (k = -120; k <  0; k++) dp_float[k] =  dp[k];
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+
+       for (lambda = 40; lambda <= 120; lambda += 9) {
+
+               /*  Calculate L_result for l = lambda .. lambda + 9.
+                */
+               register float *lp = dp_float - lambda;
+
+               register float  W;
+               register float  a = lp[-8], b = lp[-7], c = lp[-6],
+                               d = lp[-5], e = lp[-4], f = lp[-3],
+                               g = lp[-2], h = lp[-1];
+               register float  E; 
+               register float  S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
+                               S5 = 0, S6 = 0, S7 = 0, S8 = 0;
+
+#              undef STEP
+#              define  STEP(K, a, b, c, d, e, f, g, h) \
+                       if ((W = wt_float[K]) != 0.0) { \
+                       E = W * a; S8 += E;             \
+                       E = W * b; S7 += E;             \
+                       E = W * c; S6 += E;             \
+                       E = W * d; S5 += E;             \
+                       E = W * e; S4 += E;             \
+                       E = W * f; S3 += E;             \
+                       E = W * g; S2 += E;             \
+                       E = W * h; S1 += E;             \
+                       a  = lp[K];                     \
+                       E = W * a; S0 += E; } else (a = lp[K])
+
+#              define  STEP_A(K)       STEP(K, a, b, c, d, e, f, g, h)
+#              define  STEP_B(K)       STEP(K, b, c, d, e, f, g, h, a)
+#              define  STEP_C(K)       STEP(K, c, d, e, f, g, h, a, b)
+#              define  STEP_D(K)       STEP(K, d, e, f, g, h, a, b, c)
+#              define  STEP_E(K)       STEP(K, e, f, g, h, a, b, c, d)
+#              define  STEP_F(K)       STEP(K, f, g, h, a, b, c, d, e)
+#              define  STEP_G(K)       STEP(K, g, h, a, b, c, d, e, f)
+#              define  STEP_H(K)       STEP(K, h, a, b, c, d, e, f, g)
+
+               STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
+               STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
+
+               STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
+               STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
+
+               STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
+               STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
+
+               STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
+               STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
+
+               STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
+               STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
+
+               if (S0 > L_max) { L_max = S0; Nc = lambda;     }
+               if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
+               if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
+               if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
+               if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
+               if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
+               if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
+               if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
+               if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
+
+       }
+       *Nc_out = Nc;
+
+       L_max <<= 1;
+
+       /*  Rescaling of L_max
+        */
+       assert(scal <= 100 && scal >=  -100);
+       L_max = L_max >> (6 - scal);    /* sub(6, scal) */
+
+       assert( Nc <= 120 && Nc >= 40);
+
+       /*   Compute the power of the reconstructed short term residual
+        *   signal dp[..]
+        */
+       L_power = 0;
+       for (k = 0; k <= 39; k++) {
+
+               register longword L_temp;
+
+               L_temp   = SASR( dp[k - Nc], 3 );
+               L_power += L_temp * L_temp;
+       }
+       L_power <<= 1;  /* from L_MULT */
+
+       /*  Normalization of L_max and L_power
+        */
+
+       if (L_max <= 0)  {
+               *bc_out = 0;
+               return;
+       }
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       temp = gsm_norm( L_power );
+
+       R = SASR( L_max   << temp, 16 );
+       S = SASR( L_power << temp, 16 );
+
+       /*  Coding of the LTP gain
+        */
+
+       /*  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+       *bc_out = bc;
+}
+
+#endif /* LTP_CUT */
+
+static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       word            Nc, bc;
+
+       float           wt_float[40];
+       float           dp_float_base[120], * dp_float = dp_float_base + 120;
+
+       longword        L_max, L_power;
+       word            R, S, dmax, scal;
+       register word   temp;
+
+       /*  Search of the optimum scaling of d[0..39].
+        */
+       dmax = 0;
+
+       for (k = 0; k <= 39; k++) {
+               temp = d[k];
+               temp = GSM_ABS( temp );
+               if (temp > dmax) dmax = temp;
+       }
+
+       temp = 0;
+       if (dmax == 0) scal = 0;
+       else {
+               assert(dmax > 0);
+               temp = gsm_norm( (longword)dmax << 16 );
+       }
+
+       if (temp > 6) scal = 0;
+       else scal = 6 - temp;
+
+       assert(scal >= 0);
+
+       /*  Initialization of a working array wt
+        */
+
+       for (k =    0; k < 40; k++) wt_float[k] =  SASR( d[k], scal );
+       for (k = -120; k <  0; k++) dp_float[k] =  dp[k];
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+
+       for (lambda = 40; lambda <= 120; lambda += 9) {
+
+               /*  Calculate L_result for l = lambda .. lambda + 9.
+                */
+               register float *lp = dp_float - lambda;
+
+               register float  W;
+               register float  a = lp[-8], b = lp[-7], c = lp[-6],
+                               d = lp[-5], e = lp[-4], f = lp[-3],
+                               g = lp[-2], h = lp[-1];
+               register float  E; 
+               register float  S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
+                               S5 = 0, S6 = 0, S7 = 0, S8 = 0;
+
+#              undef STEP
+#              define  STEP(K, a, b, c, d, e, f, g, h) \
+                       W = wt_float[K];                \
+                       E = W * a; S8 += E;             \
+                       E = W * b; S7 += E;             \
+                       E = W * c; S6 += E;             \
+                       E = W * d; S5 += E;             \
+                       E = W * e; S4 += E;             \
+                       E = W * f; S3 += E;             \
+                       E = W * g; S2 += E;             \
+                       E = W * h; S1 += E;             \
+                       a  = lp[K];                     \
+                       E = W * a; S0 += E
+
+#              define  STEP_A(K)       STEP(K, a, b, c, d, e, f, g, h)
+#              define  STEP_B(K)       STEP(K, b, c, d, e, f, g, h, a)
+#              define  STEP_C(K)       STEP(K, c, d, e, f, g, h, a, b)
+#              define  STEP_D(K)       STEP(K, d, e, f, g, h, a, b, c)
+#              define  STEP_E(K)       STEP(K, e, f, g, h, a, b, c, d)
+#              define  STEP_F(K)       STEP(K, f, g, h, a, b, c, d, e)
+#              define  STEP_G(K)       STEP(K, g, h, a, b, c, d, e, f)
+#              define  STEP_H(K)       STEP(K, h, a, b, c, d, e, f, g)
+
+               STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
+               STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
+
+               STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
+               STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
+
+               STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
+               STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
+
+               STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
+               STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
+
+               STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
+               STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
+
+               if (S0 > L_max) { L_max = S0; Nc = lambda;     }
+               if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
+               if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
+               if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
+               if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
+               if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
+               if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
+               if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
+               if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
+       }
+       *Nc_out = Nc;
+
+       L_max <<= 1;
+
+       /*  Rescaling of L_max
+        */
+       assert(scal <= 100 && scal >=  -100);
+       L_max = L_max >> (6 - scal);    /* sub(6, scal) */
+
+       assert( Nc <= 120 && Nc >= 40);
+
+       /*   Compute the power of the reconstructed short term residual
+        *   signal dp[..]
+        */
+       L_power = 0;
+       for (k = 0; k <= 39; k++) {
+
+               register longword L_temp;
+
+               L_temp   = SASR( dp[k - Nc], 3 );
+               L_power += L_temp * L_temp;
+       }
+       L_power <<= 1;  /* from L_MULT */
+
+       /*  Normalization of L_max and L_power
+        */
+
+       if (L_max <= 0)  {
+               *bc_out = 0;
+               return;
+       }
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       temp = gsm_norm( L_power );
+
+       R = SASR( L_max   << temp, 16 );
+       S = SASR( L_power << temp, 16 );
+
+       /*  Coding of the LTP gain
+        */
+
+       /*  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+       *bc_out = bc;
+}
+
+#ifdef FAST
+#ifdef LTP_CUT
+
+static void Cut_Fast_Calculation_of_the_LTP_parameters P5((st,
+                                                       d,dp,bc_out,Nc_out),
+       struct gsm_state * st,          /*              IN      */
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       register float  wt_float;
+       word            Nc, bc;
+       word            wt_max, best_k, ltp_cut;
+
+       float           dp_float_base[120], * dp_float = dp_float_base + 120;
+
+       register float  L_result, L_max, L_power;
+
+       wt_max = 0;
+
+       for (k = 0; k < 40; ++k) {
+               if      ( d[k] > wt_max) wt_max =  d[best_k = k];
+               else if (-d[k] > wt_max) wt_max = -d[best_k = k];
+       }
+
+       assert(wt_max >= 0);
+       wt_float = (float)wt_max;
+
+       for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+
+       for (lambda = 40; lambda <= 120; lambda++) {
+               L_result = wt_float * dp_float[best_k - lambda];
+               if (L_result > L_max) {
+                       Nc    = lambda;
+                       L_max = L_result;
+               }
+       }
+
+       *Nc_out = Nc;
+       if (L_max <= 0.)  {
+               *bc_out = 0;
+               return;
+       }
+
+       /*  Compute the power of the reconstructed short term residual
+        *  signal dp[..]
+        */
+       dp_float -= Nc;
+       L_power = 0;
+       for (k = 0; k < 40; ++k) {
+               register float f = dp_float[k];
+               L_power += f * f;
+       }
+
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       /*  Coding of the LTP gain
+        *  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       lambda = L_max / L_power * 32768.;
+       for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
+       *bc_out = bc;
+}
+
+#endif /* LTP_CUT */
+
+static void Fast_Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       word            Nc, bc;
+
+       float           wt_float[40];
+       float           dp_float_base[120], * dp_float = dp_float_base + 120;
+
+       register float  L_max, L_power;
+
+       for (k = 0; k < 40; ++k) wt_float[k] = (float)d[k];
+       for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+
+       for (lambda = 40; lambda <= 120; lambda += 9) {
+
+               /*  Calculate L_result for l = lambda .. lambda + 9.
+                */
+               register float *lp = dp_float - lambda;
+
+               register float  W;
+               register float  a = lp[-8], b = lp[-7], c = lp[-6],
+                               d = lp[-5], e = lp[-4], f = lp[-3],
+                               g = lp[-2], h = lp[-1];
+               register float  E; 
+               register float  S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
+                               S5 = 0, S6 = 0, S7 = 0, S8 = 0;
+
+#              undef STEP
+#              define  STEP(K, a, b, c, d, e, f, g, h) \
+                       W = wt_float[K];                \
+                       E = W * a; S8 += E;             \
+                       E = W * b; S7 += E;             \
+                       E = W * c; S6 += E;             \
+                       E = W * d; S5 += E;             \
+                       E = W * e; S4 += E;             \
+                       E = W * f; S3 += E;             \
+                       E = W * g; S2 += E;             \
+                       E = W * h; S1 += E;             \
+                       a  = lp[K];                     \
+                       E = W * a; S0 += E
+
+#              define  STEP_A(K)       STEP(K, a, b, c, d, e, f, g, h)
+#              define  STEP_B(K)       STEP(K, b, c, d, e, f, g, h, a)
+#              define  STEP_C(K)       STEP(K, c, d, e, f, g, h, a, b)
+#              define  STEP_D(K)       STEP(K, d, e, f, g, h, a, b, c)
+#              define  STEP_E(K)       STEP(K, e, f, g, h, a, b, c, d)
+#              define  STEP_F(K)       STEP(K, f, g, h, a, b, c, d, e)
+#              define  STEP_G(K)       STEP(K, g, h, a, b, c, d, e, f)
+#              define  STEP_H(K)       STEP(K, h, a, b, c, d, e, f, g)
+
+               STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
+               STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
+
+               STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
+               STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
+
+               STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
+               STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
+
+               STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
+               STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
+
+               STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
+               STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
+
+               if (S0 > L_max) { L_max = S0; Nc = lambda;     }
+               if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
+               if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
+               if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
+               if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
+               if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
+               if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
+               if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
+               if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
+       }
+       *Nc_out = Nc;
+
+       if (L_max <= 0.)  {
+               *bc_out = 0;
+               return;
+       }
+
+       /*  Compute the power of the reconstructed short term residual
+        *  signal dp[..]
+        */
+       dp_float -= Nc;
+       L_power = 0;
+       for (k = 0; k < 40; ++k) {
+               register float f = dp_float[k];
+               L_power += f * f;
+       }
+
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       /*  Coding of the LTP gain
+        *  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       lambda = L_max / L_power * 32768.;
+       for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
+       *bc_out = bc;
+}
+
+#endif /* FAST          */
+#endif /* USE_FLOAT_MUL */
+
+
+/* 4.2.12 */
+
+static void Long_term_analysis_filtering P6((bc,Nc,dp,d,dpp,e),
+       word            bc,     /*                                      IN  */
+       word            Nc,     /*                                      IN  */
+       register word   * dp,   /* previous d   [-120..-1]              IN  */
+       register word   * d,    /* d            [0..39]                 IN  */
+       register word   * dpp,  /* estimate     [0..39]                 OUT */
+       register word   * e     /* long term res. signal [0..39]        OUT */
+)
+/*
+ *  In this part, we have to decode the bc parameter to compute
+ *  the samples of the estimate dpp[0..39].  The decoding of bc needs the
+ *  use of table 4.3b.  The long term residual signal e[0..39]
+ *  is then calculated to be fed to the RPE encoding section.
+ */
+{
+       register int      k;
+       register longword ltmp;
+
+#      undef STEP
+#      define STEP(BP)                                 \
+       for (k = 0; k <= 39; k++) {                     \
+               dpp[k]  = GSM_MULT_R( BP, dp[k - Nc]);  \
+               e[k]    = GSM_SUB( d[k], dpp[k] );      \
+       }
+
+       switch (bc) {
+       case 0: STEP(  3277 ); break;
+       case 1: STEP( 11469 ); break;
+       case 2: STEP( 21299 ); break;
+       case 3: STEP( 32767 ); break; 
+       }
+}
+
+void Gsm_Long_Term_Predictor P7((S,d,dp,e,dpp,Nc,bc),  /* 4x for 160 samples */
+
+       struct gsm_state        * S,
+
+       word    * d,    /* [0..39]   residual signal    IN      */
+       word    * dp,   /* [-120..-1] d'                IN      */
+
+       word    * e,    /* [0..39]                      OUT     */
+       word    * dpp,  /* [0..39]                      OUT     */
+       word    * Nc,   /* correlation lag              OUT     */
+       word    * bc    /* gain factor                  OUT     */
+)
+{
+       assert( d  ); assert( dp ); assert( e  );
+       assert( dpp); assert( Nc ); assert( bc );
+
+#if defined(FAST) && defined(USE_FLOAT_MUL)
+       if (S->fast) 
+#if   defined (LTP_CUT)
+               if (S->ltp_cut)
+                       Cut_Fast_Calculation_of_the_LTP_parameters(S,
+                               d, dp, bc, Nc);
+               else
+#endif /* LTP_CUT */
+                       Fast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc );
+       else 
+#endif /* FAST & USE_FLOAT_MUL */
+#ifdef LTP_CUT
+               if (S->ltp_cut)
+                       Cut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc);
+               else
+#endif
+                       Calculation_of_the_LTP_parameters(d, dp, bc, Nc);
+
+       Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e );
+}
+
+/* 4.3.2 */
+void Gsm_Long_Term_Synthesis_Filtering P5((S,Ncr,bcr,erp,drp),
+       struct gsm_state        * S,
+
+       word                    Ncr,
+       word                    bcr,
+       register word           * erp,     /* [0..39]                    IN */
+       register word           * drp      /* [-120..-1] IN, [-120..40] OUT */
+)
+/*
+ *  This procedure uses the bcr and Ncr parameter to realize the
+ *  long term synthesis filtering.  The decoding of bcr needs
+ *  table 4.3b.
+ */
+{
+       register longword       ltmp;   /* for ADD */
+       register int            k;
+       word                    brp, drpp, Nr;
+
+       /*  Check the limits of Nr.
+        */
+       Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr;
+       S->nrp = Nr;
+       assert(Nr >= 40 && Nr <= 120);
+
+       /*  Decoding of the LTP gain bcr
+        */
+       brp = gsm_QLB[ bcr ];
+
+       /*  Computation of the reconstructed short term residual 
+        *  signal drp[0..39]
+        */
+       assert(brp != MIN_WORD);
+
+       for (k = 0; k <= 39; k++) {
+               drpp   = GSM_MULT_R( brp, drp[ k - Nr ] );
+               drp[k] = GSM_ADD( erp[k], drpp );
+       }
+
+       /*
+        *  Update of the reconstructed short term residual signal
+        *  drp[ -1..-120 ]
+        */
+
+       for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ];
+}
diff --git a/libgsmfr/src/lpc.c b/libgsmfr/src/lpc.c
new file mode 100644 (file)
index 0000000..21b9faf
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/lpc.c,v 1.5 1994/12/30 23:14:54 jutta Exp $ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+#undef P
+
+/*
+ *  4.2.4 .. 4.2.7 LPC ANALYSIS SECTION
+ */
+
+/* 4.2.4 */
+
+
+static void Autocorrelation P2((s, L_ACF),
+       word     * s,           /* [0..159]     IN/OUT  */
+       longword * L_ACF)       /* [0..8]       OUT     */
+/*
+ *  The goal is to compute the array L_ACF[k].  The signal s[i] must
+ *  be scaled in order to avoid an overflow situation.
+ */
+{
+       register int    k, i;
+
+       word            temp, smax, scalauto;
+
+#ifdef USE_FLOAT_MUL
+       float           float_s[160];
+#endif
+
+       /*  Dynamic scaling of the array  s[0..159]
+        */
+
+       /*  Search for the maximum.
+        */
+       smax = 0;
+       for (k = 0; k <= 159; k++) {
+               temp = GSM_ABS( s[k] );
+               if (temp > smax) smax = temp;
+       }
+
+       /*  Computation of the scaling factor.
+        */
+       if (smax == 0) scalauto = 0;
+       else {
+               assert(smax > 0);
+               scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */
+       }
+
+       /*  Scaling of the array s[0...159]
+        */
+
+       if (scalauto > 0) {
+
+# ifdef USE_FLOAT_MUL
+#   define SCALE(n)    \
+       case n: for (k = 0; k <= 159; k++) \
+                       float_s[k] = (float)    \
+                               (s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\
+               break;
+# else 
+#   define SCALE(n)    \
+       case n: for (k = 0; k <= 159; k++) \
+                       s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\
+               break;
+# endif /* USE_FLOAT_MUL */
+
+               switch (scalauto) {
+               SCALE(1)
+               SCALE(2)
+               SCALE(3)
+               SCALE(4)
+               }
+# undef        SCALE
+       }
+# ifdef        USE_FLOAT_MUL
+       else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k];
+# endif
+
+       /*  Compute the L_ACF[..].
+        */
+       {
+# ifdef        USE_FLOAT_MUL
+               register float * sp = float_s;
+               register float   sl = *sp;
+
+#              define STEP(k)   L_ACF[k] += (longword)(sl * sp[ -(k) ]);
+# else
+               word  * sp = s;
+               word    sl = *sp;
+
+#              define STEP(k)   L_ACF[k] += ((longword)sl * sp[ -(k) ]);
+# endif
+
+#      define NEXTI     sl = *++sp
+
+
+       for (k = 9; k--; L_ACF[k] = 0) ;
+
+       STEP (0);
+       NEXTI;
+       STEP(0); STEP(1);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2); STEP(3);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2); STEP(3); STEP(4);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7);
+
+       for (i = 8; i <= 159; i++) {
+
+               NEXTI;
+
+               STEP(0);
+               STEP(1); STEP(2); STEP(3); STEP(4);
+               STEP(5); STEP(6); STEP(7); STEP(8);
+       }
+
+       for (k = 9; k--; L_ACF[k] <<= 1) ; 
+
+       }
+       /*   Rescaling of the array s[0..159]
+        */
+       if (scalauto > 0) {
+               assert(scalauto <= 4); 
+               for (k = 160; k--; *s++ <<= scalauto) ;
+       }
+}
+
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+
+static void Fast_Autocorrelation P2((s, L_ACF),
+       word * s,               /* [0..159]     IN/OUT  */
+       longword * L_ACF)       /* [0..8]       OUT     */
+{
+       register int    k, i;
+       float f_L_ACF[9];
+       float scale;
+
+       float          s_f[160];
+       register float *sf = s_f;
+
+       for (i = 0; i < 160; ++i) sf[i] = s[i];
+       for (k = 0; k <= 8; k++) {
+               register float L_temp2 = 0;
+               register float *sfl = sf - k;
+               for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i];
+               f_L_ACF[k] = L_temp2;
+       }
+       scale = MAX_LONGWORD / f_L_ACF[0];
+
+       for (k = 0; k <= 8; k++) {
+               L_ACF[k] = f_L_ACF[k] * scale;
+       }
+}
+#endif /* defined (USE_FLOAT_MUL) && defined (FAST) */
+
+/* 4.2.5 */
+
+static void Reflection_coefficients P2( (L_ACF, r),
+       longword        * L_ACF,                /* 0...8        IN      */
+       register word   * r                     /* 0...7        OUT     */
+)
+{
+       register int    i, m, n;
+       register word   temp;
+       register longword ltmp;
+       word            ACF[9]; /* 0..8 */
+       word            P[  9]; /* 0..8 */
+       word            K[  9]; /* 2..8 */
+
+       /*  Schur recursion with 16 bits arithmetic.
+        */
+
+       if (L_ACF[0] == 0) {
+               for (i = 8; i--; *r++ = 0) ;
+               return;
+       }
+
+       assert( L_ACF[0] != 0 );
+       temp = gsm_norm( L_ACF[0] );
+
+       assert(temp >= 0 && temp < 32);
+
+       /* ? overflow ? */
+       for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 );
+
+       /*   Initialize array P[..] and K[..] for the recursion.
+        */
+
+       for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ];
+       for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ];
+
+       /*   Compute reflection coefficients
+        */
+       for (n = 1; n <= 8; n++, r++) {
+
+               temp = P[1];
+               temp = GSM_ABS(temp);
+               if (P[0] < temp) {
+