From: Andrew Pam <avatar@aus.xanadu.com>
Subject: sox 12 patches to add GSM support
Date: Sun, 19 Feb 1995 14:30:36 +1100 (EST)
Organization: Xanadu Australia

diff -Nu sox12/Makefile.unx soxnew/Makefile.unx
--- sox12/Makefile.unx	Tue Dec  6 02:34:26 1994
+++ soxnew/Makefile.unx	Sun Feb 19 13:55:21 1995
@@ -43,7 +43,7 @@
 
 FOBJ= raw.o voc.o au.o sf.o aiff.o hcom.o 8svx.o sndrtool.o wav.o \
 	smp.o sbdsp.o auto.o cdr.o dat.o wve.o maud.o \
-	g711.o g72x.o g721.o g723_24.o g723_40.o
+	g711.o g72x.o g721.o g723_24.o g723_40.o gsm.o
 
 EOBJ= copy.o avg.o pred.o stat.o vibro.o echo.o rate.o band.o lowp.o \
 	highp.o reverse.o dyn.o cut.o map.o split.o pick.o mask.o \
@@ -156,7 +156,7 @@
 all: sox
 
 sox: sox.o $(SOUNDLIB)
-	$(CC) $(CFLAGS) -o sox sox.o $(SOUNDLIB) -lm
+	$(CC) $(CFLAGS) -o sox sox.o $(SOUNDLIB) -lm -lgsm
 
 $(SOUNDLIB): $(LIBOBJS)
 	$(RM) $(SOUNDLIB)
diff -Nu sox12/gsm.c soxnew/gsm.c
--- sox12/gsm.c	Thu Jan  1 10:00:00 1970
+++ soxnew/gsm.c	Sun Feb 19 13:51:36 1995
@@ -0,0 +1,149 @@
+/*
+ * Copyright 1991, 1992, 1993 Guido van Rossum And Sundry Contributors.
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained. 
+ * Guido van Rossum And Sundry Contributors are not responsible for 
+ * the consequences of using this software.
+ */
+
+/*
+ * GSM 06.10 courtesy Communications and Operating Systems Research Group,
+ * Technische Universitaet Berlin
+ * Available from ftp://ftp.cs.tu-berlin.de/pub/local/kbs/tubmik/gsm
+ * Written 26 Jan 1995 by Andrew Pam
+ * Portions Copyright (c) 1995 Serious Cybernetics
+ */
+
+#include "st.h"
+#include "gsm.h"
+
+/* Private data */
+struct gsmpriv {
+	gsm		handle;
+	gsm_signal	sample[160];
+	int		index;
+};
+
+gsmstartread(ft) 
+ft_t ft;
+{
+	struct gsmpriv *p = (struct gsmpriv *) ft->priv;
+
+	/* Sanity check */
+	if (sizeof(struct gsmpriv) > PRIVSIZE)
+		fail(
+"struct gsmpriv is too big (%d); change PRIVSIZE in st.h and recompile sox",
+		     sizeof(struct gsmpriv));
+
+	ft->info.style = GSM;
+	ft->info.size = BYTE;
+	if (!ft->info.rate)
+		ft->info.rate = 8000;
+	p->handle = gsm_create();
+	if (!p->handle)
+		fail("unable to create GSM stream");
+	p->index = 0;
+}
+
+gsmstartwrite(ft)
+ft_t ft;
+{
+	struct gsmpriv *p = (struct gsmpriv *) ft->priv;
+
+	ft->info.style = GSM;
+	ft->info.size = BYTE;
+	if (!ft->info.rate)
+		ft->info.rate = 8000;
+	p->handle = gsm_create();
+	if (!p->handle)
+		fail("unable to create GSM stream");
+	p->index = 0;
+}
+
+/*
+ * Read up to len samples from file.
+ * Convert to signed longs.
+ * Place in buf[].
+ * Return number of samples read.
+ */
+
+gsmread(ft, buf, samp)
+ft_t ft;
+long *buf, samp;
+{
+	int bytes;
+	int done = 0;
+	int handle = fileno(ft->fp);
+	gsm_frame	frame;
+	struct gsmpriv *p = (struct gsmpriv *) ft->priv;
+
+	while (p->index && (p->index < 160) && (done < samp))
+		buf[done++] = LEFT(p->sample[p->index++], 16);
+
+	while (done < samp)
+	{
+		p->index = 0;
+		bytes = read(handle, frame, sizeof(frame));
+		if (bytes <= 0)
+			return done;
+		if (bytes < sizeof(frame))
+			fail("invalid frame size: %d bytes", bytes);
+		if (gsm_decode(p->handle, frame, p->sample) < 0)
+			fail("error during GSM decode");
+		while ((p->index < 160) && (done < samp))
+			buf[done++] = LEFT(p->sample[p->index++], 16);
+	}
+
+	return done;
+}
+
+gsmwrite(ft, buf, samp)
+ft_t ft;
+long *buf, samp;
+{
+	int done = 0;
+	int handle = fileno(ft->fp);
+	gsm_frame	frame;
+	struct gsmpriv *p = (struct gsmpriv *) ft->priv;
+
+	while (done < samp)
+	{
+		while ((p->index < 160) && (done < samp))
+			p->sample[p->index++] = RIGHT(buf[done++], 16);
+		if (p->index < 160)
+			return done;
+		gsm_encode(p->handle, p->sample, frame);
+		if (write(handle, frame, sizeof(frame)) != sizeof(frame))
+			fail("write error");
+		p->index = 0;
+	}
+
+	return done;
+}
+
+
+gsmstopread(ft)
+ft_t ft;
+{
+	struct gsmpriv *p = (struct gsmpriv *) ft->priv;
+
+	gsm_destroy(p->handle);
+}
+
+gsmstopwrite(ft)
+ft_t ft;
+{
+	int handle = fileno(ft->fp);
+	gsm_frame	frame;
+	struct gsmpriv *p = (struct gsmpriv *) ft->priv;
+
+	if (p->index)
+	{
+		while (p->index < 160)
+			p->sample[p->index++] = 0;
+		gsm_encode(p->handle, p->sample, frame);
+		if (write(handle, frame, sizeof(frame)) != sizeof(frame))
+			fail("write error");
+	}
+	gsm_destroy(p->handle);
+}
diff -Nu sox12/handlers.c soxnew/handlers.c
--- sox12/handlers.c	Mon Dec  5 02:54:51 1994
+++ soxnew/handlers.c	Wed Feb  8 16:09:14 1995
@@ -61,7 +61,6 @@
 extern wvestartread();
 extern wvestartwrite(), wveread(), wvewrite(), wvestopwrite();
 
