dect
/
asterisk
Archived
13
0
Fork 0

Version 0.1.1 from FTP

git-svn-id: http://svn.digium.com/svn/asterisk/trunk@139 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
markster 1999-12-16 13:44:30 +00:00
parent 70f08a7afb
commit 509765aef5
13 changed files with 1750 additions and 68 deletions

6
BUGS
View File

@ -2,8 +2,10 @@
these bugs are in asterisk, and sometimes they relate to the products
that asterisk uses.
* The MP3 decoder is completely broken
* The translator API may introduce warble in the case of going in both
directions, but I haven't verified that. The trouble should only enter
in the case of mismatched frame lengths.
* In general Asterisk is a very new program, and there are liable to be
many bugs yet to be discovered, so if you think you've found one, please
be sure to report it.

View File

@ -3,7 +3,7 @@
*
* QuickNet Internet Phone Jack Channel
*
* Copyright (C) 1999, Adtran Inc. and Linux Support Services, LLC
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
@ -60,7 +60,7 @@ static pthread_mutex_t monlock = PTHREAD_MUTEX_INITIALIZER;
which are not currently in use. */
static pthread_t monitor_thread = -1;
static int restart_monitor();
static int restart_monitor(void);
/* The private structures of the Phone Jack channels are linked for
selecting outgoing channels */
@ -129,7 +129,8 @@ static int ixj_call(struct ast_channel *ast, char *dest, int timeout)
}
/* When we call, it just works, really, there's no destination... Just
ring the phone and wait for someone to answer */
ast_log(LOG_DEBUG, "Ringing %s on %s (%d)\n", dest, ast->name, ast->fd);
if (option_debug)
ast_log(LOG_DEBUG, "Ringing %s on %s (%d)\n", dest, ast->name, ast->fd);
ioctl(p->fd, IXJCTL_RING_START);
ast->state = AST_STATE_RINGING;
return 0;
@ -139,7 +140,8 @@ static int ixj_hangup(struct ast_channel *ast)
{
struct ixj_pvt *p;
p = ast->pvt->pvt;
ast_log(LOG_DEBUG, "ixj_hangup(%s)\n", ast->name);
if (option_debug)
ast_log(LOG_DEBUG, "ixj_hangup(%s)\n", ast->name);
if (!ast->pvt->pvt) {
ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
return 0;
@ -217,7 +219,8 @@ static int ixj_setup(struct ast_channel *ast)
static int ixj_answer(struct ast_channel *ast)
{
ixj_setup(ast);
ast_log(LOG_DEBUG, "ixj_answer(%s)\n", ast->name);
if (option_debug)
ast_log(LOG_DEBUG, "ixj_answer(%s)\n", ast->name);
ast->rings = 0;
ast->state = AST_STATE_UP;
return 0;
@ -287,6 +290,14 @@ static struct ast_frame *ixj_read(struct ast_channel *ast)
res = read(p->fd, p->buf, IXJ_MAX_BUF);
ast->blocking = 0;
if (res < 0) {
#if 0
if (errno == EAGAIN) {
ast_log(LOG_WARNING, "Null frame received\n");
p->fr.frametype = AST_FRAME_NULL;
p->fr.subclass = 0;
return &p->fr;
}
#endif
ast_log(LOG_WARNING, "Error reading: %s\n", strerror(errno));
return NULL;
}
@ -486,6 +497,10 @@ static void ixj_check_exception(struct ixj_pvt *i)
ixj_new(i, AST_STATE_UP);
/* No need to restart monitor, we are the monitor */
if (i->owner) {
pthread_mutex_lock(&usecnt_lock);
usecnt--;
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
ixj_setup(i->owner);
}
} else if (ast_exists_extension(NULL, "default", i->ext, 1)) {
@ -494,10 +509,16 @@ static void ixj_check_exception(struct ixj_pvt *i)
strncpy(i->context, "default", sizeof(i->context));
ixj_new(i, AST_STATE_UP);
if (i->owner) {
pthread_mutex_lock(&usecnt_lock);
usecnt--;
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
ixj_setup(i->owner);
}
} else if ((strlen(i->ext) >= ast_pbx_longest_extension(i->context)) &&
(strlen(i->ext) >= ast_pbx_longest_extension("default"))) {
if (option_debug)
ast_log(LOG_DEBUG, "%s is too long\n", i->ext);
/* It's not a valid extension, give a busy signal */
ioctl(i->fd, IXJCTL_BUSY);
}
@ -512,18 +533,23 @@ static void ixj_check_exception(struct ixj_pvt *i)
if (i->mode == MODE_IMMEDIATE) {
ixj_new(i, AST_STATE_RING);
} else if (i->mode == MODE_DIALTONE) {
#if 0
/* XXX Bug in the Phone jack, you can't detect DTMF when playing a tone XXX */
ioctl(i->fd, IXJCTL_DIALTONE);
#else
pthread_mutex_lock(&usecnt_lock);
usecnt++;
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
/* Play the dialtone */
i->dialtone++;
ioctl(i->fd, IXJCTL_PLAY_STOP);
ioctl(i->fd, IXJCTL_PLAY_CODEC, ULAW);
ioctl(i->fd, IXJCTL_PLAY_START);
#endif
}
} else {
if (i->dialtone) {
pthread_mutex_lock(&usecnt_lock);
usecnt--;
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
}
memset(i->ext, 0, sizeof(i->ext));
ioctl(i->fd, IXJCTL_CPT_STOP);
ioctl(i->fd, IXJCTL_PLAY_STOP);
@ -690,11 +716,13 @@ static int restart_monitor()
return 0;
}
struct ixj_pvt *mkif(char *iface, int mode)
static struct ixj_pvt *mkif(char *iface, int mode)
{
/* Make a ixj_pvt structure for this interface */
struct ixj_pvt *tmp;
#if 0
int flags;
#endif
tmp = malloc(sizeof(struct ixj_pvt));
if (tmp) {
@ -709,8 +737,10 @@ struct ixj_pvt *mkif(char *iface, int mode)
ioctl(tmp->fd, IXJCTL_RING_STOP);
ioctl(tmp->fd, IXJCTL_CPT_STOP);
tmp->mode = mode;
#if 0
flags = fcntl(tmp->fd, F_GETFL);
fcntl(tmp->fd, F_SETFL, flags | O_NONBLOCK);
#endif
tmp->owner = NULL;
tmp->lastformat = -1;
tmp->lastinput = -1;

View File

@ -3,7 +3,7 @@
*
* Implementation of Voice over Frame Relay, Adtran Style
*
* Copyright (C) 1999, Adtran Inc. and Linux Support Services, LLC
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
@ -55,7 +55,7 @@ static pthread_mutex_t monlock = PTHREAD_MUTEX_INITIALIZER;
which are not currently in use. */
static pthread_t monitor_thread = -1;
static int restart_monitor();
static int restart_monitor(void);
/* The private structures of the Adtran VoFR channels are linked for
selecting outgoing channels */
@ -558,6 +558,9 @@ static struct ast_frame *vofr_read(struct ast_channel *ast)
fr->subclass = 0;
break;
}
case VOFR_SIGNAL_RING:
ast->rings++;
break;
case VOFR_SIGNAL_UNKNOWN:
switch(vh->data[1]) {
case 0x1:
@ -783,7 +786,21 @@ static int vofr_mini_packet(struct vofr_pvt *i, struct vofr_hdr *pkt, int len)
switch(pkt->data[0]) {
case VOFR_SIGNAL_RING:
/* If we get a RING, we definitely want to start a new thread */
vofr_new(i, AST_STATE_RING);
if (!i->owner)
vofr_new(i, AST_STATE_RING);
else
ast_log(LOG_WARNING, "Got a ring, but there's an owner?\n");
break;
case VOFR_SIGNAL_OFF_HOOK:
/* Network termination, go off hook */
#if 0
ast_log(LOG_DEBUG, "Off hook\n");
#endif
vofr_xmit_signal(i, 0x10, 2);
if (!i->owner)
vofr_new(i, AST_STATE_UP);
else
ast_log(LOG_WARNING, "Got an offhook, but there's an owner?\n");
break;
case VOFR_SIGNAL_ON_HOOK:
break;
@ -896,7 +913,7 @@ static void *do_monitor(void *data)
}
static int restart_monitor()
static int restart_monitor(void)
{
/* If we're supposed to be stopped -- stay stopped */
if (monitor_thread == -2)
@ -926,7 +943,7 @@ static int restart_monitor()
return 0;
}
struct vofr_pvt *mkif(char *type, char *iface)
static struct vofr_pvt *mkif(char *type, char *iface)
{
/* Make a vofr_pvt structure for this interface */
struct vofr_pvt *tmp;

37
codecs/mp3/Makefile Executable file
View File

@ -0,0 +1,37 @@
#
# LMC section
CFLAGS+= -I../include -Iinclude -O6 -funroll-loops -finline-functions -Wall -Wno-missing-prototypes -Wno-missing-declarations -g
RANLIB=ranlib
# the XING decoder objs and dependencies:
# This is kinda nasty, since there's C, C++, and asm, oh my!
# of course, each needs different compilation methods. grr.
XINGOBJX86 = src/x86gas.o
XINGOBJS = src/cdct.o src/cupl3.o \
src/hwin.o src/iup.o src/l3init.o \
src/msis.o src/wavep.o src/csbt.o \
src/cwinm.o src/icdct.o src/mdct.o \
src/uph.o src/cup.o src/dec8.o \
src/isbt.o src/l3dq.o src/mhead.o \
src/upsf.o src/iwinm.o
LIBMP3=libmp3.a
ARFLAGS=cr
XINGLMCOBJC += $(shell if uname -m | grep -q i.86; then echo src/x86gas.o; fi)
#assembly lang code, if we need it
XINGLMCOBJ = $(XINGOBJS)
all: $(LIBMP3)
$(LIBMP3): $(XINGOBJS)
$(AR) $(ARFLAGS) $(LIBMP3) $(XINGLMCOBJ)
$(RANLIB) $(LIBMP3)
clean:
rm -f $(XINGOBJS)
rm -f $(LIBMP3)

View File

@ -3,7 +3,7 @@
*
* Old-style G.723 frame/timestamp format.
*
* Copyright (C) 1999, Adtran Inc. and Linux Support Services, LLC
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
@ -285,7 +285,7 @@ static int g723_write(struct ast_filestream *fs, struct ast_frame *f)
return 0;
}
char *g723_getcomment(struct ast_filestream *s)
static char *g723_getcomment(struct ast_filestream *s)
{
return NULL;
}

298
formats/format_gsm.c Executable file
View File

@ -0,0 +1,298 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Save to raw, headerless GSM data.
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/channel.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/sched.h>
#include <asterisk/module.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <endian.h>
/* Some Ideas for this code came from makegsme.c by Jeffery Chilton */
/* Portions of the conversion code are by guido@sienanet.it */
struct ast_filestream {
void *reserved[AST_RESERVED_POINTERS];
/* Believe it or not, we must decode/recode to account for the
weird MS format */
/* This is what a filestream means to us */
int fd; /* Descriptor */
struct ast_channel *owner;
struct ast_frame fr; /* Frame information */
char waste[AST_FRIENDLY_OFFSET]; /* Buffer for sending frames, etc */
char empty; /* Empty character */
unsigned char gsm[33]; /* Two Real GSM Frames */
int lasttimeout;
struct timeval last;
int adj;
struct ast_filestream *next;
};
static struct ast_filestream *glist = NULL;
static pthread_mutex_t gsm_lock = PTHREAD_MUTEX_INITIALIZER;
static int glistcnt = 0;
static char *name = "gsm";
static char *desc = "Raw GSM data";
static char *exts = "gsm";
static struct ast_filestream *gsm_open(int fd)
{
/* We don't have any header to read or anything really, but
if we did, it would go here. We also might want to check
and be sure it's a valid file. */
struct ast_filestream *tmp;
if ((tmp = malloc(sizeof(struct ast_filestream)))) {
memset(tmp, 0, sizeof(struct ast_filestream));
if (pthread_mutex_lock(&gsm_lock)) {
ast_log(LOG_WARNING, "Unable to lock gsm list\n");
free(tmp);
return NULL;
}
tmp->next = glist;
glist = tmp;
tmp->fd = fd;
tmp->owner = NULL;
tmp->fr.data = tmp->gsm;
tmp->fr.frametype = AST_FRAME_VOICE;
tmp->fr.subclass = AST_FORMAT_GSM;
/* datalen will vary for each frame */
tmp->fr.src = name;
tmp->fr.mallocd = 0;
tmp->lasttimeout = -1;
glistcnt++;
pthread_mutex_unlock(&gsm_lock);
ast_update_use_count();
}
return tmp;
}
static struct ast_filestream *gsm_rewrite(int fd, char *comment)
{
/* We don't have any header to read or anything really, but
if we did, it would go here. We also might want to check
and be sure it's a valid file. */
struct ast_filestream *tmp;
if ((tmp = malloc(sizeof(struct ast_filestream)))) {
memset(tmp, 0, sizeof(struct ast_filestream));
if (pthread_mutex_lock(&gsm_lock)) {
ast_log(LOG_WARNING, "Unable to lock gsm list\n");
free(tmp);
return NULL;
}
tmp->next = glist;
glist = tmp;
tmp->fd = fd;
tmp->owner = NULL;
tmp->lasttimeout = -1;
glistcnt++;
pthread_mutex_unlock(&gsm_lock);
ast_update_use_count();
} else
ast_log(LOG_WARNING, "Out of memory\n");
return tmp;
}
static struct ast_frame *gsm_read(struct ast_filestream *s)
{
return NULL;
}
static void gsm_close(struct ast_filestream *s)
{
struct ast_filestream *tmp, *tmpl = NULL;
if (pthread_mutex_lock(&gsm_lock)) {
ast_log(LOG_WARNING, "Unable to lock gsm list\n");
return;
}
tmp = glist;
while(tmp) {
if (tmp == s) {
if (tmpl)
tmpl->next = tmp->next;
else
glist = tmp->next;
break;
}
tmpl = tmp;
tmp = tmp->next;
}
glistcnt--;
if (s->owner) {
s->owner->stream = NULL;
if (s->owner->streamid > -1)
ast_sched_del(s->owner->sched, s->owner->streamid);
s->owner->streamid = -1;
}
pthread_mutex_unlock(&gsm_lock);
ast_update_use_count();
if (!tmp)
ast_log(LOG_WARNING, "Freeing a filestream we don't seem to own\n");
close(s->fd);
free(s);
}
static int ast_read_callback(void *data)
{
int retval = 0;
int res;
int delay = 20;
struct ast_filestream *s = data;
struct timeval tv;
/* Send a frame from the file to the appropriate channel */
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass = AST_FORMAT_GSM;
s->fr.offset = AST_FRIENDLY_OFFSET;
s->fr.timelen = 20;
s->fr.datalen = 33;
s->fr.mallocd = 0;
s->fr.data = s->gsm;
if ((res = read(s->fd, s->gsm, 33)) != 33) {
if (res)
ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
s->owner->streamid = -1;
return 0;
}
/* Lastly, process the frame */
if (ast_write(s->owner, &s->fr)) {
ast_log(LOG_WARNING, "Failed to write frame\n");
s->owner->streamid = -1;
return 0;
}
if (s->last.tv_usec || s->last.tv_usec) {
int ms;
gettimeofday(&tv, NULL);
ms = 1000 * (tv.tv_sec - s->last.tv_sec) +
(tv.tv_usec - s->last.tv_usec) / 1000;
s->last.tv_sec = tv.tv_sec;
s->last.tv_usec = tv.tv_usec;
if ((ms - delay) * (ms - delay) > 4) {
/* Compensate if we're more than 2 ms off */
s->adj -= (ms - delay);
}
#if 0
fprintf(stdout, "Delay is %d, adjustment is %d, last was %d\n", delay, s->adj, ms);
#endif
delay += s->adj;
if (delay < 1)
delay = 1;
} else
gettimeofday(&s->last, NULL);
if (s->lasttimeout != delay) {
/* We'll install the next timeout now. */
s->owner->streamid = ast_sched_add(s->owner->sched,
delay, ast_read_callback, s);
s->lasttimeout = delay;
} else {
/* Just come back again at the same time */
retval = -1;
}
return retval;
}
static int gsm_apply(struct ast_channel *c, struct ast_filestream *s)
{
/* Select our owner for this stream, and get the ball rolling. */
s->owner = c;
ast_read_callback(s);
return 0;
}
static int gsm_write(struct ast_filestream *fs, struct ast_frame *f)
{
int res;
if (f->frametype != AST_FRAME_VOICE) {
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
return -1;
}
if (f->subclass != AST_FORMAT_GSM) {
ast_log(LOG_WARNING, "Asked to write non-GSM frame (%d)!\n", f->subclass);
return -1;
}
if (f->datalen != 33) {
ast_log(LOG_WARNING, "Invalid data length, %d, should be 33\n", f->datalen);
return -1;
}
if ((res = write(fs->fd, f->data, f->datalen)) != f->datalen) {
ast_log(LOG_WARNING, "Bad write (%d/33): %s\n", res, strerror(errno));
return -1;
}
return 0;
}
static char *gsm_getcomment(struct ast_filestream *s)
{
return NULL;
}
int load_module()
{
return ast_format_register(name, exts, AST_FORMAT_GSM,
gsm_open,
gsm_rewrite,
gsm_apply,
gsm_write,
gsm_read,
gsm_close,
gsm_getcomment);
}
int unload_module()
{
struct ast_filestream *tmp, *tmpl;
if (pthread_mutex_lock(&gsm_lock)) {
ast_log(LOG_WARNING, "Unable to lock gsm list\n");
return -1;
}
tmp = glist;
while(tmp) {
if (tmp->owner)
ast_softhangup(tmp->owner);
tmpl = tmp;
tmp = tmp->next;
free(tmpl);
}
pthread_mutex_unlock(&gsm_lock);
return ast_format_unregister(name);
}
int usecount()
{
int res;
if (pthread_mutex_lock(&gsm_lock)) {
ast_log(LOG_WARNING, "Unable to lock gsm list\n");
return -1;
}
res = glistcnt;
pthread_mutex_unlock(&gsm_lock);
return res;
}
char *description()
{
return desc;
}

View File

@ -3,7 +3,7 @@
*
* Everybody's favorite format: MP3 Files! Yay!
*
* Copyright (C) 1999, Adtran Inc. and Linux Support Services, LLC
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
@ -26,8 +26,7 @@
#include <sys/time.h>
#include "../channels/adtranvofr.h"
#define MP3_MAX_SIZE 1400
#define MAX_FRAME_SIZE 1441
struct ast_filestream {
/* First entry MUST be reserved for the channel type */
@ -36,9 +35,13 @@ struct ast_filestream {
int fd; /* Descriptor */
struct ast_channel *owner;
struct ast_filestream *next;
struct ast_frame *fr; /* Frame representation of buf */
char buf[sizeof(struct ast_frame) + MP3_MAX_SIZE + AST_FRIENDLY_OFFSET]; /* Buffer for sending frames, etc */
struct ast_frame fr; /* Frame representation of buf */
char offset[AST_FRIENDLY_OFFSET];
unsigned char buf[MAX_FRAME_SIZE * 2];
int lasttimeout;
int pos;
int adj;
struct timeval last;
};
@ -47,16 +50,10 @@ static pthread_mutex_t mp3_lock = PTHREAD_MUTEX_INITIALIZER;
static int glistcnt = 0;
static char *name = "mp3";
static char *desc = "MPEG-2 Layer 3 File Format Support";
static char *desc = "MPEG-1,2 Layer 3 File Format Support";
static char *exts = "mp3|mpeg3";
#if 0
#define MP3_FRAMELEN 417
#else
#define MP3_FRAMELEN 400
#endif
#define MP3_OUTPUTLEN 2304 /* Bytes */
#define MP3_TIMELEN ((MP3_OUTPUTLEN * 1000 / 16000) )
#include "../codecs/mp3anal.h"
static struct ast_filestream *mp3_open(int fd)
{
@ -74,13 +71,10 @@ static struct ast_filestream *mp3_open(int fd)
glist = tmp;
tmp->fd = fd;
tmp->owner = NULL;
tmp->fr = (struct ast_frame *)tmp->buf;
tmp->fr->data = tmp->buf + sizeof(struct ast_frame);
tmp->fr->frametype = AST_FRAME_VOICE;
tmp->fr->subclass = AST_FORMAT_MP3;
/* datalen will vary for each frame */
tmp->fr->src = name;
tmp->fr->mallocd = 0;
tmp->lasttimeout = -1;
tmp->last.tv_usec = 0;
tmp->last.tv_sec = 0;
tmp->adj = 0;
glistcnt++;
pthread_mutex_unlock(&mp3_lock);
ast_update_use_count();
@ -104,7 +98,6 @@ static struct ast_filestream *mp3_rewrite(int fd, char *comment)
glist = tmp;
tmp->fd = fd;
tmp->owner = NULL;
tmp->fr = NULL;
glistcnt++;
pthread_mutex_unlock(&mp3_lock);
ast_update_use_count();
@ -155,28 +148,67 @@ static void mp3_close(struct ast_filestream *s)
static int ast_read_callback(void *data)
{
/* XXX Don't assume frames are this size XXX */
u_int16_t size=MP3_FRAMELEN;
u_int32_t delay = -1;
int res;
struct ast_filestream *s = data;
/* Send a frame from the file to the appropriate channel */
/* Read the data into the buffer */
s->fr->offset = AST_FRIENDLY_OFFSET;
s->fr->datalen = size;
s->fr->data = s->buf + sizeof(struct ast_frame) + AST_FRIENDLY_OFFSET;
if ((res = read(s->fd, s->fr->data , size)) != size) {
ast_log(LOG_WARNING, "Short read (%d of %d bytes) (%s)!\n", res, size, strerror(errno));
int size;
int ms=0;
struct timeval tv;
if ((res = read(s->fd, s->buf , 4)) != 4) {
ast_log(LOG_WARNING, "Short read (%d of 4 bytes) (%s)!\n", res, strerror(errno));
s->owner->streamid = -1;
return 0;
}
delay = MP3_TIMELEN;
s->fr->timelen = delay;
if (mp3_badheader(s->buf)) {
ast_log(LOG_WARNING, "Bad mp3 header\n");
return 0;
}
if ((size = mp3_framelen(s->buf)) < 0) {
ast_log(LOG_WARNING, "Unable to calculate frame size\n");
return 0;
}
if ((res = read(s->fd, s->buf + 4 , size - 4)) != size - 4) {
ast_log(LOG_WARNING, "Short read (%d of %d bytes) (%s)!\n", res, size - 4, strerror(errno));
s->owner->streamid = -1;
return 0;
}
/* Send a frame from the file to the appropriate channel */
/* Read the data into the buffer */
s->fr.offset = AST_FRIENDLY_OFFSET;
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass = AST_FORMAT_MP3;
s->fr.mallocd = 0;
s->fr.src = name;
s->fr.datalen = size;
s->fr.data = s->buf;
delay = mp3_samples(s->buf) * 1000 / mp3_samplerate(s->buf);
if (s->last.tv_sec || s->last.tv_usec) {
/* To keep things running smoothly, we watch how close we're coming */
gettimeofday(&tv, NULL);
ms = ((tv.tv_usec - s->last.tv_usec) / 1000 + (tv.tv_sec - s->last.tv_sec) * 1000);
/* If we're within 2 milliseconds, that's close enough */
if ((ms - delay) * (ms - delay) > 4)
s->adj -= (ms - delay);
}
s->fr.timelen = delay;
#if 0
ast_log(LOG_DEBUG, "delay is %d, adjusting by %d, as last was %d\n", delay, s->adj, ms);
#endif
delay += s->adj;
if (delay < 1)
delay = 1;
/* Lastly, process the frame */
if (ast_write(s->owner, s->fr)) {
if (ast_write(s->owner, &s->fr)) {
ast_log(LOG_WARNING, "Failed to write frame\n");
s->owner->streamid = -1;
return 0;
}
gettimeofday(&s->last, NULL);
if (s->lasttimeout != delay) {
s->owner->streamid = ast_sched_add(s->owner->sched, delay, ast_read_callback, s);
s->lasttimeout = delay;
return 0;
}
return -1;
}
@ -184,7 +216,6 @@ static int mp3_apply(struct ast_channel *c, struct ast_filestream *s)
{
/* Select our owner for this stream, and get the ball rolling. */
s->owner = c;
s->owner->streamid = ast_sched_add(s->owner->sched, MP3_TIMELEN, ast_read_callback, s);
ast_read_callback(s);
return 0;
}
@ -192,10 +223,6 @@ static int mp3_apply(struct ast_channel *c, struct ast_filestream *s)
static int mp3_write(struct ast_filestream *fs, struct ast_frame *f)
{
int res;
if (fs->fr) {
ast_log(LOG_WARNING, "Asked to write on a read stream??\n");
return -1;
}
if (f->frametype != AST_FRAME_VOICE) {
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
return -1;
@ -211,7 +238,7 @@ static int mp3_write(struct ast_filestream *fs, struct ast_frame *f)
return 0;
}
char *mp3_getcomment(struct ast_filestream *s)
static char *mp3_getcomment(struct ast_filestream *s)
{
return NULL;
}

View File

@ -3,7 +3,7 @@
*
* Microsoft WAV File Format using libaudiofile
*
* Copyright (C) 1999, Adtran Inc. and Linux Support Services, LLC
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
@ -298,7 +298,7 @@ static int wav_write(struct ast_filestream *fs, struct ast_frame *f)
return 0;
}
char *wav_getcomment(struct ast_filestream *s)
static char *wav_getcomment(struct ast_filestream *s)
{
return NULL;
}

586
formats/format_wav_gsm.c Executable file
View File

@ -0,0 +1,586 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Save GSM in the proprietary Microsoft format.
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/channel.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/sched.h>
#include <asterisk/module.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <endian.h>
#include "msgsm.h"
/* Some Ideas for this code came from makewave.c by Jeffery Chilton */
/* Portions of the conversion code are by guido@sienanet.it */
struct ast_filestream {
void *reserved[AST_RESERVED_POINTERS];
/* Believe it or not, we must decode/recode to account for the
weird MS format */
/* This is what a filestream means to us */
int fd; /* Descriptor */
int bytes;
struct ast_channel *owner;
struct ast_frame fr; /* Frame information */
char waste[AST_FRIENDLY_OFFSET]; /* Buffer for sending frames, etc */
char empty; /* Empty character */
unsigned char gsm[66]; /* Two Real GSM Frames */
int foffset;
int secondhalf; /* Are we on the second half */
int lasttimeout;
struct timeval last;
int adj;
struct ast_filestream *next;
};
static struct ast_filestream *glist = NULL;
static pthread_mutex_t wav_lock = PTHREAD_MUTEX_INITIALIZER;
static int glistcnt = 0;
static char *name = "wav49";
static char *desc = "Microsoft WAV format (Proprietary GSM)";
static char *exts = "WAV";
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define htoll(b) (b)
#define htols(b) (b)
#define ltohl(b) (b)
#define ltohs(b) (b)
#else
#if __BYTE_ORDER == __BIG_ENDIAN
#define htoll(b) \
(((((b) ) & 0xFF) << 24) | \
((((b) >> 8) & 0xFF) << 16) | \
((((b) >> 16) & 0xFF) << 8) | \
((((b) >> 24) & 0xFF) ))
#define htols(b) \
(((((b) ) & 0xFF) << 8) | \
((((b) >> 8) & 0xFF) ))
#define ltohl(b) htoll(b)
#define ltohs(b) htols(b)
#else
#error "Endianess not defined"
#endif
#endif
static int check_header(int fd)
{
int type, size, formtype;
int fmt, hsize, fact;
short format, chans;
int freq;
int data;
if (read(fd, &type, 4) != 4) {
ast_log(LOG_WARNING, "Read failed (type)\n");
return -1;
}
if (read(fd, &size, 4) != 4) {
ast_log(LOG_WARNING, "Read failed (size)\n");
return -1;
}
size = ltohl(size);
if (read(fd, &formtype, 4) != 4) {
ast_log(LOG_WARNING, "Read failed (formtype)\n");
return -1;
}
if (memcmp(&type, "RIFF", 4)) {
ast_log(LOG_WARNING, "Does not begin with RIFF\n");
return -1;
}
if (memcmp(&formtype, "WAVE", 4)) {
ast_log(LOG_WARNING, "Does not contain WAVE\n");
return -1;
}
if (read(fd, &fmt, 4) != 4) {
ast_log(LOG_WARNING, "Read failed (fmt)\n");
return -1;
}
if (memcmp(&fmt, "fmt ", 4)) {
ast_log(LOG_WARNING, "Does not say fmt\n");
return -1;
}
if (read(fd, &hsize, 4) != 4) {
ast_log(LOG_WARNING, "Read failed (formtype)\n");
return -1;
}
if (ltohl(hsize) != 20) {
ast_log(LOG_WARNING, "Unexpected header size %d\n", ltohl(hsize));
return -1;
}
if (read(fd, &format, 2) != 2) {
ast_log(LOG_WARNING, "Read failed (format)\n");
return -1;
}
if (ltohs(format) != 49) {
ast_log(LOG_WARNING, "Not a GSM file %d\n", ltohs(format));
return -1;
}
if (read(fd, &chans, 2) != 2) {
ast_log(LOG_WARNING, "Read failed (format)\n");
return -1;
}
if (ltohs(chans) != 1) {
ast_log(LOG_WARNING, "Not in mono %d\n", ltohs(chans));
return -1;
}
if (read(fd, &freq, 4) != 4) {
ast_log(LOG_WARNING, "Read failed (freq)\n");
return -1;
}
if (ltohl(freq) != 8000) {
ast_log(LOG_WARNING, "Unexpected freqency %d\n", ltohl(freq));
return -1;
}
/* Ignore the byte frequency */
if (read(fd, &freq, 4) != 4) {
ast_log(LOG_WARNING, "Read failed (X_1)\n");
return -1;
}
/* Ignore the two weird fields */
if (read(fd, &freq, 4) != 4) {
ast_log(LOG_WARNING, "Read failed (X_2/X_3)\n");
return -1;
}
/* Ignore the byte frequency */
if (read(fd, &freq, 4) != 4) {
ast_log(LOG_WARNING, "Read failed (Y_1)\n");
return -1;
}
/* Check for the word fact */
if (read(fd, &fact, 4) != 4) {
ast_log(LOG_WARNING, "Read failed (fact)\n");
return -1;
}
if (memcmp(&fact, "fact", 4)) {
ast_log(LOG_WARNING, "Does not say fact\n");
return -1;
}
/* Ignore the "fact value" */
if (read(fd, &fact, 4) != 4) {
ast_log(LOG_WARNING, "Read failed (fact header)\n");
return -1;
}
if (read(fd, &fact, 4) != 4) {
ast_log(LOG_WARNING, "Read failed (fact value)\n");
return -1;
}
/* Check for the word data */
if (read(fd, &data, 4) != 4) {
ast_log(LOG_WARNING, "Read failed (data)\n");
return -1;
}
if (memcmp(&data, "data", 4)) {
ast_log(LOG_WARNING, "Does not say data\n");
return -1;
}
/* Ignore the data length */
if (read(fd, &data, 4) != 4) {
ast_log(LOG_WARNING, "Read failed (data)\n");
return -1;
}
return 0;
}
static int update_header(int fd, int bytes)
{
int cur;
int datalen = htoll(bytes);
int filelen = htoll(52 + ((bytes + 1) & ~0x1));
cur = lseek(fd, 0, SEEK_CUR);
if (cur < 0) {
ast_log(LOG_WARNING, "Unable to find our position\n");
return -1;
}
if (lseek(fd, 4, SEEK_SET) != 4) {
ast_log(LOG_WARNING, "Unable to set our position\n");
return -1;
}
if (write(fd, &filelen, 4) != 4) {
ast_log(LOG_WARNING, "Unable to set write file size\n");
return -1;
}
if (lseek(fd, 56, SEEK_SET) != 56) {
ast_log(LOG_WARNING, "Unable to set our position\n");
return -1;
}
if (write(fd, &datalen, 4) != 4) {
ast_log(LOG_WARNING, "Unable to set write datalen\n");
return -1;
}
if (lseek(fd, cur, SEEK_SET) != cur) {
ast_log(LOG_WARNING, "Unable to return to position\n");
return -1;
}
return 0;
}
static int write_header(int fd)
{
unsigned int hz=htoll(8000);
unsigned int bhz = htoll(1625);
unsigned int hs = htoll(20);
unsigned short fmt = htols(49);
unsigned short chans = htols(1);
unsigned int fhs = htoll(4);
unsigned int x_1 = htoll(65);
unsigned short x_2 = htols(2);
unsigned short x_3 = htols(320);
unsigned int y_1 = htoll(20160);
unsigned int size = htoll(0);
/* Write a GSM header, ignoring sizes which will be filled in later */
if (write(fd, "RIFF", 4) != 4) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
if (write(fd, &size, 4) != 4) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
if (write(fd, "WAVEfmt ", 8) != 8) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
if (write(fd, &hs, 4) != 4) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
if (write(fd, &fmt, 2) != 2) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
if (write(fd, &chans, 2) != 2) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
if (write(fd, &hz, 4) != 4) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
if (write(fd, &bhz, 4) != 4) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
if (write(fd, &x_1, 4) != 4) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
if (write(fd, &x_2, 2) != 2) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
if (write(fd, &x_3, 2) != 2) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
if (write(fd, "fact", 4) != 4) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
if (write(fd, &fhs, 4) != 4) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
if (write(fd, &y_1, 4) != 4) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
if (write(fd, "data", 4) != 4) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
if (write(fd, &size, 4) != 4) {
ast_log(LOG_WARNING, "Unable to write header\n");
return -1;
}
return 0;
}
static struct ast_filestream *wav_open(int fd)
{
/* We don't have any header to read or anything really, but
if we did, it would go here. We also might want to check
and be sure it's a valid file. */
struct ast_filestream *tmp;
if ((tmp = malloc(sizeof(struct ast_filestream)))) {
memset(tmp, 0, sizeof(struct ast_filestream));
if (check_header(fd)) {
free(tmp);
return NULL;
}
if (pthread_mutex_lock(&wav_lock)) {
ast_log(LOG_WARNING, "Unable to lock wav list\n");
free(tmp);
return NULL;
}
tmp->next = glist;
glist = tmp;
tmp->fd = fd;
tmp->owner = NULL;
tmp->fr.data = tmp->gsm;
tmp->fr.frametype = AST_FRAME_VOICE;
tmp->fr.subclass = AST_FORMAT_GSM;
/* datalen will vary for each frame */
tmp->fr.src = name;
tmp->fr.mallocd = 0;
tmp->secondhalf = 0;
tmp->lasttimeout = -1;
glistcnt++;
pthread_mutex_unlock(&wav_lock);
ast_update_use_count();
}
return tmp;
}
static struct ast_filestream *wav_rewrite(int fd, char *comment)
{
/* We don't have any header to read or anything really, but
if we did, it would go here. We also might want to check
and be sure it's a valid file. */
struct ast_filestream *tmp;
if ((tmp = malloc(sizeof(struct ast_filestream)))) {
memset(tmp, 0, sizeof(struct ast_filestream));
if (write_header(fd)) {
free(tmp);
return NULL;
}
if (pthread_mutex_lock(&wav_lock)) {
ast_log(LOG_WARNING, "Unable to lock wav list\n");
free(tmp);
return NULL;
}
tmp->next = glist;
glist = tmp;
tmp->fd = fd;
tmp->owner = NULL;
tmp->lasttimeout = -1;
glistcnt++;
pthread_mutex_unlock(&wav_lock);
ast_update_use_count();
} else
ast_log(LOG_WARNING, "Out of memory\n");
return tmp;
}
static struct ast_frame *wav_read(struct ast_filestream *s)
{
return NULL;
}
static void wav_close(struct ast_filestream *s)
{
struct ast_filestream *tmp, *tmpl = NULL;
char zero = 0;
if (pthread_mutex_lock(&wav_lock)) {
ast_log(LOG_WARNING, "Unable to lock wav list\n");
return;
}
tmp = glist;
while(tmp) {
if (tmp == s) {
if (tmpl)
tmpl->next = tmp->next;
else
glist = tmp->next;
break;
}
tmpl = tmp;
tmp = tmp->next;
}
glistcnt--;
if (s->owner) {
s->owner->stream = NULL;
if (s->owner->streamid > -1)
ast_sched_del(s->owner->sched, s->owner->streamid);
s->owner->streamid = -1;
}
pthread_mutex_unlock(&wav_lock);
ast_update_use_count();
if (!tmp)
ast_log(LOG_WARNING, "Freeing a filestream we don't seem to own\n");
/* Pad to even length */
if (s->bytes & 0x1)
write(s->fd, &zero, 1);
close(s->fd);
free(s);
}
static int ast_read_callback(void *data)
{
int retval = 0;
int res;
int delay = 20;
struct ast_filestream *s = data;
char msdata[66];
struct timeval tv;
/* Send a frame from the file to the appropriate channel */
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass = AST_FORMAT_GSM;
s->fr.offset = AST_FRIENDLY_OFFSET;
s->fr.timelen = 20;
s->fr.datalen = 33;
s->fr.mallocd = 0;
if (s->secondhalf) {
/* Just return a frame based on the second GSM frame */
s->fr.data = s->gsm + 33;
} else {
if ((res = read(s->fd, msdata, 65)) != 65) {
if (res && (res != 1))
ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
s->owner->streamid = -1;
return 0;
}
/* Convert from MS format to two real GSM frames */
conv65(msdata, s->gsm);
s->fr.data = s->gsm;
}
s->secondhalf = !s->secondhalf;
/* Lastly, process the frame */
if (ast_write(s->owner, &s->fr)) {
ast_log(LOG_WARNING, "Failed to write frame\n");
s->owner->streamid = -1;
return 0;
}
if (s->last.tv_usec || s->last.tv_usec) {
int ms;
gettimeofday(&tv, NULL);
ms = 1000 * (tv.tv_sec - s->last.tv_sec) +
(tv.tv_usec - s->last.tv_usec) / 1000;
s->last.tv_sec = tv.tv_sec;
s->last.tv_usec = tv.tv_usec;
if ((ms - delay) * (ms - delay) > 4) {
/* Compensate if we're more than 2 ms off */
s->adj -= (ms - delay);
}
#if 0
fprintf(stdout, "Delay is %d, adjustment is %d, last was %d\n", delay, s->adj, ms);
#endif
delay += s->adj;
if (delay < 1)
delay = 1;
} else
gettimeofday(&s->last, NULL);
if (s->lasttimeout != delay) {
/* We'll install the next timeout now. */
s->owner->streamid = ast_sched_add(s->owner->sched,
delay, ast_read_callback, s);
s->lasttimeout = delay;
} else {
/* Just come back again at the same time */
retval = -1;
}
return retval;
}
static int wav_apply(struct ast_channel *c, struct ast_filestream *s)
{
/* Select our owner for this stream, and get the ball rolling. */
s->owner = c;
ast_read_callback(s);
return 0;
}
static int wav_write(struct ast_filestream *fs, struct ast_frame *f)
{
int res;
char msdata[66];
if (f->frametype != AST_FRAME_VOICE) {
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
return -1;
}
if (f->subclass != AST_FORMAT_GSM) {
ast_log(LOG_WARNING, "Asked to write non-GSM frame (%d)!\n", f->subclass);
return -1;
}
if (fs->secondhalf) {
memcpy(fs->gsm + 33, f->data, 33);
conv66(fs->gsm, msdata);
if ((res = write(fs->fd, msdata, 65)) != 65) {
ast_log(LOG_WARNING, "Bad write (%d/65): %s\n", res, strerror(errno));
return -1;
}
fs->bytes += 65;
update_header(fs->fd, fs->bytes);
} else {
/* Copy the data and do nothing */
memcpy(fs->gsm, f->data, 33);
}
fs->secondhalf = !fs->secondhalf;
return 0;
}
static char *wav_getcomment(struct ast_filestream *s)
{
return NULL;
}
int load_module()
{
return ast_format_register(name, exts, AST_FORMAT_GSM,
wav_open,
wav_rewrite,
wav_apply,
wav_write,
wav_read,
wav_close,
wav_getcomment);
}
int unload_module()
{
struct ast_filestream *tmp, *tmpl;
if (pthread_mutex_lock(&wav_lock)) {
ast_log(LOG_WARNING, "Unable to lock wav list\n");
return -1;
}
tmp = glist;
while(tmp) {
if (tmp->owner)
ast_softhangup(tmp->owner);
tmpl = tmp;
tmp = tmp->next;
free(tmpl);
}
pthread_mutex_unlock(&wav_lock);
return ast_format_unregister(name);
}
int usecount()
{
int res;
if (pthread_mutex_lock(&wav_lock)) {
ast_log(LOG_WARNING, "Unable to lock wav list\n");
return -1;
}
res = glistcnt;
pthread_mutex_unlock(&wav_lock);
return res;
}
char *description()
{
return desc;
}

685
formats/msgsm.h Executable file
View File

@ -0,0 +1,685 @@
/* Conversion routines derived from code by guido@sienanet.it */
#define GSM_MAGIC 0xD
typedef unsigned char gsm_byte;
typedef unsigned char wav_byte;
typedef unsigned int uword;
#define readGSM_33(c1) { \
gsm_byte *c = (c1); \
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 */ \
}
static void conv66(gsm_byte * d, wav_byte * c) {
gsm_byte frame_chain;
unsigned int sr;
unsigned int LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
readGSM_33(d);
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;
frame_chain = *c;
readGSM_33(d+33);// puts all the parameters into LARc etc.
sr = 0;
// sr = (sr >> 4 )|( s->frame_chain << 12);
sr = (sr >> 4 )|( 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;
}
#define writeGSM_33(c1) { \
gsm_byte *c = (c1); \
*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); \
}
static void conv65( wav_byte * c, gsm_byte * d){
unsigned int sr = 0;
unsigned int frame_chain;
unsigned int LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
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[49] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 2;
xmc[50] = sr & 0x7; sr >>= 3;
xmc[51] = sr & 0x7; sr >>= 3;
frame_chain = sr & 0xf;
writeGSM_33(d);// LARc etc. -> array of 33 GSM bytes
sr = 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;
writeGSM_33(d+33);
}

View File

@ -3,7 +3,7 @@
*
* Private channel definitions for channel implementations only.
*
* Copyright (C) 1999, Adtran Inc. and Linux Support Services, LLC
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
@ -40,8 +40,8 @@ struct ast_channel_pvt {
};
/* Create a channel structure */
struct ast_channel *ast_channel_alloc();
#define ast_channel_free(a) free(a)
struct ast_channel *ast_channel_alloc(void);
void ast_channel_free(struct ast_channel *);
#if defined(__cplusplus) || defined(c_plusplus)
}

View File

@ -3,7 +3,7 @@
*
* Mark Spencer <markster@marko.net>
*
* Copyright(C) 1999, Adtran, Inc.
* Copyright(C) Mark Spencer
*
* Distributed under the terms of the GNU General Public License (GPL) Version 2
*
@ -38,10 +38,10 @@ extern "C" {
struct io_context;
/* Create a context for I/O operations */
struct io_context *io_context_create();
extern struct io_context *io_context_create(void);
/* Destroy a context for I/O operations */
void io_context_destroy(struct io_context *ioc);
extern void io_context_destroy(struct io_context *ioc);
typedef int (*ast_io_cb)(int *id, int fd, short events, void *cbdata);
#define AST_IO_CB(a) ((ast_io_cb)(a))

4
io.c
View File

@ -3,7 +3,7 @@
*
* Mark Spencer <markster@marko.net>
*
* Copyright(C) 1999, Adtran, Inc.
* Copyright(C) Mark Spencer
*
* Distributed under the terms of the GNU General Public License (GPL) Version 2
*
@ -58,7 +58,7 @@ struct io_context {
};
struct io_context *io_context_create()
struct io_context *io_context_create(void)
{
/* Create an I/O context */
struct io_context *tmp;