ref: 55f8f1eaab58a32d29a804559b45b50ab10070b6
dir: /src/gsm.c/
#if defined(HAVE_LIBGSM)
/*
* 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
*
* More information on this format can be obtained from
* http://www.cs.tu-berlin.de/~jutta/toast.html
*
* Source is 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
*
* July 19, 1998 - Chris Bagwell (cbagwell@sprynet.com)
* Added GSM support to SOX from patches floating around with the help
* of Dima Barsky (ess2db@ee.surrey.ac.uk).
*/
#include "st.h"
#include "gsm.h"
/* Private data */
struct gsmpriv {
gsm handle;
gsm_signal sample[160];
int index;
};
void
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;
}
void
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.
*/
LONG
gsmread(ft, buf, samp)
ft_t ft;
long *buf, samp;
{
int bytes;
int done = 0;
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 = fread( frame, 1, sizeof(frame), ft->fp );
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;
}
int
gsmwrite(ft, buf, samp)
ft_t ft;
long *buf, samp;
{
int done = 0;
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 (fwrite(frame, 1, sizeof(frame), ft->fp) != sizeof(frame))
fail("write error");
p->index = 0;
}
return done;
}
void
gsmstopread(ft)
ft_t ft;
{
struct gsmpriv *p = (struct gsmpriv *) ft->priv;
gsm_destroy(p->handle);
}
void
gsmstopwrite(ft)
ft_t ft;
{
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 (fwrite(frame, 1, sizeof(frame), ft->fp) != sizeof(frame))
fail("write error");
}
gsm_destroy(p->handle);
}
#endif /* HAVE_LIBGSM */