-
 char *aiffnames[] = {
 	"aiff",
 	"aif",
@@ -140,7 +139,6 @@
 extern ulstartread();
 extern ulstartwrite();
 
-
 char *alnames[] = {
 	"al",
 	(char *) 0
@@ -148,6 +146,12 @@
 extern alstartread();
 extern alstartwrite();
 
+char *gsmnames[] = {
+	"gsm",
+	(char *) 0
+};
+extern gsmstartread(), gsmread(), gsmstopread();
+extern gsmstartwrite(), gsmwrite(), gsmstopwrite();
 
 char *sfnames[] = {
 	"sf",
@@ -250,6 +254,9 @@
 	{alnames, FILE_STEREO,
 		alstartread, rawread, nothing, 	/* a-law byte raw */
 		alstartwrite, rawwrite, nothing},	
+	{gsmnames, 0,
+		gsmstartread, gsmread, gsmstopread,	/* GSM 06.10 lossy */
+		gsmstartwrite, gsmwrite, gsmstopwrite},
 	{aiffnames, FILE_STEREO,
 		aiffstartread, aiffread, aiffstopread,    /* SGI/Apple AIFF */
 		aiffstartwrite, aiffwrite, aiffstopwrite},
diff -Nu sox12/misc.c soxnew/misc.c
--- sox12/misc.c	Thu Aug 18 06:10:15 1994
+++ soxnew/misc.c	Wed Feb  8 17:46:46 1995
@@ -32,7 +32,8 @@
 	"unsigned",
 	"signed (2's complement)",
 	"u-law",
-	"a-law"
+	"a-law",
+	"GSM"
 };
 
 char readerr[] = "Premature EOF while reading sample file.";
diff -Nu sox12/st.h soxnew/st.h
--- sox12/st.h	Thu Sep  1 14:04:19 1994
+++ soxnew/st.h	Wed Feb  8 18:14:45 1995
@@ -101,7 +101,7 @@
  *  Format information for input and output files.
  */
 
-#define	PRIVSIZE	100
+#define	PRIVSIZE	330
 
 #define NLOOPS		8
 
@@ -140,6 +140,7 @@
 #define SIGN2		2	/* signed linear 2's comp: Mac */
 #define	ULAW		3	/* U-law signed logs: US telephony, SPARC */
 #define ALAW		4	/* A-law signed logs: non-US telephony */
+#define	GSM		5	/* GSM 06.10 33-byte frames: lossy compression */
 
 IMPORT char *sizes[], *styles[];
 
-- 
Andrew Pam                                      avatar@aus.xanadu.com
Manager, Serious Cybernetics                    avatar@jolt.mpx.com.au
Coordinator, Xanadu Australia                   <http://www.aus.xanadu.com/>
P.O. Box 409, Canterbury VIC 3126 Australia     gopher gopher.aus.xanadu.com
