Compare commits

..

3 Commits
0.1.8 ... 0.1.4

Author SHA1 Message Date
Kevin P. Fleming
be1254452d remove extraneous svn:executable properties
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/0.1.4@7221 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2005-11-29 18:24:39 +00:00
Kevin P. Fleming
9c2ffcab5d automatic tag renames
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/0.1.4@7201 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2005-11-27 17:18:34 +00:00
Admin Commit
a316ffc3b5 This commit was manufactured by cvs2svn to create tag 'v0-1-4'.
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/v0-1-4@221 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2000-10-26 13:33:57 +00:00
148 changed files with 2368 additions and 16702 deletions

8
BUGS
View File

@@ -2,10 +2,10 @@
these bugs are in asterisk, and sometimes they relate to the products
that asterisk uses.
* 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.
* When you flip to call waiting on a tormenta channel while you have a
three way call up, the parties in the three way cannot hear one another
in the general case.

54
CHANGES
View File

@@ -1,57 +1,3 @@
Asterisk 0.1.8
-- Keep track of version information
-- Add -f to cause Asterisk not to fork
-- Keep important information in voicemail .txt file
-- Adtran Voice over Frame Relay updates
-- Implement option setting/querying of channel drivers
-- IAX performance improvements and protocol fixes
-- Substantial enhancement of console channel driver
-- Add IAX registration. Now IAX can dynamically register
-- Add flash-hook transfer on tormenta channels
-- Added Three Way Calling on tormenta channels
-- Start on concept of zombie channel
-- Add Call Waiting CallerID
-- Keep track of who registeres contexts, includes, and extensions
-- Added Call Waiting(tm), *67, *70, and *82 codes
-- Move parked calls into "parkedcalls" context by default
-- Allow dialplan to be displayed
-- Allow "=>" instead of just "=" to make instantiation clearer
-- Asterisk forks if called with no arguments
-- Add remote control by running asterisk -vvvc
-- Adjust verboseness with "set verbose" now
-- No longer requires libaudiofile
-- Install beep
-- Make PBX Config module reload extensions on SIGHUP
-- Allow modules to be reloaded when SIGHUP is received
-- Variables now contain line numbers
-- Make dialer send in band signalling
-- Add record application
-- Added PRI signalling to Tormenta driver
-- Allow use of BYEXTENSION in "Goto"
-- Allow adjustment of gains on tormenta channels
-- Added raw PCM file format support
-- Add U-law translator
-- Fix DTMF handling in bridge code
-- Fix access control with IAX
* Asterisk 0.1.7
-- Update configuration files and add some missing sounds
-- Added ability to include one context in another
-- Rewrite of PBX switching
-- Major mods to dialler application
-- Added Caller*ID spill reception
-- Added Dialogic VOX file format support
-- Added ADPCM Codec
-- Add Tormenta driver (RBS signalling)
-- Add Caller*ID spill creation
-- Rewrite of translation layer entirely
-- Add ability to run PBX without additional thread
* Asterisk 0.1.6
-- Make app_dial handle a lack of translators smoothly
-- Add ISDN4Linux support -- dtmf is weird...
-- Minor bug fixes
* Asterisk 0.1.5
-- Fix a small mistake in IAX
-- Fix the QuickNet driver to work with newer cards
* Asterisk 0.1.4
-- Update VoFR some more
-- Fix the QuickNet driver to work with LineJack

View File

@@ -23,17 +23,11 @@ PROC=i586
DEBUG=-g #-pg
INCLUDE=-Iinclude -I../include
CFLAGS=-pipe -Wall -Werror -Wmissing-prototypes -Wmissing-declarations -O6 $(DEBUG) $(INCLUDE) -D_REENTRANT
CFLAGS=-pipe -Wall -Werror -Wmissing-prototypes -Wmissing-declarations -O6 $(DEBUG) $(INCLUDE) -D_REENTRANT
CFLAGS+=$(shell if $(CC) -march=$(PROC) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=$(PROC)"; fi)
ASTERISKVERSION=$(shell cat .version)
CFLAGS+=-DASTERISK_VERSION=\"$(ASTERISKVERSION)\"
CFLAGS+= -DDO_CRASH -DDEBUG_THREADS
CFLAGS+=# -fomit-frame-pointer
SUBDIRS=channels pbx apps codecs formats
LIBS=-ldl -lpthread -lreadline -lncurses -lm
OBJS=io.o sched.o logger.o frame.o loader.o config.o channel.o \
translate.o file.o say.o pbx.o cli.o md5.o \
ulaw.o callerid.o fskmodem.o asterisk.o
LIBS=-ldl -lpthread -lreadline # -lefence
OBJS=io.o sched.o logger.o frame.o loader.o config.o channel.o translate.o file.o say.o pbx.o cli.o md5.o asterisk.o
CC=gcc
INSTALL=install
@@ -49,13 +43,7 @@ _all: all
all: asterisk subdirs
_version:
if [ -d CVS ]; then echo "CVS-`date +"%D-%T"`" > .version; fi
build.h:
./make_build_h
asterisk: _version build.h $(OBJS)
asterisk: $(OBJS)
gcc -o asterisk -rdynamic $(OBJS) $(LIBS)
subdirs:
@@ -64,20 +52,18 @@ subdirs:
clean:
for x in $(SUBDIRS); do $(MAKE) -C $$x clean || exit 1 ; done
rm -f *.o *.so asterisk
rm -f build.h
datafiles: all
mkdir -p /var/lib/asterisk/sounds/digits
for x in sounds/digits/*; do \
install $$x /var/lib/asterisk/sounds/digits ; \
done
for x in sounds/vm-* sounds/transfer* sounds/pbx-* sounds/ss-* sounds/beep*; do \
for x in sounds/vm-* sounds/transfer* ; do \
install $$x /var/lib/asterisk/sounds ; \
done
install: all datafiles
install: all
mkdir -p $(MODULES_DIR)
mkdir -p /usr/sbin
install -m 755 asterisk /usr/sbin/
for x in $(SUBDIRS); do $(MAKE) -C $$x install || exit 1 ; done
install -d /usr/include/asterisk
install include/asterisk/*.h /usr/include/asterisk

58
README
View File

@@ -18,17 +18,24 @@ on the project itself, please visit the Asterisk home page at:
Linux OS, although it may be portable to other UNIX-like operating systems
as well.
== libaudiofile ==
If you want to use format_wav module, then you need a very recent
version of libaudiofile (at least version 0.2.0, or you can apply the
included patch. RPMS for the patched libaudiofile are available at:
ftp://ftp.asteriskpbx.com/pub/asterisk/support
* GETTING STARTED
First, be sure you've got supported hardware. To use Asterisk right now,
you will need one of the following:
First, be sure you've installed the required libaudiofile upgrade if
you want to use the non-GSM WAV format. Next, be sure you've got
supported hardware. To use Asterisk right now, you will need one of
the following:
* Adtran Atlas 800 Plus
* QuickNet Internet PhoneJack
* Full Duplex Sound Card supported by Linux
* ISDN4Linux compatible ISDN card
* Tormenta Dual T1 card (www.bsdtelephony.com.mx)
Assuming you have one of these (most likely the third) you're ready to
proceed:
@@ -47,10 +54,13 @@ Finally, you can launch Asterisk with:
./asterisk -vvvc
If you get an error about unresolved symbols, install the updated
libaudiofile (available at ftp://ftp.asteriskpbx.com/pub/asterisk/support
You'll see a bunch of verbose messages fly by your screen as Asterisk
initializes (that's the "very very verbose" mode). When it's ready, if
you specified the "c" then you'll get a command line console, that looks
like this:
like this:
*CLI>
@@ -65,44 +75,6 @@ won't work right (not yet).
Feel free to look over the configuration files in /etc/asterisk, where
you'll find a lot of information about what you can do with Asterisk.
* ABOUT CONFIGURATION FILES
All Asterisk configuration files share a common format. Comments are
delimited by ';' (since '#' of course, being a DTMF digit, may occur in
many places). A configuration file is divided into sections whose names
appear in []'s. Each section typically contains two types of statements,
those of the form 'variable = value', and those of the form 'object =>
parameters'. Internally the use of '=' and '=>' is exactly the same, so
they're used only to help make the configuration file easier to
understand, and do not affect how it is actually parsed.
Entries of the form 'variable=value' set the value of some parameter in
asterisk. For example, in tormenta.conf, one might specify:
switchtype=national
In order to indicate to Asterisk that the switch they are connecting to is
of the type "national". In general, the parameter will apply to
instantiations which occur below its specification. For example, if the
configuration file read:
switchtype = national
channel => 1-4
channel => 10-12
switchtype = dms100
channel => 25-47
Then, the "national" switchtype would be applied to channels one through
four and channels 10 through 12, whereas the "dms100" switchtype would
apply to channels 25 through 47.
The "object => parameters" instantiates an object with the given
parameters. For example, the line "channel => 25-47" creates objects for
the channels 25 through 47 of the tormenta card, obtaining the settings
from the variables specified above.
* MORE INFORMATION
Finally, you may wish to visit the web site and join the mailing list if
you're interested in getting more information.

View File

@@ -11,28 +11,17 @@
# the GNU General Public License
#
APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_intercom.so app_mp3.so \
app_system.so app_echo.so app_record.so
APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_intercom.so app_mp3.so app_system.so app_echo.so
CFLAGS+=
all: $(APPS)
clean:
rm -f *.so *.o look
rm -f *.so *.o
%.so : %.o
$(CC) -shared -Xlinker -x -o $@ $<
install: all
for x in $(APPS); do $(INSTALL) -m 755 $$x $(MODULES_DIR) ; done
app_todd.o: app_todd.c
gcc -pipe -O6 -g -Iinclude -I../include -D_REENTRANT -march=i586 -DDO_CRASH -DDEBUG_THREADS -c -o app_todd.o app_todd.c
app_todd.so: app_todd.o
$(CC) -shared -Xlinker -x -o $@ $< -L/usr/local/ssl/lib -lssl -lcrypto
look: look.c
gcc -pipe -O6 -g look.c -o look -lncurses

View File

@@ -27,7 +27,6 @@
#include <stdio.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <pthread.h>
@@ -37,31 +36,11 @@ static char *app = "Dial";
static char *parkedcall = "ParkedCall";
static char *synopsis = "Place an call and connect to the current channel";
static char *registrar = "app_dial";
static char *descrip =
" Dial(Technology/resource[&Technology2/resource2...][|timeout][|transfer]): Requests one or more channels\n"
" and places specified outgoing calls on them. As soon as a channel answers, the Dial app\n"
" will answer the originating channel (if it needs to be answered) and will bridge a call\n"
" with the channel which first answered. All other calls placed by the Dial app will be\n"
" hung up. If a timeout is not specified, the Dial application will wait indefinitely until\n"
" either one of the called channels answers, the user hangs up, or all channels return busy or\n"
" error. In general, the dialler will return 0 if it was unable to place the call, or the\n"
" timeout expired. However, if all channels were busy, and there exists an extension with\n"
" priority n+101 (where n is the priority of the dialler instance), then it will be the\n"
" next executed extension (this allows you to setup different behavior on busy from no-answer)\n."
" This application returns -1 if the originating channel hangs up, or if the call is bridged and\n"
" either of the parties in the bridge terminate the call. The transfer string may contain a\n"
" 't' to allow the called user transfer a call or 'T' to allow the calling user to transfer the call.\n"
" In addition to transferring the call, a call may be parked and then picked up by another user.\n";
/* No more than 45 seconds parked before you do something with them */
static int parkingtime = 45000;
/* No more than 90 seconds parked before you do something with them */
static int parkingtime = 90000;
/* Context for which parking is made accessible */
static char parking_con[AST_MAX_EXTENSION] = "parkedcalls";
static char parking_con[AST_MAX_EXTENSION] = "default";
/* Extension you type to park the call */
static char parking_ext[AST_MAX_EXTENSION] = "700";
@@ -113,7 +92,7 @@ static int park_call(struct ast_channel *chan, struct ast_channel *peer)
int x;
pu = malloc(sizeof(struct parkeduser));
if (pu) {
ast_pthread_mutex_lock(&parking_lock);
pthread_mutex_lock(&parking_lock);
for (x=parking_start;x<=parking_stop;x++) {
cur = parkinglot;
while(cur) {
@@ -135,7 +114,7 @@ static int park_call(struct ast_channel *chan, struct ast_channel *peer)
pu->priority = chan->priority;
pu->next = parkinglot;
parkinglot = pu;
ast_pthread_mutex_unlock(&parking_lock);
pthread_mutex_unlock(&parking_lock);
/* Wake up the (presumably select()ing) thread */
pthread_kill(parking_thread, SIGURG);
if (option_verbose > 1)
@@ -145,7 +124,7 @@ static int park_call(struct ast_channel *chan, struct ast_channel *peer)
} else {
ast_log(LOG_WARNING, "No more parking spaces\n");
free(pu);
ast_pthread_mutex_unlock(&parking_lock);
pthread_mutex_unlock(&parking_lock);
return -1;
}
} else {
@@ -161,7 +140,6 @@ static void *do_parking_thread(void *ignore)
struct parkeduser *pu, *pl, *pt = NULL;
struct timeval tv;
struct ast_frame *f;
int x;
fd_set rfds, efds;
fd_set nrfds, nefds;
FD_ZERO(&rfds);
@@ -169,7 +147,7 @@ static void *do_parking_thread(void *ignore)
for (;;) {
ms = -1;
max = -1;
ast_pthread_mutex_lock(&parking_lock);
pthread_mutex_lock(&parking_lock);
pl = NULL;
pu = parkinglot;
gettimeofday(&tv, NULL);
@@ -196,50 +174,41 @@ static void *do_parking_thread(void *ignore)
pt = pu;
pu = pu->next;
free(pt);
} else {
for (x=0;x<AST_MAX_FDS;x++) {
if ((pu->chan->fds[x] > -1) && (FD_ISSET(pu->chan->fds[x], &rfds) || FD_ISSET(pu->chan->fds[x], &efds))) {
if (FD_ISSET(pu->chan->fds[x], &efds))
pu->chan->exception = 1;
pu->chan->fdno = x;
/* See if they need servicing */
f = ast_read(pu->chan);
if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
/* There's a problem, hang them up*/
if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "%s got tired of being parked\n", pu->chan->name);
ast_hangup(pu->chan);
/* And take them out of the parking lot */
if (pl)
pl->next = pu->next;
else
parkinglot = pu->next;
pt = pu;
pu = pu->next;
free(pt);
break;
} else {
/* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
ast_frfree(f);
goto std; /* XXX Ick: jumping into an else statement??? XXX */
}
}
}
if (x >= AST_MAX_FDS) {
/* Keep this one for next one */
std: FD_SET(pu->chan->fds[x], &nrfds);
FD_SET(pu->chan->fds[x], &nefds);
/* Keep track of our longest wait */
if ((tms < ms) || (ms < 0))
ms = tms;
if (pu->chan->fds[x] > max)
max = pu->chan->fds[x];
pl = pu;
} else if (FD_ISSET(pu->chan->fd, &rfds) || FD_ISSET(pu->chan->fd, &efds)) {
/* See if they need servicing */
f = ast_read(pu->chan);
if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
/* There's a problem, hang them up*/
if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "%s got tired of being parked\n", pu->chan->name);
ast_hangup(pu->chan);
/* And take them out of the parking lot */
if (pl)
pl->next = pu->next;
else
parkinglot = pu->next;
pt = pu;
pu = pu->next;
free(pt);
} else {
/* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
ast_frfree(f);
goto std; /* XXX Ick: jumping into an else statement??? XXX */
}
} else {
/* Keep this one for next one */
std: FD_SET(pu->chan->fd, &nrfds);
FD_SET(pu->chan->fd, &nefds);
/* Keep track of our longest wait */
if ((tms < ms) || (ms < 0))
ms = tms;
if (pu->chan->fd > max)
max = pu->chan->fd;
pl = pu;
pu = pu->next;
}
}
ast_pthread_mutex_unlock(&parking_lock);
pthread_mutex_unlock(&parking_lock);
rfds = nrfds;
efds = nefds;
tv.tv_sec = ms / 1000;
@@ -265,46 +234,43 @@ static void hanguptree(struct localuser *outgoing, struct ast_channel *exception
}
}
#define MAX 256
static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, int *allowredir)
{
fd_set rfds, efds;
struct localuser *o;
int found;
int numlines;
int sentringing = 0;
int numbusies = 0;
int orig = *to;
struct timeval tv;
struct ast_frame *f;
struct ast_channel *peer = NULL;
struct ast_channel *watchers[MAX];
int pos;
int single;
struct ast_channel *winner;
single = (outgoing && !outgoing->next);
if (single) {
/* If we are calling a single channel, make them compatible for in-band tone purpose */
ast_channel_make_compatible(outgoing->chan, in);
}
while(*to && !peer) {
/* Watch all outgoing channels looking for an answer of some sort. */
tv.tv_sec = *to / 1000;
tv.tv_usec = (*to % 1000) * 1000;
while((tv.tv_sec || tv.tv_usec) && !peer) {
FD_ZERO(&rfds);
FD_ZERO(&efds);
/* Always watch the input fd */
FD_SET(in->fd, &rfds);
FD_SET(in->fd, &efds);
o = outgoing;
found = -1;
pos = 1;
numlines = 0;
watchers[0] = in;
while(o) {
/* Keep track of important channels */
if (o->stillgoing) {
watchers[pos++] = o->chan;
found = 1;
/* Pay attention to this one */
CHECK_BLOCKING(o->chan);
FD_SET(o->chan->fd, &rfds);
FD_SET(o->chan->fd, &efds);
if (o->chan->fd > found)
found = o->chan->fd;
}
o = o->next;
numlines++;
o = o->next;
}
if (found < 0) {
/* If nobody is left, just go ahead and stop */
if (found<0) {
if (numlines == numbusies) {
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy at this time\n");
@@ -315,58 +281,72 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_2 "No one is available to answer at this time\n");
}
*to = 0;
break;
}
if (in->fd > found)
found = in->fd;
if (*to > -1)
found = select(found + 1, &rfds, NULL, &efds, &tv);
else
found = select(found + 1, &rfds, NULL, &efds, NULL);
if (found < 0) {
ast_log(LOG_WARNING, "select failed, returned %d (%s)\n", errno, strerror(errno));
*to = -1;
o = outgoing;
while(o) {
if (o->stillgoing) {
o->chan->blocking = 0;
}
o = o->next;
}
return NULL;
}
winner = ast_waitfor_n(watchers, pos, to);
o = outgoing;
while(o) {
if (o->chan == winner) {
f = ast_read(winner);
if (f) {
if (f->frametype == AST_FRAME_CONTROL) {
switch(f->subclass) {
case AST_CONTROL_ANSWER:
/* This is our guy if someone answered. */
if (!peer) {
if (o->stillgoing) {
o->chan->blocking = 0;
if (FD_ISSET(o->chan->fd, &rfds) || FD_ISSET(o->chan->fd, &efds)) {
f = ast_read(o->chan);
if (f) {
if (f->frametype == AST_FRAME_CONTROL) {
switch(f->subclass) {
case AST_CONTROL_ANSWER:
/* This is our guy if someone answered. */
if (!peer) {
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
peer = o->chan;
*allowredir = o->allowredirect;
}
break;
case AST_CONTROL_BUSY:
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
peer = o->chan;
*allowredir = o->allowredirect;
ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", o->chan->name);
o->stillgoing = 0;
numbusies++;
break;
case AST_CONTROL_RINGING:
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name);
break;
case AST_CONTROL_OFFHOOK:
/* Ignore going off hook */
break;
default:
ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
}
break;
case AST_CONTROL_BUSY:
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", o->chan->name);
o->stillgoing = 0;
numbusies++;
break;
case AST_CONTROL_RINGING:
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name);
if (!sentringing) {
ast_indicate(in, AST_CONTROL_RINGING);
sentringing++;
}
break;
case AST_CONTROL_OFFHOOK:
/* Ignore going off hook */
break;
default:
ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
}
} else if (single && (f->frametype == AST_FRAME_VOICE)) {
if (ast_write(in, f))
ast_log(LOG_WARNING, "Unable to forward frame\n");
ast_frfree(f);
} else {
o->stillgoing = 0;
}
ast_frfree(f);
} else {
o->stillgoing = 0;
}
}
o = o->next;
}
if (winner == in) {
if (FD_ISSET(in->fd, &rfds) || FD_ISSET(in->fd, &efds)) {
/* After unblocking the entirity of the list, check for the main channel */
f = ast_read(in);
#if 0
if (f && (f->frametype != AST_FRAME_VOICE))
@@ -378,112 +358,122 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
return NULL;
}
}
if (!*to && (option_verbose > 2))
ast_verbose( VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
}
if (!(tv.tv_sec || tv.tv_usec) && (option_verbose > 2))
ast_verbose( VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
*to = 0;
return peer;
}
static int bridge_call(struct ast_channel *chan, struct ast_channel *peer, int allowredirect)
{
/* Copy voice back and forth between the two channels. Give the peer
the ability to transfer calls with '#<extension' syntax. */
int len;
struct ast_channel *cs[3];
int to = -1, len;
struct ast_frame *f;
struct ast_channel *who;
char newext[256], *ptr;
int res;
struct ast_option_header *aoh;
/* Answer if need be */
if (chan->state != AST_STATE_UP)
if (ast_answer(chan))
return -1;
peer->appl = "Bridged Call";
peer->data = chan->name;
for (;;) {
res = ast_channel_bridge(chan, peer, AST_BRIDGE_DTMF_CHANNEL_1, &f, &who);
if (res < 0) {
ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
cs[0] = chan;
cs[1] = peer;
for (/* ever */;;) {
who = ast_waitfor_n(cs, 2, &to);
if (!who) {
ast_log(LOG_WARNING, "Nobody there??\n");
continue;
}
f = ast_read(who);
if (!f || ((f->frametype == AST_FRAME_CONTROL) &&
((f->subclass == AST_CONTROL_HANGUP) ||
(f->subclass == AST_CONTROL_BUSY))))
return -1;
}
if (!f || ((f->frametype == AST_FRAME_CONTROL) && ((f->subclass == AST_CONTROL_HANGUP) || (f->subclass == AST_CONTROL_BUSY) ||
(f->subclass == AST_CONTROL_CONGESTION)))) {
res = -1;
break;
}
if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RINGING)) {
if (who == chan)
ast_indicate(peer, AST_CONTROL_RINGING);
else
ast_indicate(chan, AST_CONTROL_RINGING);
}
if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_OPTION)) {
aoh = f->data;
/* Forward option Requests */
if (aoh && (aoh->flag == AST_OPTION_FLAG_REQUEST)) {
if (who == chan)
ast_channel_setoption(peer, ntohs(aoh->option), aoh->data, f->datalen - sizeof(struct ast_option_header), 0);
else
ast_channel_setoption(chan, ntohs(aoh->option), aoh->data, f->datalen - sizeof(struct ast_option_header), 0);
}
}
if ((f->frametype == AST_FRAME_DTMF) && (who == peer) && allowredirect &&
(f->subclass == '#')) {
memset(newext, 0, sizeof(newext));
ptr = newext;
len = ast_pbx_longest_extension(chan->context) + 1;
if (len < ast_pbx_longest_extension("default") + 1)
len = ast_pbx_longest_extension("default") + 1;
if ((f->frametype == AST_FRAME_VOICE) ||
(f->frametype == AST_FRAME_DTMF) ||
(f->frametype == AST_FRAME_TEXT)) {
if ((f->frametype == AST_FRAME_DTMF) && (who == peer) && allowredirect &&
(f->subclass == '#')) {
if (f->subclass == '#') {
memset(newext, 0, sizeof(newext));
ptr = newext;
len = ast_pbx_longest_extension(chan->context) + 1;
if (len < ast_pbx_longest_extension("default") + 1)
len = ast_pbx_longest_extension("default") + 1;
/* Transfer */
if ((res=ast_streamfile(peer, "pbx-transfer", chan->language)))
break;
if ((res=ast_waitstream(peer, AST_DIGIT_ANY)) < 0)
break;
ast_stopstream(peer);
if (res > 0) {
/* If they've typed a digit already, handle it */
newext[0] = res;
ptr++;
len --;
}
res = ast_readstring(peer, ptr, len, 3000, 2000, "#");
if (res)
break;
if (!strcmp(newext, parking_ext)) {
if (!park_call(chan, peer)) {
/* We return non-zero, but tell the PBX not to hang the channel when
the thread dies -- We have to be careful now though. We are responsible for
hanging up the channel, else it will never be hung up! */
res=AST_PBX_KEEPALIVE;
if ((res=ast_streamfile(peer, "pbx-transfer", chan->language)))
break;
} else {
ast_log(LOG_WARNING, "Unable to park call %s\n", chan->name);
if ((res=ast_waitstream(peer, AST_DIGIT_ANY)) < 0)
break;
ast_stopstream(peer);
if (res > 0) {
/* If they've typed a digit already, handle it */
newext[0] = res;
ptr++;
len --;
}
/* XXX Maybe we should have another message here instead of invalid extension XXX */
} else if (ast_exists_extension(chan, peer->context, newext, 1)) {
/* Set the channel's new extension, since it exists, using peer context */
strncpy(chan->exten, newext, sizeof(chan->exten));
strncpy(chan->context, peer->context, sizeof(chan->context));
chan->priority = 0;
ast_frfree(f);
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Transferring %s to '%s' (context %s) priority 1\n", chan->name, chan->exten, chan->context);
res=0;
break;
res = ast_readstring(peer, ptr, len, 3000, 2000, "#");
if (res)
break;
if (!strcmp(newext, parking_ext)) {
if (!park_call(chan, peer)) {
/* We return non-zero, but tell the PBX not to hang the channel when
the thread dies -- We have to be careful now though. We are responsible for
hanging up the channel, else it will never be hung up! */
res=AST_PBX_KEEPALIVE;
break;
} else {
ast_log(LOG_WARNING, "Unable to park call %s\n", chan->name);
}
/* XXX Maybe we should have another message here instead of invalid extension XXX */
} else if (ast_exists_extension(chan, peer->context, newext, 1)) {
/* Set the channel's new extension, since it exists, using peer context */
strncpy(chan->exten, newext, sizeof(chan->exten));
strncpy(chan->context, peer->context, sizeof(chan->context));
chan->priority = 0;
ast_frfree(f);
res=0;
break;
} else if (ast_exists_extension(chan, "default", newext, 1)) {
/* Set the channel's new extension, since it exists, using peer context */
strncpy(chan->exten, newext, sizeof(chan->exten));
strncpy(chan->context, "default", sizeof(chan->context));
chan->priority = 0;
ast_frfree(f);
res=0;
break;
}
res = ast_streamfile(peer, "pbx-invalid", chan->language);
if (res)
break;
res = ast_waitstream(peer, AST_DIGIT_ANY);
ast_stopstream(peer);
res = 0;
}
res = ast_streamfile(peer, "pbx-invalid", chan->language);
if (res)
break;
res = ast_waitstream(peer, AST_DIGIT_ANY);
ast_stopstream(peer);
res = 0;
} else {
#if 1
ast_log(LOG_DEBUG, "Read from %s (%d,%d)\n", who->name, f->frametype, f->subclass);
#if 0
ast_log(LOG_DEBUG, "Read from %s\n", who->name);
#endif
if (who == chan)
ast_write(peer, f);
else
ast_write(chan, f);
}
ast_frfree(f);
} else
ast_frfree(f);
/* Swap who gets priority */
cs[2] = cs[0];
cs[0] = cs[1];
cs[1] = cs[2];
}
return res;
}
@@ -492,7 +482,7 @@ static int park_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
struct ast_channel *peer=NULL;
struct ast_channel *peer=NULL, *nchan;
struct parkeduser *pu, *pl=NULL;
int park;
if (!data) {
@@ -501,7 +491,7 @@ static int park_exec(struct ast_channel *chan, void *data)
}
LOCAL_USER_ADD(u);
park = atoi((char *)data);
ast_pthread_mutex_lock(&parking_lock);
pthread_mutex_lock(&parking_lock);
pu = parkinglot;
while(pu) {
if (pu->parkingnum == park) {
@@ -513,23 +503,24 @@ static int park_exec(struct ast_channel *chan, void *data)
}
pu = pu->next;
}
ast_pthread_mutex_unlock(&parking_lock);
pthread_mutex_unlock(&parking_lock);
if (pu) {
peer = pu->chan;
free(pu);
}
if (peer) {
res = ast_channel_make_compatible(chan, peer);
if (res < 0) {
ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name);
ast_hangup(peer);
return -1;
}
/* Build a translator if necessary */
if (peer->format & chan->format)
nchan = chan;
else
nchan = ast_translator_create(chan, peer->format, AST_DIRECTION_BOTH);
/* This runs sorta backwards, since we give the incoming channel control, as if it
were the person called. */
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Channel %s connected to parked call %d\n", chan->name, park);
res = bridge_call(peer, chan, 1);
res = bridge_call(peer, nchan, 1);
if (nchan != chan)
ast_translator_destroy(nchan);
/* Simulate the PBX hanging up */
if (res != AST_PBX_KEEPALIVE)
ast_hangup(peer);
@@ -550,12 +541,11 @@ static int dial_exec(struct ast_channel *chan, void *data)
struct localuser *u;
char *info, *peers, *timeout, *tech, *number, *rest, *cur;
struct localuser *outgoing=NULL, *tmp;
struct ast_channel *peer;
struct ast_channel *peer, *npeer;
int to;
int allowredir=0;
char numsubst[AST_MAX_EXTENSION];
char restofit[AST_MAX_EXTENSION];
char *transfer = NULL;
char *newnum;
if (!data) {
@@ -567,81 +557,51 @@ static int dial_exec(struct ast_channel *chan, void *data)
/* Parse our arguments XXX Check for failure XXX */
info = malloc(strlen((char *)data) + AST_MAX_EXTENSION);
if (!info) {
ast_log(LOG_WARNING, "Out of memory\n");
return -1;
}
strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION);
peers = info;
if (peers) {
timeout = strchr(info, '|');
if (timeout) {
*timeout = '\0';
timeout++;
transfer = strchr(timeout, '|');
if (transfer) {
*transfer = '\0';
transfer++;
}
}
} else
timeout = NULL;
if (!peers || !strlen(peers)) {
peers = strtok(info, "|");
if (!peers) {
ast_log(LOG_WARNING, "Dial argument takes format (technology1/number1&technology2/number2...|optional timeout)\n");
goto out;
}
cur = peers;
timeout = strtok(NULL, "|");
rest = peers;
do {
cur = strtok(rest, "&");
/* Remember where to start next time */
rest = strchr(cur, '&');
if (rest) {
*rest = 0;
rest++;
}
rest = strtok(NULL, "\128");
/* Get a technology/[device:]number pair */
tech = cur;
number = strchr(tech, '/');
tech = strtok(cur, "/");
number = strtok(NULL, "&");
if (!number) {
ast_log(LOG_WARNING, "Dial argument takes format (technology1/[device:]number1&technology2/[device:]number2...|optional timeout)\n");
goto out;
}
*number = '\0';
number++;
tmp = malloc(sizeof(struct localuser));
if (!tmp) {
ast_log(LOG_WARNING, "Out of memory\n");
goto out;
}
if (transfer && (strchr(transfer, 't')))
tmp->allowredirect = 1;
else
tmp->allowredirect = 0;
tmp->allowredirect = 1;
strncpy(numsubst, number, sizeof(numsubst));
/* If we're dialing by extension, look at the extension to know what to dial */
if ((newnum = strstr(numsubst, "BYEXTENSION"))) {
strncpy(restofit, newnum + strlen("BYEXTENSION"), sizeof(restofit));
snprintf(newnum, sizeof(numsubst) - (newnum - numsubst), "%s%s", chan->exten,restofit);
/* By default, if we're dialing by extension, don't permit redirecting */
tmp->allowredirect = 0;
if (option_debug)
ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
}
/* Request the peer */
tmp->chan = ast_request(tech, chan->nativeformats, numsubst);
tmp->chan = ast_request(tech, chan->format, numsubst);
if (!tmp->chan) {
/* If we can't, just go on to the next call */
ast_log(LOG_WARNING, "Unable to create channel of type '%s'\n", tech);
free(tmp);
cur = rest;
continue;
}
tmp->chan->appl = "AppDial";
tmp->chan->data = "(Outgoing Line)";
if (tmp->chan->callerid)
free(tmp->chan->callerid);
if (chan->callerid)
tmp->chan->callerid = strdup(chan->callerid);
else
tmp->chan->callerid = NULL;
/* Place the call, but don't wait on the answer */
res = ast_call(tmp->chan, numsubst, 0);
if (res) {
@@ -652,7 +612,6 @@ static int dial_exec(struct ast_channel *chan, void *data)
ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
ast_hangup(tmp->chan);
free(tmp);
cur = rest;
continue;
} else
if (option_verbose > 2)
@@ -663,10 +622,8 @@ static int dial_exec(struct ast_channel *chan, void *data)
tmp->stillgoing = -1;
tmp->next = outgoing;
outgoing = tmp;
cur = rest;
} while(cur);
if (timeout && strlen(timeout))
} while(rest);
if (timeout)
to = atoi(timeout) * 1000;
else
to = -1;
@@ -687,14 +644,14 @@ static int dial_exec(struct ast_channel *chan, void *data)
conversation. */
hanguptree(outgoing, peer);
outgoing = NULL;
/* Make sure channels are compatible */
res = ast_channel_make_compatible(chan, peer);
if (res < 0) {
ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
ast_hangup(peer);
return -1;
}
res = bridge_call(chan, peer, allowredir);
/* Build a translator if necessary */
if (peer->format & chan->format)
npeer = peer;
else
npeer = ast_translator_create(peer, chan->format, AST_DIRECTION_BOTH);
res = bridge_call(chan, npeer, allowredir);
if (npeer != peer)
ast_translator_destroy(npeer);
ast_hangup(peer);
}
out:
@@ -718,20 +675,17 @@ int load_module(void)
char exten[AST_MAX_EXTENSION];
con = ast_context_find(parking_con);
if (!con) {
con = ast_context_create(parking_con, registrar);
if (!con) {
ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
return -1;
}
ast_log(LOG_ERROR, "Parking context '%s' does not exist\n", parking_con);
return -1;
}
for(x=parking_start; x<=parking_stop;x++) {
snprintf(exten, sizeof(exten), "%d", x);
ast_add_extension2(con, 1, exten, 1, parkedcall, strdup(exten), free, registrar);
ast_add_extension2(con, 1, exten, 1, parkedcall, strdup(exten), free);
}
pthread_create(&parking_thread, NULL, do_parking_thread, NULL);
res = ast_register_application(parkedcall, park_exec, synopsis, descrip);
res = ast_register_application(parkedcall, park_exec);
if (!res)
res = ast_register_application(app, dial_exec, synopsis, descrip);
res = ast_register_application(app, dial_exec);
return res;
}
@@ -746,8 +700,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -28,14 +28,6 @@
static char *tdesc = "Extension Directory";
static char *app = "Directory";
static char *synopsis = "Provide directory of voicemail extensions";
static char *descrip =
" Directory(context): Presents the user with a directory of extensions from which\n"
" they may select by name. The list of names and extensions is discovered from\n"
" voicemail.conf. The context argument is required, and specifies the context\n"
" in which to interpret the extensions\n. Returns 0 unless the user hangs up. It\n"
" also sets up the channel on exit to enter the extension the user selected.\n";
/* For simplicity, I'm keeping the format compatible with the voicemail config,
but i'm open to suggestions for isolating it */
@@ -256,7 +248,7 @@ int unload_module(void)
int load_module(void)
{
return ast_register_application(app, directory_exec, synopsis, descrip);
return ast_register_application(app, directory_exec);
}
char *description(void)
@@ -270,8 +262,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -28,17 +28,11 @@ static char *tdesc = "Simple Echo Application";
static char *app = "Echo";
static char *synopsis = "Echo audio read back to the user";
static char *descrip =
" Echo(): Echo audio read from channel back to the channel. Returns 0\n"
" if the user exits with the '#' key, or -1 if the user hangs up.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int echo_exec(struct ast_channel *chan, void *data)
static int skel_exec(struct ast_channel *chan, void *data)
{
int res=-1;
struct localuser *u;
@@ -70,7 +64,7 @@ int unload_module(void)
int load_module(void)
{
return ast_register_application(app, echo_exec, synopsis, descrip);
return ast_register_application(app, skel_exec);
}
char *description(void)
@@ -84,8 +78,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -37,12 +37,6 @@ static char *tdesc = "Intercom using /dev/dsp for output";
static char *app = "Intercom";
static char *synopsis = "(Obsolete) Send to Intercom";
static char *descrip =
" Intercom(): Sends the user to the intercom (i.e. /dev/dsp). This program\n"
" is generally considered obselete by the chan_oss module. Returns 0 if the\n"
" user exits with a DTMF tone, or -1 if they hangup.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
@@ -54,19 +48,19 @@ static int write_audio(short *data, int len)
{
int res;
struct audio_buf_info info;
ast_pthread_mutex_lock(&sound_lock);
pthread_mutex_lock(&sound_lock);
if (sound < 0) {
ast_log(LOG_WARNING, "Sound device closed?\n");
ast_pthread_mutex_unlock(&sound_lock);
pthread_mutex_unlock(&sound_lock);
return -1;
}
if (ioctl(sound, SNDCTL_DSP_GETOSPACE, &info)) {
ast_log(LOG_WARNING, "Unable to read output space\n");
ast_pthread_mutex_unlock(&sound_lock);
pthread_mutex_unlock(&sound_lock);
return -1;
}
res = write(sound, data, len);
ast_pthread_mutex_unlock(&sound_lock);
pthread_mutex_unlock(&sound_lock);
return res;
}
@@ -122,44 +116,48 @@ static int intercom_exec(struct ast_channel *chan, void *data)
int res = 0;
struct localuser *u;
struct ast_frame *f;
int oreadformat;
LOCAL_USER_ADD(u);
/* Remember original read format */
oreadformat = chan->readformat;
/* Set mode to signed linear */
res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set format to signed linear on channel %s\n", chan->name);
struct ast_channel *trans;
if (!data) {
ast_log(LOG_WARNING, "Playback requires an argument (filename)\n");
return -1;
}
/* Read packets from the channel */
while(!res) {
res = ast_waitfor(chan, -1);
if (res > 0) {
res = 0;
f = ast_read(chan);
if (f) {
if (f->frametype == AST_FRAME_DTMF) {
LOCAL_USER_ADD(u);
/* See if we need a translator */
if (!(chan->format & AST_FORMAT_SLINEAR))
trans = ast_translator_create(chan, AST_FORMAT_SLINEAR, AST_DIRECTION_IN);
else
trans = chan;
if (trans) {
/* Read packets from the channel */
while(!res) {
res = ast_waitfor(trans, -1);
if (res > 0) {
res = 0;
f = ast_read(trans);
if (f) {
if (f->frametype == AST_FRAME_DTMF) {
ast_frfree(f);
break;
} else {
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass == AST_FORMAT_SLINEAR) {
res = write_audio(f->data, f->datalen);
if (res > 0)
res = 0;
} else
ast_log(LOG_DEBUG, "Unable to handle non-signed linear frame (%d)\n", f->subclass);
}
}
ast_frfree(f);
break;
} else {
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass == AST_FORMAT_SLINEAR) {
res = write_audio(f->data, f->datalen);
if (res > 0)
res = 0;
} else
ast_log(LOG_DEBUG, "Unable to handle non-signed linear frame (%d)\n", f->subclass);
}
}
ast_frfree(f);
} else
res = -1;
} else
res = -1;
}
}
}
if (trans != chan)
ast_translator_destroy(trans);
} else
ast_log(LOG_WARNING, "Unable to build translator to signed linear format on '%s'\n", chan->name);
LOCAL_USER_REMOVE(u);
if (!res)
ast_set_read_format(chan, oreadformat);
return res;
}
@@ -175,7 +173,7 @@ int load_module(void)
{
if (create_audio())
return -1;
return ast_register_application(app, intercom_exec, synopsis, descrip);
return ast_register_application(app, intercom_exec);
}
char *description(void)
@@ -189,8 +187,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -33,13 +33,6 @@ static char *tdesc = "Silly MP3 Application";
static char *app = "MP3Player";
static char *synopsis = "Play an MP3 file or stream";
static char *descrip =
" MP3Player(location) Executes mpg123 to play the given location\n"
" which typically would be a filename or a URL. Returns -1 on\n"
" hangup or 0 otherwise. User can exit by pressing any key\n.";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
@@ -66,17 +59,15 @@ static int mp3_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
struct ast_channel *trans;
int fds[2];
int rfds[1 + AST_MAX_FDS];
int rfds[2];
int ms = -1;
int pid;
int us;
int exception;
int owriteformat;
struct timeval tv;
struct timeval last;
struct ast_frame *f;
int x;
struct myframe {
struct ast_frame f;
char offset[AST_FRIENDLY_OFFSET];
@@ -94,96 +85,87 @@ static int mp3_exec(struct ast_channel *chan, void *data)
}
LOCAL_USER_ADD(u);
ast_stopstream(chan);
owriteformat = chan->writeformat;
res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
return -1;
}
res = mp3play((char *)data, fds[1]);
if (res >= 0) {
pid = res;
/* Order is important -- there's almost always going to be mp3... we want to prioritize the
user */
for (x=0;x<AST_MAX_FDS;x++)
rfds[x] = chan->fds[x];
rfds[x] = fds[0];
for (;;) {
CHECK_BLOCKING(chan);
res = ast_waitfor_n_fd(rfds, AST_MAX_FDS+1, &ms, &exception);
chan->blocking = 0;
if (res < 1) {
ast_log(LOG_DEBUG, "Hangup detected\n");
res = -1;
break;
}
for(x=0;x<AST_MAX_FDS;x++)
if (res == chan->fds[x])
break;
if (x < AST_MAX_FDS) {
if (exception)
chan->exception = 1;
f = ast_read(chan);
if (!f) {
ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
if (chan->format & AST_FORMAT_SLINEAR)
trans = chan;
else
trans = ast_translator_create(chan, AST_FORMAT_SLINEAR, AST_DIRECTION_OUT);
if (trans) {
res = mp3play((char *)data, fds[1]);
if (res >= 0) {
pid = res;
/* Order is important -- there's almost always going to be mp3... we want to prioritize the
user */
rfds[0] = trans->fd;
rfds[1] = fds[0];
for (;;) {
CHECK_BLOCKING(trans);
res = ast_waitfor_n_fd(rfds, 2, &ms);
trans->blocking = 0;
if (res < 1) {
ast_log(LOG_DEBUG, "Hangup detected\n");
res = -1;
break;
}
if (f->frametype == AST_FRAME_DTMF) {
ast_log(LOG_DEBUG, "User pressed a key\n");
ast_frfree(f);
res = 0;
break;
}
ast_frfree(f);
} else if (res == fds[0]) {
gettimeofday(&tv, NULL);
if (last.tv_sec || last.tv_usec) {
/* We should wait at least a frame length */
us = sizeof(myf.frdata) / 16 * 1000;
/* Subtract 1,000,000 us for each second late we've passed */
us -= (tv.tv_sec - last.tv_sec) * 1000000;
/* And one for each us late we've passed */
us -= (tv.tv_usec - last.tv_usec);
/* Sleep that long if needed */
if (us > 0)
usleep(us);
}
last = tv;
res = read(fds[0], myf.frdata, sizeof(myf.frdata));
if (res > 0) {
myf.f.frametype = AST_FRAME_VOICE;
myf.f.subclass = AST_FORMAT_SLINEAR;
myf.f.datalen = res;
myf.f.timelen = res / 16;
myf.f.mallocd = 0;
myf.f.offset = AST_FRIENDLY_OFFSET;
myf.f.src = __PRETTY_FUNCTION__;
myf.f.data = myf.frdata;
if (ast_write(chan, &myf.f) < 0) {
} else if (res == trans->fd) {
f = ast_read(trans);
if (!f) {
ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
res = -1;
break;
}
if (f->frametype == AST_FRAME_DTMF) {
ast_log(LOG_DEBUG, "User pressed a key\n");
ast_frfree(f);
res = 0;
break;
}
ast_frfree(f);
} else if (res == fds[0]) {
gettimeofday(&tv, NULL);
if (last.tv_sec || last.tv_usec) {
/* We should wait at least a frame length */
us = sizeof(myf.frdata) / 16 * 1000;
/* Subtract 1,000,000 us for each second late we've passed */
us -= (tv.tv_sec - last.tv_sec) * 1000000;
/* And one for each us late we've passed */
us -= (tv.tv_usec - last.tv_usec);
/* Sleep that long if needed */
if (us > 0)
usleep(us);
}
last = tv;
res = read(fds[0], myf.frdata, sizeof(myf.frdata));
if (res > 0) {
myf.f.frametype = AST_FRAME_VOICE;
myf.f.subclass = AST_FORMAT_SLINEAR;
myf.f.datalen = res;
myf.f.timelen = res / 16;
myf.f.mallocd = 0;
myf.f.offset = AST_FRIENDLY_OFFSET;
myf.f.src = __PRETTY_FUNCTION__;
myf.f.data = myf.frdata;
if (ast_write(trans, &myf.f) < 0) {
res = -1;
break;
}
} else {
ast_log(LOG_DEBUG, "No more mp3\n");
res = 0;
}
} else {
ast_log(LOG_DEBUG, "No more mp3\n");
res = 0;
ast_log(LOG_DEBUG, "HuhHHH?\n");
res = -1;
break;
}
} else {
ast_log(LOG_DEBUG, "HuhHHH?\n");
res = -1;
break;
}
kill(pid, SIGTERM);
}
kill(pid, SIGTERM);
}
if (trans != chan)
ast_translator_destroy(trans);
} else
ast_log(LOG_WARNING, "No translator channel available\n");
close(fds[0]);
close(fds[1]);
LOCAL_USER_REMOVE(u);
if (!res)
ast_set_write_format(chan, owriteformat);
return res;
}
@@ -195,7 +177,7 @@ int unload_module(void)
int load_module(void)
{
return ast_register_application(app, mp3_exec, synopsis, descrip);
return ast_register_application(app, mp3_exec);
}
char *description(void)
@@ -209,8 +191,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -25,13 +25,6 @@ static char *tdesc = "Trivial Playback Application";
static char *app = "Playback";
static char *synopsis = "Play a file";
static char *descrip =
"Playback(filename): Plays back a given filename (do not put extension).\n"
"Returns -1 if the channel was hung up, or if the file does not exist.\n"
"Returns 0 otherwise.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
@@ -68,7 +61,7 @@ int unload_module(void)
int load_module(void)
{
return ast_register_application(app, playback_exec, synopsis, descrip);
return ast_register_application(app, playback_exec);
}
char *description(void)
@@ -82,8 +75,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,168 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Trivial application to record a sound file
*
* Copyright (C) 2001, Linux Support Services, Inc.
*
* Matthew Fredrickson <creslin@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
static char *tdesc = "Trivial Record Application";
static char *app = "Record";
static char *synopsis = "Record to a file";
static char *descrip =
" Record(filename:extension): Records from the channel into a given filename.\n"
" If the file exists it will be overwritten. The 'extension' is the extension\n"
" of the file type to be recorded (wav, gsm, etc). Returns -1 when the user\n"
" hangs up.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int record_exec(struct ast_channel *chan, void *data)
{
int res = 0;
int count = 0;
int percentflag = 0;
char fil[256];
char tmp[256];
char ext[10];
char * vdata; /* Used so I don't have to typecast every use of *data */
int i = 0;
int j = 0;
struct ast_filestream *s = '\0';
struct localuser *u;
struct ast_frame *f;
vdata = data; /* explained above */
/* The next few lines of code parse out the filename and header from the input string */
if (!vdata) { /* no data implies no filename or anything is present */
ast_log(LOG_WARNING, "Record requires an argument (filename)\n");
return -1;
}
for (; vdata[i] && (vdata[i] != ':') ; i++ ) {
if ((vdata[i] == '%') && (vdata[i+1] == 'd')) {
percentflag = 1; /* the wildcard is used */
}
if (i == strlen(vdata) ) {
ast_log(LOG_WARNING, "No extension found\n");
return -1;
}
fil[i] = vdata[i];
}
fil[i++] = '\0';
for (; j < 10 && i < strlen(data); i++, j++)
ext[j] = vdata[i];
ext[j] = '\0';
/* done parsing */
/* these are to allow the use of the %d in the config file for a wild card of sort to
create a new file with the inputed name scheme */
if (percentflag) {
do {
snprintf(tmp, 256, fil, count);
count++;
} while ( ast_fileexists(tmp, ext, chan->language) != -1 );
} else
strncpy(tmp, fil, 256);
/* end of routine mentioned */
LOCAL_USER_ADD(u);
if (chan->state != AST_STATE_UP) {
res = ast_answer(chan); /* Shouldn't need this, but checking to see if channel is already answered
* Theoretically asterisk should already have answered before running the app */
}
if (!res) {
/* Some code to play a nice little beep to signify the start of the record operation */
res = ast_streamfile(chan, "beep", chan->language);
if (!res) {
printf("Waiting on stream\n");
res = ast_waitstream(chan, "");
} else {
printf("streamfile failed\n");
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", chan->name);
}
ast_stopstream(chan);
/* The end of beep code. Now the recording starts */
s = ast_writefile( tmp, ext, NULL, O_CREAT|O_TRUNC|O_WRONLY , 0, 0644);
if (s) {
while ((f = ast_read(chan))) {
if (f->frametype == AST_FRAME_VOICE) {
res = ast_writestream(s, f);
if (res) {
ast_log(LOG_WARNING, "Problem writing frame\n");
break;
}
}
}
if (!f) {
ast_log(LOG_DEBUG, "Got hangup\n");
res = -1;
}
ast_closestream(s);
} else
ast_log(LOG_WARNING, "Could not create file %s\n", fil);
} else
ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, record_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -68,8 +68,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -28,14 +28,6 @@ static char *tdesc = "Generic System() application";
static char *app = "System";
static char *synopsis = "Execute a system command";
static char *descrip =
" System(command): Executes a command by using system(). Returns -1 on failure to execute\n"
" the specified command. If the command itself executes but is in error, and if there exists\n"
" a priority n + 101, where 'n' is the priority of the current instance, then the channel will\n"
" will be setup to continue at that priority level. Otherwise, System returns 0.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
@@ -74,7 +66,7 @@ int unload_module(void)
int load_module(void)
{
return ast_register_application(app, skel_exec, synopsis, descrip);
return ast_register_application(app, skel_exec);
}
char *description(void)
@@ -88,8 +80,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -54,22 +54,6 @@
static char *tdesc = "Comedian Mail (Voicemail System)";
static char *synopsis_vm =
"Leave a voicemail message";
static char *descrip_vm =
" VoiceMail([s]extension): Leaves voicemail for a given extension (must be configured in\n"
" voicemail.conf). If the extension is preceeded by an 's' then instructions for leaving\n"
" the message will be skipped. Returns -1 on error or mailbox not found, or if the user\n"
" hangs up. Otherwise, it returns 0. \n";
static char *synopsis_vmain =
"Enter voicemail system";
static char *descrip_vmain =
" VoiceMailMain(): Enters the main voicemail system for the checking of voicemail. Returns\n"
" -1 if the user hangs up or 0 otherwise.\n";
/* Leave a message */
static char *app = "VoiceMail";
@@ -152,15 +136,6 @@ static int sendmail(char *email, char *name, int msgnum, char *mailbox)
return 0;
}
static int get_date(char *s, int len)
{
struct tm *tm;
time_t t;
t = time(0);
tm = localtime(&t);
return strftime(s, len, "%a %b %e %r %Z %Y", tm);
}
static int leave_voicemail(struct ast_channel *chan, char *ext, int silent)
{
struct ast_config *cfg;
@@ -168,13 +143,10 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent)
char comment[256];
struct ast_filestream *writer=NULL, *others[MAX_OTHER_FORMATS];
char *sfmt[MAX_OTHER_FORMATS];
char txtfile[256];
FILE *txt;
int res = -1, fmtcnt=0, x;
int msgnum;
int outmsg=0;
struct ast_frame *f;
char date[256];
cfg = ast_load(VOICEMAIL_CONFIG);
if (!cfg) {
@@ -220,33 +192,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent)
msgnum++;
} while(!writer && (msgnum < MAXMSG));
if (writer) {
/* Store information */
snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
txt = fopen(txtfile, "w+");
if (txt) {
get_date(date, sizeof(date));
fprintf(txt,
"#\n"
"# Message Information file\n"
"#\n"
"origmailbox=%s\n"
"context=%s\n"
"exten=%s\n"
"priority=%d\n"
"callerchan=%s\n"
"callerid=%s\n"
"origdate=%s\n",
ext,
chan->context,
chan->exten,
chan->priority,
chan->name,
chan->callerid ? chan->callerid : "Unknown",
date);
fclose(txt);
} else
ast_log(LOG_WARNING, "Error opening text file for output\n");
/* We need to reset these values */
free(fmts);
fmt = ast_variable_retrieve(cfg, "general", "format");
@@ -368,8 +313,6 @@ static int vm_execmain(struct ast_channel *chan, void *data)
char username[80];
char password[80], *copy;
int deleted[MAXMSG];
char ntxt[256];
char txt[256];
struct ast_config *cfg;
int state;
char *dir=NULL;
@@ -380,8 +323,6 @@ static int vm_execmain(struct ast_channel *chan, void *data)
ast_log(LOG_WARNING, "No voicemail configuration\n");
goto out;
}
if (chan->state != AST_STATE_UP)
ast_answer(chan);
if (ast_streamfile(chan, "vm-login", chan->language)) {
ast_log(LOG_WARNING, "Couldn't stream login file\n");
goto out;
@@ -477,7 +418,7 @@ static int vm_execmain(struct ast_channel *chan, void *data)
ast_verbose( VERBOSE_PREFIX_3 "User '%s' logged in on channel %s with %d messages\n", username, chan->name, maxmsg);
if (!ast_streamfile(chan, "vm-instructions", chan->language)) {
for(;;) {
if (chan->stream) {
if (chan->stream || (chan->trans && chan->trans->stream)) {
d = ast_waitstream(chan, AST_DIGIT_ANY);
ast_stopstream(chan);
if (!d && (state == STATE_MESSAGE_PLAYING)) {
@@ -604,12 +545,8 @@ out:
curmsg++;
fn = get_fn(dir, x);
nfn = get_fn(dir, curmsg);
if (strcmp(fn, nfn)) {
snprintf(txt, sizeof(txt), "%s.txt", fn);
snprintf(ntxt, sizeof(ntxt), "%s.txt", nfn);
if (strcmp(fn, nfn))
ast_filerename(fn, nfn, NULL);
rename(txt, ntxt);
}
free(fn);
free(nfn);
}
@@ -617,9 +554,7 @@ out:
for (x = curmsg + 1; x<maxmsg; x++) {
fn = get_fn(dir, x);
if (fn) {
snprintf(txt, sizeof(txt), "%s.txt", fn);
ast_filedelete(fn, NULL);
unlink(txt);
free(fn);
}
}
@@ -664,9 +599,9 @@ int unload_module(void)
int load_module(void)
{
int res;
res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
res = ast_register_application(app, vm_exec);
if (!res)
res = ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
res = ast_register_application(app2, vm_execmain);
return res;
}
@@ -681,8 +616,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -17,242 +17,37 @@
#include <asterisk/options.h>
#include <asterisk/cli.h>
#include <asterisk/channel.h>
#include <asterisk/ulaw.h>
#include <asterisk/callerid.h>
#include <asterisk/module.h>
#include <stdio.h>
#include <signal.h>
#include <sched.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/select.h>
#include <string.h>
#include <errno.h>
#include <readline/readline.h>
#include <readline/history.h>
#include "asterisk.h"
#define AST_MAX_CONNECTS 128
#define NUM_MSGS 64
int option_verbose=0;
int option_debug=0;
int option_nofork=0;
int option_quiet=0;
int option_console=0;
int option_highpriority=0;
int option_remote=0;
int option_exec=0;
int fully_booted = 0;
static int ast_socket = -1; /* UNIX Socket for allowing remote control */
static int ast_consock = -1; /* UNIX Socket for controlling another asterisk */
static int mainpid;
struct console {
int fd; /* File descriptor */
int p[2]; /* Pipe */
pthread_t t; /* Thread of handler */
};
struct console consoles[AST_MAX_CONNECTS];
char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE;
static int fdprint(int fd, char *s)
{
return write(fd, s, strlen(s) + 1);
}
static void network_verboser(char *s, int pos, int replace, int complete)
{
int x;
for (x=0;x<AST_MAX_CONNECTS; x++) {
if (consoles[x].fd > -1)
fdprint(consoles[x].p[1], s);
}
}
static pthread_t lthread;
static void *netconsole(void *vconsole)
{
struct console *con = vconsole;
char hostname[256];
char tmp[512];
int res;
int max;
fd_set rfds;
if (gethostname(hostname, sizeof(hostname)))
strncpy(hostname, "<Unknown>", sizeof(hostname));
snprintf(tmp, sizeof(tmp), "%s/%d/%s\n", hostname, mainpid, ASTERISK_VERSION);
fdprint(con->fd, tmp);
for(;;) {
FD_ZERO(&rfds);
FD_SET(con->fd, &rfds);
FD_SET(con->p[0], &rfds);
max = con->fd;
if (con->p[0] > max)
max = con->p[0];
res = select(max + 1, &rfds, NULL, NULL, NULL);
if (res < 0) {
ast_log(LOG_WARNING, "select returned < 0: %s\n", strerror(errno));
continue;
}
if (FD_ISSET(con->fd, &rfds)) {
res = read(con->fd, tmp, sizeof(tmp));
if (res < 1)
break;
tmp[res] = 0;
ast_cli_command(con->fd, tmp);
}
if (FD_ISSET(con->p[0], &rfds)) {
res = read(con->p[0], tmp, sizeof(tmp));
if (res < 1) {
ast_log(LOG_ERROR, "read returned %d\n", res);
break;
}
res = write(con->fd, tmp, res);
if (res < 1)
break;
}
}
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection disconnected\n");
close(con->fd);
close(con->p[0]);
close(con->p[1]);
con->fd = -1;
return NULL;
}
static void *listener(void *unused)
{
struct sockaddr_un sun;
int s;
int len;
int x;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
for(;;) {
len = sizeof(sun);
s = accept(ast_socket, (struct sockaddr *)&sun, &len);
if (s < 0) {
ast_log(LOG_WARNING, "Accept retured %d: %s\n", s, strerror(errno));
} else {
for (x=0;x<AST_MAX_CONNECTS;x++) {
if (consoles[x].fd < 0) {
if (pipe(consoles[x].p)) {
ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
consoles[x].fd = -1;
fdprint(s, "Server failed to create pipe\n");
close(s);
break;
}
consoles[x].fd = s;
if (pthread_create(&consoles[x].t, &attr, netconsole, &consoles[x])) {
ast_log(LOG_ERROR, "Unable to spawn thread to handle connection\n");
consoles[x].fd = -1;
fdprint(s, "Server failed to spawn thread\n");
close(s);
}
break;
}
}
if (x >= AST_MAX_CONNECTS) {
fdprint(s, "No more connections allowed\n");
ast_log(LOG_WARNING, "No more connections allowed\n");
close(s);
} else if (consoles[x].fd > -1) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection\n");
}
}
}
return NULL;
}
static int ast_makesocket(void)
{
struct sockaddr_un sun;
int res;
int x;
for (x=0;x<AST_MAX_CONNECTS;x++)
consoles[x].fd = -1;
unlink(AST_SOCKET);
ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
if (ast_socket < 0) {
ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
return -1;
}
memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_LOCAL;
strncpy(sun.sun_path, AST_SOCKET, sizeof(sun.sun_path));
res = bind(ast_socket, (struct sockaddr *)&sun, sizeof(sun));
if (res) {
ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", AST_SOCKET, strerror(errno));
close(ast_socket);
ast_socket = -1;
return -1;
}
res = listen(ast_socket, 2);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", AST_SOCKET, strerror(errno));
close(ast_socket);
ast_socket = -1;
return -1;
}
ast_register_verbose(network_verboser);
pthread_create(&lthread, NULL, listener, NULL);
return 0;
}
static int ast_tryconnect(void)
{
struct sockaddr_un sun;
int res;
ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
if (ast_consock < 0) {
ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
return 0;
}
memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_LOCAL;
strncpy(sun.sun_path, AST_SOCKET, sizeof(sun.sun_path));
res = connect(ast_consock, (struct sockaddr *)&sun, sizeof(sun));
if (res) {
close(ast_consock);
ast_consock = -1;
return 0;
} else
return 1;
}
#define HIGH_PRIORITY 1
#define HIGH_PRIORITY_SCHED SCHED_RR
static void urg_handler(int num)
{
/* Called by soft_hangup to interrupt the select, read, or other
system call. We don't actually need to do anything though. */
if (option_debug)
if (option_debug)
ast_log(LOG_DEBUG, "Urgent handler\n");
signal(num, urg_handler);
return;
}
static void hup_handler(int num)
{
if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "Received HUP signal -- Reloading configs\n");
ast_module_reload();
}
static void pipe_handler(int num)
{
/* Ignore sigpipe */
}
static void set_title(char *text)
{
/* Set an X-term or screen title */
@@ -269,17 +64,14 @@ static void set_icon(char *text)
static int set_priority(int pri)
{
struct sched_param sched;
memset(&sched, 0, sizeof(sched));
/* We set ourselves to a high priority, that we might pre-empt everything
else. If your PBX has heavy activity on it, this is a good thing. */
if (pri) {
sched.sched_priority = 10;
if (sched_setscheduler(0, SCHED_RR, &sched)) {
sched.sched_priority = HIGH_PRIORITY;
if (sched_setscheduler(0, HIGH_PRIORITY_SCHED, &sched)) {
ast_log(LOG_WARNING, "Unable to set high priority\n");
return -1;
} else
if (option_verbose)
ast_verbose("Set to realtime thread\n");
}
} else {
sched.sched_priority = 0;
if (sched_setscheduler(0, SCHED_OTHER, &sched)) {
@@ -292,26 +84,19 @@ static int set_priority(int pri)
static void quit_handler(int num)
{
static pthread_mutex_t quitlock = PTHREAD_MUTEX_INITIALIZER;
char filename[80] = "";
if (option_console || option_remote) {
if (getenv("HOME"))
snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
if (strlen(filename))
write_history(filename);
rl_callback_handler_remove();
}
if (getenv("HOME"))
snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
/* Quit only once */
pthread_mutex_lock(&quitlock);
/* Called on exit */
if (option_verbose && option_console)
if (option_verbose)
ast_verbose("Asterisk ending (%d).\n", num);
else if (option_debug)
ast_log(LOG_DEBUG, "Asterisk ending (%d).\n", num);
if (ast_socket > -1)
close(ast_socket);
if (ast_consock > -1)
close(ast_consock);
if (ast_socket > -1)
unlink(AST_SOCKET);
if (strlen(filename))
write_history(filename);
exit(0);
}
@@ -349,39 +134,10 @@ static void consolehandler(char *s)
fprintf(stdout, "\nUse \"quit\" to exit\n");
}
static char cmd[1024];
static void remoteconsolehandler(char *s)
{
/* Called when readline data is available */
if (s && strlen(s))
add_history(s);
/* Give the console access to the shell */
if (s) {
if (s[0] == '!') {
if (s[1])
system(s+1);
else
system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
} else
strncpy(cmd, s, sizeof(cmd));
if (!strcasecmp(s, "help"))
fprintf(stdout, " !<command> Executes a given shell command\n");
if (!strcasecmp(s, "quit"))
quit_handler(0);
} else
fprintf(stdout, "\nUse \"quit\" to exit\n");
}
static char quit_help[] =
"Usage: quit\n"
" Exits Asterisk.\n";
static char shutdown_help[] =
"Usage: shutdown\n"
" Shuts down a running Asterisk PBX.\n";
static int handle_quit(int fd, int argc, char *argv[])
{
if (argc != 1)
@@ -392,137 +148,19 @@ static int handle_quit(int fd, int argc, char *argv[])
#define ASTERISK_PROMPT "*CLI> "
#define ASTERISK_PROMPT2 "%s*CLI> "
static struct ast_cli_entry quit = { { "quit", NULL }, handle_quit, "Exit Asterisk", quit_help };
static struct ast_cli_entry astshutdown = { { "shutdown", NULL }, handle_quit, "Shut down an Asterisk PBX", shutdown_help };
static char *cli_generator(char *text, int state)
{
return ast_cli_generator(rl_line_buffer, text, state);
}
static char *console_cli_generator(char *text, int state)
{
char buf[1024];
int res;
#if 0
fprintf(stderr, "Searching for '%s', %s %d\n", rl_line_buffer, text, state);
#endif
snprintf(buf, sizeof(buf),"_COMMAND COMPLETE \"%s\" \"%s\" %d", rl_line_buffer, text, state);
fdprint(ast_consock, buf);
res = read(ast_consock, buf, sizeof(buf));
buf[res] = '\0';
#if 0
printf("res is %d, buf is '%s'\n", res, buf);
#endif
if (strncmp(buf, "NULL", 4))
return strdup(buf);
else
return NULL;
}
static void ast_remotecontrol(char * data)
{
char buf[80];
int res;
int max;
int lastpos = 0;
fd_set rfds;
char filename[80] = "";
char *hostname;
char *cpid;
char *version;
int pid;
char tmp[80];
read(ast_consock, buf, sizeof(buf));
if (data) {
write(ast_consock, data, strlen(data) + 1);
return;
}
hostname = strtok(buf, "/");
cpid = strtok(NULL, "/");
version = strtok(NULL, "/");
if (!version)
version = "<Version Unknown>";
strtok(hostname, ".");
if (cpid)
pid = atoi(cpid);
else
pid = -1;
snprintf(tmp, sizeof(tmp), "set verbose atleast %d", option_verbose);
fdprint(ast_consock, tmp);
ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
snprintf(tmp, sizeof(tmp), ASTERISK_PROMPT2, hostname);
if (getenv("HOME"))
snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
if (strlen(filename))
read_history(filename);
ast_cli_register(&quit);
ast_cli_register(&astshutdown);
rl_callback_handler_install(tmp, remoteconsolehandler);
rl_completion_entry_function = (Function *)console_cli_generator;
for(;;) {
FD_ZERO(&rfds);
FD_SET(ast_consock, &rfds);
FD_SET(STDIN_FILENO, &rfds);
max = ast_consock;
if (STDIN_FILENO > max)
max = STDIN_FILENO;
res = select(max + 1, &rfds, NULL, NULL, NULL);
if (res < 0) {
if (errno == EINTR)
continue;
ast_log(LOG_ERROR, "select failed: %s\n", strerror(errno));
break;
}
if (FD_ISSET(STDIN_FILENO, &rfds)) {
rl_callback_read_char();
if (strlen(cmd)) {
res = write(ast_consock, cmd, strlen(cmd) + 1);
if (res < 1) {
ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
break;
}
strcpy(cmd, "");
}
}
if (FD_ISSET(ast_consock, &rfds)) {
res = read(ast_consock, buf, sizeof(buf));
if (res < 1)
break;
buf[res] = 0;
if (!lastpos)
write(STDOUT_FILENO, "\r", 2);
write(STDOUT_FILENO, buf, res);
if ((buf[res-1] == '\n') || (buf[res-2] == '\n')) {
rl_forced_update_display();
lastpos = 0;
} else {
lastpos = 1;
}
}
}
printf("\nDisconnected from Asterisk server\n");
}
int main(int argc, char *argv[])
{
char c;
fd_set rfds;
int res;
int pid;
char filename[80] = "";
char hostname[256];
char * xarg = NULL;
sigset_t sigs;
if (gethostname(hostname, sizeof(hostname)))
strncpy(hostname, "<Unknown>", sizeof(hostname));
mainpid = getpid();
ast_ulaw_init();
callerid_init();
if (getenv("HOME"))
snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
/* Check if we're root */
@@ -531,7 +169,7 @@ int main(int argc, char *argv[])
exit(1);
}
/* Check for options */
while((c=getopt(argc, argv, "fdvqprcx:")) != EOF) {
while((c=getopt(argc, argv, "dvqpc")) != EOF) {
switch(c) {
case 'd':
option_debug++;
@@ -540,14 +178,6 @@ int main(int argc, char *argv[])
case 'c':
option_console++;
option_nofork++;
break;
case 'f':
option_nofork++;
break;
case 'r':
option_remote++;
option_nofork++;
break;
case 'p':
option_highpriority++;
break;
@@ -558,60 +188,14 @@ int main(int argc, char *argv[])
case 'q':
option_quiet++;
break;
case 'x':
option_exec++;
xarg = optarg;
break;
case '?':
exit(1);
}
}
if (ast_tryconnect()) {
/* One is already running */
if (option_remote) {
if (option_exec) {
ast_remotecontrol(xarg);
quit_handler(0);
exit(0);
}
ast_register_verbose(console_verboser);
ast_verbose( "Asterisk " ASTERISK_VERSION ", Copyright (C) 1999-2001 Linux Support Services, Inc.\n");
ast_verbose( "Written by Mark Spencer <markster@linux-support.net>\n");
ast_verbose( "=========================================================================\n");
ast_remotecontrol(NULL);
quit_handler(0);
exit(0);
} else {
ast_log(LOG_ERROR, "Asterisk already running on %s. Use 'asterisk -r' to connect.\n", AST_SOCKET);
exit(1);
}
} else if (option_remote || option_exec) {
ast_log(LOG_ERROR, "Unable to connect to remote asterisk\n");
exit(1);
}
if (!option_verbose && !option_console && !option_debug) {
pid = fork();
if (pid < 0) {
ast_log(LOG_ERROR, "Unable to fork(): %s\n", strerror(errno));
exit(1);
}
if (pid)
exit(0);
}
ast_makesocket();
sigemptyset(&sigs);
sigaddset(&sigs, SIGHUP);
sigaddset(&sigs, SIGTERM);
sigaddset(&sigs, SIGINT);
sigaddset(&sigs, SIGPIPE);
sigaddset(&sigs, SIGWINCH);
pthread_sigmask(SIG_BLOCK, &sigs, NULL);
if (option_console || option_verbose || option_remote)
ast_register_verbose(console_verboser);
ast_register_verbose(console_verboser);
/* Print a welcome message if desired */
if (option_verbose || option_console) {
ast_verbose( "Asterisk " ASTERISK_VERSION ", Copyright (C) 1999-2001 Linux Support Services, Inc.\n");
ast_verbose( "Asterisk, Copyright (C) 1999 Mark Spencer\n");
ast_verbose( "Written by Mark Spencer <markster@linux-support.net>\n");
ast_verbose( "=========================================================================\n");
}
@@ -620,16 +204,15 @@ int main(int argc, char *argv[])
signal(SIGURG, urg_handler);
signal(SIGINT, quit_handler);
signal(SIGTERM, quit_handler);
signal(SIGHUP, hup_handler);
signal(SIGPIPE, pipe_handler);
if (set_priority(option_highpriority))
exit(1);
signal(SIGHUP, quit_handler);
if (init_logger())
exit(1);
if (load_pbx())
exit(1);
if (load_modules())
exit(1);
if (set_priority(option_highpriority))
exit(1);
/* We might have the option of showing a console, but for now just
do nothing... */
if (option_console && !option_verbose)
@@ -637,14 +220,12 @@ int main(int argc, char *argv[])
if (option_verbose || option_console)
ast_verbose( "Asterisk Ready.\n");
fully_booted = 1;
pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
ast_cli_register(&astshutdown);
if (option_console) {
/* Console stuff now... */
/* Register our quit function */
char title[256];
set_icon("Asterisk");
snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %d)", hostname, mainpid);
snprintf(title, sizeof(title), "Asterisk Console (pid %d)", getpid());
set_title(title);
ast_cli_register(&quit);
consolethread = pthread_self();

View File

@@ -17,7 +17,6 @@
#define DEFAULT_LANGUAGE "en"
#define AST_CONFIG_DIR "/etc/asterisk"
#define AST_SOCKET "/var/run/asterisk.ctl"
#define AST_MODULE_DIR "/usr/lib/asterisk/modules"
#define AST_SPOOL_DIR "/var/spool/asterisk"
#define AST_VAR_DIR "/var/lib/asterisk"

24
audiofile.patch Normal file
View File

@@ -0,0 +1,24 @@
diff -uNr audiofile-0.1.9.old/libaudiofile/audiofile.c audiofile-0.1.9/libaudiofile/audiofile.c
--- audiofile-0.1.9.old/libaudiofile/audiofile.c Fri Jul 23 12:57:56 1999
+++ audiofile-0.1.9/libaudiofile/audiofile.c Fri Dec 10 18:43:30 1999
@@ -488,6 +488,20 @@
return afOpenVirtualFile(af_virtual_file_new_for_file(fp), mode, setup);
}
+AFfilehandle afOpenFD(int fd, const char *mode, AFfilesetup setup)
+{
+ FILE *fp;
+
+ fp = fdopen(fd, mode);
+ if (fp == NULL)
+ {
+ _af_error(AF_BAD_OPEN);
+ return AF_NULL_FILEHANDLE;
+ }
+
+ return afOpenVirtualFile(af_virtual_file_new_for_file(fp), mode, setup);
+}
+
int afGetFileFormat (AFfilehandle file, int *version)
{
assert(file);

View File

@@ -1,526 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* CallerID Generation support
*
* Copyright (C) 2001, Linux Support Services, Inc.
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License.
*
* Includes code and algorithms from the Zapata library.
*
*/
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <asterisk/ulaw.h>
#include <asterisk/callerid.h>
#include <asterisk/logger.h>
#include <asterisk/fskmodem.h>
#include "sas.h"
#include "cas.h"
struct callerid_state {
fsk_data fskd;
char rawdata[256];
short oldstuff[160];
int oldlen;
int pos;
int type;
int cksum;
char name[64];
char number[64];
int flags;
int sawflag;
int len;
};
static float dr[4], di[4];
static float clidsb = 8000.0 / 1200.0;
#define CALLERID_SPACE 2200.0 /* 2200 hz for "0" */
#define CALLERID_MARK 1200.0 /* 1200 hz for "1" */
void callerid_init(void)
{
/* Initialize stuff for inverse FFT */
dr[0] = cos(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
di[0] = sin(CALLERID_SPACE * 2.0 * M_PI / 8000.0);
dr[1] = cos(CALLERID_MARK * 2.0 * M_PI / 8000.0);
di[1] = sin(CALLERID_MARK * 2.0 * M_PI / 8000.0);
}
struct callerid_state *callerid_new(void)
{
struct callerid_state *cid;
cid = malloc(sizeof(struct callerid_state));
memset(cid, 0, sizeof(*cid));
if (cid) {
cid->fskd.spb = 7; /* 1200 baud */
cid->fskd.hdlc = 0; /* Async */
cid->fskd.nbit = 8; /* 8 bits */
cid->fskd.nstop = 1; /* 1 stop bit */
cid->fskd.paridad = 0; /* No parity */
cid->fskd.bw=1; /* Filter 800 Hz */
cid->fskd.f_mark_idx = 2; /* 1200 Hz */
cid->fskd.f_space_idx = 3; /* 2200 Hz */
cid->fskd.pcola = 0; /* No clue */
cid->fskd.cont = 0; /* Digital PLL reset */
cid->fskd.x0 = 0.0;
cid->fskd.state = 0;
memset(cid->name, 0, sizeof(cid->name));
memset(cid->number, 0, sizeof(cid->number));
cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER;
cid->pos = 0;
} else
ast_log(LOG_WARNING, "Out of memory\n");
return cid;
}
void callerid_get(struct callerid_state *cid, char **name, char **number, int *flags)
{
*flags = cid->flags;
if (cid->flags & (CID_UNKNOWN_NAME | CID_PRIVATE_NUMBER))
*name = NULL;
else
*name = cid->name;
if (cid->flags & (CID_UNKNOWN_NUMBER | CID_PRIVATE_NUMBER))
*number = NULL;
else
*number = cid->number;
}
int ast_callerid_gen_cas(unsigned char *outbuf, int len)
{
int pos = 0;
int cnt;
int saslen=2400;
if (len < saslen)
return -1;
while(saslen) {
cnt = saslen;
if (cnt > sizeof(sas))
cnt = sizeof(sas);
memcpy(outbuf + pos, sas, cnt);
pos += cnt;
len -= cnt;
saslen -= cnt;
}
while(len) {
cnt = len;
if (cnt > sizeof(cas))
cnt = sizeof(cas);
memcpy(outbuf + pos, cas, cnt);
pos += cnt;
len -= cnt;
}
return 0;
}
int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len)
{
int mylen = len;
int olen;
int b = 'X';
int res;
int x;
short *buf = malloc(2 * len + cid->oldlen);
short *obuf = buf;
if (!buf) {
ast_log(LOG_WARNING, "Out of memory\n");
return -1;
}
memset(buf, 0, 2 * len + cid->oldlen);
memcpy(buf, cid->oldstuff, cid->oldlen);
mylen += cid->oldlen/2;
for (x=0;x<len;x++)
buf[x+cid->oldlen/2] = ast_mulaw[ubuf[x]];
while(mylen >= 80) {
olen = mylen;
res = fsk_serie(&cid->fskd, buf, &mylen, &b);
buf += (olen - mylen);
if (res < 0) {
ast_log(LOG_NOTICE, "fsk_serie failed\n");
return -1;
}
if (res == 1) {
/* Ignore invalid bytes */
if (b > 0xff)
continue;
switch(cid->sawflag) {
case 0: /* Look for flag */
if (b == 'U')
cid->sawflag = 2;
break;
case 2: /* Get lead-in */
if ((b == 0x04) || (b == 0x80)) {
cid->type = b;
cid->sawflag = 3;
cid->cksum = b;
}
break;
case 3: /* Get length */
/* Not a lead in. We're ready */
cid->sawflag = 4;
cid->len = b;
cid->pos = 0;
cid->cksum += b;
break;
case 4: /* Retrieve message */
if (cid->pos >= 128) {
ast_log(LOG_WARNING, "Caller ID too long???\n");
return -1;
}
cid->rawdata[cid->pos++] = b;
cid->len--;
cid->cksum += b;
if (!cid->len) {
cid->rawdata[cid->pos] = '\0';
cid->sawflag = 5;
}
break;
case 5: /* Check checksum */
if (b != (256 - (cid->cksum & 0xff))) {
ast_log(LOG_NOTICE, "Caller*ID failed checksum\n");
/* Try again */
cid->sawflag = 0;
break;
}
strcpy(cid->number, "");
strcpy(cid->name, "");
/* If we get this far we're fine. */
if (cid->type == 0x80) {
/* MDMF */
/* Go through each element and process */
for (x=0;x< cid->pos;) {
switch(cid->rawdata[x++]) {
case 1:
/* Date */
break;
case 2: /* Number */
case 4: /* Number */
res = cid->rawdata[x];
if (res > 32) {
ast_log(LOG_NOTICE, "Truncating long caller ID number from %d bytes to 32\n", cid->rawdata[x]);
res = 32;
}
memcpy(cid->number, cid->rawdata + x + 1, res);
/* Null terminate */
cid->number[res] = '\0';
break;
case 7: /* Name */
case 8: /* Name */
res = cid->rawdata[x];
if (res > 32) {
ast_log(LOG_NOTICE, "Truncating long caller ID name from %d bytes to 32\n", cid->rawdata[x]);
res = 32;
}
memcpy(cid->name, cid->rawdata + x + 1, res);
cid->name[res] = '\0';
break;
default:
ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x-1]);
}
x += cid->rawdata[x];
x++;
}
} else {
/* SDMF */
strncpy(cid->number, cid->rawdata + 8, sizeof(cid->number));
}
/* Update flags */
cid->flags = 0;
if (!strcmp(cid->number, "P")) {
strcpy(cid->number, "");
cid->flags |= CID_PRIVATE_NUMBER;
} else if (!strcmp(cid->number, "O") || !strlen(cid->number)) {
strcpy(cid->number, "");
cid->flags |= CID_UNKNOWN_NUMBER;
}
if (!strcmp(cid->name, "P")) {
strcpy(cid->name, "");
cid->flags |= CID_PRIVATE_NAME;
} else if (!strcmp(cid->name, "O") || !strlen(cid->name)) {
strcpy(cid->name, "");
cid->flags |= CID_UNKNOWN_NAME;
}
return 1;
break;
default:
ast_log(LOG_ERROR, "Dunno what to do with a digit in sawflag %d\n", cid->sawflag);
}
}
}
if (mylen) {
memcpy(cid->oldstuff, buf, mylen * 2);
cid->oldlen = mylen * 2;
}
free(obuf);
return 0;
}
void callerid_free(struct callerid_state *cid)
{
free(cid);
}
static void callerid_genmsg(char *msg, int size, char *number, char *name, int flags)
{
time_t t;
struct tm *tm;
char *ptr;
int res;
int i,x;
/* Get the time */
time(&t);
tm = localtime(&t);
ptr = msg;
/* Format time and message header */
res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm->tm_mon + 1,
tm->tm_mday, tm->tm_hour, tm->tm_min);
size -= res;
ptr += res;
if (!number || !strlen(number) || (flags & CID_UNKNOWN_NUMBER)) {
/* Indicate number not known */
res = snprintf(ptr, size, "\004\001O");
size -= res;
ptr += res;
} else if (flags & CID_PRIVATE_NUMBER) {
/* Indicate number is private */
res = snprintf(ptr, size, "\004\001P");
size -= res;
ptr += res;
} else {
/* Send up to 10 digits of number MAX */
i = strlen(number);
if (i > 10) i = 10;
res = snprintf(ptr, size, "\002%c", i);
size -= res;
ptr += res;
for (x=0;x<i;x++)
ptr[x] = number[x];
ptr[i] = '\0';
ptr += i;
size -= i;
}
if (!name || !strlen(name) || (flags & CID_UNKNOWN_NAME)) {
/* Indicate name not known */
res = snprintf(ptr, size, "\010\001O");
size -= res;
ptr += res;
} else if (flags & CID_PRIVATE_NAME) {
/* Indicate name is private */
res = snprintf(ptr, size, "\010\001P");
size -= res;
ptr += res;
} else {
/* Send up to 10 digits of number MAX */
i = strlen(name);
if (i > 16) i = 16;
res = snprintf(ptr, size, "\007%c", i);
size -= res;
ptr += res;
for (x=0;x<i;x++)
ptr[x] = name[x];
ptr[i] = '\0';
ptr += i;
size -= i;
}
}
static inline float callerid_getcarrier(float *cr, float *ci, int bit)
{
/* Move along. There's nothing to see here... */
float t;
t = *cr * dr[bit] - *ci * di[bit];
*ci = *cr * di[bit] + *ci * dr[bit];
*cr = t;
t = 2.0 - (*cr * *cr + *ci * *ci);
*cr *= t;
*ci *= t;
return *cr;
}
#define PUT_BYTE(a) do { \
*(buf++) = (a); \
bytes++; \
} while(0)
#define PUT_AUDIO_SAMPLE(y) do { \
int index = (short)(rint(8192.0 * (y))); \
*(buf++) = ast_lin2mu[index + 32768]; \
bytes++; \
} while(0)
#define PUT_CLID_MARKMS do { \
int x; \
for (x=0;x<8;x++) \
PUT_AUDIO_SAMPLE(callerid_getcarrier(&cr, &ci, 1)); \
} while(0)
#define PUT_CLID_BAUD(bit) do { \
while(scont < clidsb) { \
PUT_AUDIO_SAMPLE(callerid_getcarrier(&cr, &ci, bit)); \
scont += 1.0; \
} \
scont -= clidsb; \
} while(0)
#define PUT_CLID(byte) do { \
int z; \
unsigned char b = (byte); \
PUT_CLID_BAUD(0); /* Start bit */ \
for (z=0;z<8;z++) { \
PUT_CLID_BAUD(b & 1); \
b >>= 1; \
} \
PUT_CLID_BAUD(1); /* Stop bit */ \
} while(0);
int callerid_generate(unsigned char *buf, char *number, char *name, int flags, int callwaiting)
{
int bytes=0;
int x, sum;
/* Initial carriers (real/imaginary) */
float cr = 1.0;
float ci = 0.0;
float scont = 0.0;
char msg[256];
callerid_genmsg(msg, sizeof(msg), number, name, flags);
if (!callwaiting) {
/* Wait a half a second */
for (x=0;x<4000;x++)
PUT_BYTE(0x7f);
/* Transmit 30 0x55's (looks like a square wave) for channel seizure */
for (x=0;x<30;x++)
PUT_CLID(0x55);
}
/* Send 150ms of callerid marks */
for (x=0;x<150;x++)
PUT_CLID_MARKMS;
/* Send 0x80 indicating MDMF format */
PUT_CLID(0x80);
/* Put length of whole message */
PUT_CLID(strlen(msg));
sum = 0x80 + strlen(msg);
/* Put each character of message and update checksum */
for (x=0;x<strlen(msg); x++) {
PUT_CLID(msg[x]);
sum += msg[x];
}
/* Send 2's compliment of sum */
PUT_CLID(256 - (sum & 255));
/* Send 50 more ms of marks */
for (x=0;x<50;x++)
PUT_CLID_MARKMS;
return bytes;
}
void ast_shrink_phone_number(char *n)
{
int x,y=0;
for (x=0;n[x];x++)
if (!strchr("( )-.", n[x]))
n[y++] = n[x];
n[y] = '\0';
}
int ast_isphonenumber(char *n)
{
int x;
if (!n)
return 0;
for (x=0;n[x];x++)
if (!strchr("0123456789", n[x]))
return 0;
return 1;
}
int ast_callerid_parse(char *instr, char **name, char **location)
{
char *ns, *ne;
char *ls, *le;
char tmp[256];
/* Try for "name" <location> format or
name <location> format */
if ((ls = strchr(instr, '<')) && (le = strchr(ls, '>'))) {
/* Found the location */
*le = '\0';
*ls = '\0';
*location = ls + 1;
if ((ns = strchr(instr, '\"')) && (ne = strchr(ns + 1, '\"'))) {
/* Get name out of quotes */
*ns = '\0';
*ne = '\0';
*name = ns + 1;
return 0;
} else {
/* Just trim off any trailing spaces */
*name = instr;
while(strlen(instr) && (instr[strlen(instr) - 1] < 33))
instr[strlen(instr) - 1] = '\0';
/* And leading spaces */
while(**name && (**name < 33))
name++;
return 0;
}
} else {
strncpy(tmp, instr, sizeof(tmp));
ast_shrink_phone_number(tmp);
if (!ast_isphonenumber(tmp)) {
/* Assume it's just a location */
*name = NULL;
*location = instr;
} else {
/* Assume it's just a name */
*name = instr;
*location = NULL;
}
return 0;
}
return -1;
}
static int __ast_callerid_generate(unsigned char *buf, char *callerid, int callwaiting)
{
char tmp[256];
char *n, *l;
if (!callerid)
return callerid_generate(buf, NULL, NULL, 0, callwaiting);
strncpy(tmp, callerid, sizeof(tmp));
if (ast_callerid_parse(tmp, &n, &l)) {
ast_log(LOG_WARNING, "Unable to parse '%s' into CallerID name & number\n", callerid);
return callerid_generate(buf, NULL, NULL, 0, callwaiting);
}
if (l)
ast_shrink_phone_number(l);
if (!ast_isphonenumber(l))
return callerid_generate(buf, NULL, n, 0, callwaiting);
return callerid_generate(buf, l, n, 0, callwaiting);
}
int ast_callerid_generate(unsigned char *buf, char *callerid)
{
return __ast_callerid_generate(buf, callerid, 0);
}
int ast_callerid_callwaiting_generate(unsigned char *buf, char *callerid)
{
return __ast_callerid_generate(buf, callerid, 1);
}

58
cas.h
View File

@@ -1,58 +0,0 @@
/* cas.h: Generated from frequencies 2130 and 2750
by gensound. 800 samples */
static unsigned char cas[800] = {
255, 177, 60, 69, 189, 105, 95, 95, 90, 188, 78, 56, 180, 207, 48,
196, 191, 63, 117, 226, 224, 207, 60, 229, 180, 56, 66, 176, 80, 60,
194, 226, 103, 101, 74, 189, 223, 50, 190, 187, 50, 241, 186, 72, 90,
237, 238, 198, 63, 76, 177, 72, 54, 180, 215, 57, 207, 214, 120, 251,
66, 196, 193, 49, 219, 178, 57, 73, 185, 91, 83, 124, 103, 191, 75,
60, 179, 223, 48, 190, 191, 59, 241, 211, 244, 220, 63, 216, 184, 54,
74, 175, 72, 59, 189, 230, 84, 113, 83, 191, 255, 53, 187, 190, 48,
217, 185, 64, 89, 214, 243, 205, 64, 87, 179, 65, 57, 178, 233, 55,
199, 208, 90, 122, 74, 196, 201, 50, 206, 180, 53, 78, 183, 79, 77,
222, 119, 199, 74, 64, 179, 111, 49, 186, 194, 55, 222, 203, 101, 234,
69, 210, 187, 54, 84, 175, 64, 60, 185, 246, 75, 236, 96, 196, 100,
56, 185, 196, 47, 204, 184, 60, 91, 203, 117, 218, 69, 104, 182, 62,
60, 176, 104, 54, 191, 207, 77, 252, 84, 199, 210, 52, 200, 183, 51,
89, 180, 72, 74, 207, 255, 207, 74, 72, 180, 89, 51, 183, 200, 52,
210, 199, 84, 252, 77, 207, 191, 54, 104, 176, 60, 62, 182, 104, 69,
218, 117, 203, 91, 60, 184, 204, 47, 196, 185, 56, 100, 196, 96, 236,
75, 246, 185, 60, 64, 175, 84, 54, 187, 210, 69, 234, 101, 203, 222,
55, 194, 186, 49, 111, 179, 64, 74, 199, 119, 222, 77, 79, 183, 78,
53, 180, 206, 50, 201, 196, 74, 122, 90, 208, 199, 55, 233, 178, 57,
65, 179, 87, 64, 205, 243, 214, 89, 64, 185, 217, 48, 190, 187, 53,
255, 191, 83, 113, 84, 230, 189, 59, 72, 175, 74, 54, 184, 216, 63,
220, 244, 211, 241, 59, 191, 190, 48, 223, 179, 60, 75, 191, 103, 124,
83, 91, 185, 73, 57, 178, 219, 49, 193, 196, 66, 251, 120, 214, 207,
57, 215, 180, 54, 72, 177, 76, 63, 198, 238, 237, 90, 72, 186, 241,
50, 187, 190, 50, 223, 189, 74, 101, 103, 226, 194, 60, 80, 176, 66,
56, 180, 229, 60, 207, 224, 226, 117, 63, 191, 196, 48, 207, 180, 56,
78, 188, 90, 95, 95, 105, 189, 69, 60, 177, 255, 49, 188, 197, 61,
233, 223, 223, 218, 60, 206, 184, 52, 79, 176, 68, 63, 191, 245, 98,
96, 79, 188, 101, 52, 184, 194, 48, 208, 188, 66, 98, 231, 229, 202,
61, 95, 178, 62, 59, 178, 113, 58, 200, 218, 109, 110, 70, 191, 204,
49, 200, 182, 52, 87, 185, 79, 86, 248, 123, 194, 68, 65, 177, 91,
50, 185, 201, 57, 219, 211, 252, 231, 63, 203, 188, 51, 95, 176, 62,
63, 187, 113, 83, 116, 92, 191, 88, 56, 182, 202, 47, 200, 187, 61,
102, 212, 241, 211, 63, 255, 181, 59, 62, 176, 89, 57, 192, 217, 86,
115, 77, 192, 215, 51, 193, 185, 50, 105, 183, 71, 80, 218, 250, 202,
68, 73, 178, 78, 52, 181, 206, 55, 207, 205, 94, 247, 71, 202, 192,
51, 239, 177, 58, 66, 183, 94, 75, 229, 106, 197, 82, 59, 182, 212,
47, 192, 188, 57, 118, 203, 108, 224, 68, 228, 184, 57, 68, 175, 76,
56, 188, 219, 75, 245, 90, 197, 232, 54, 190, 188, 48, 232, 182, 63,
79, 205, 124, 212, 71, 82, 180, 72, 55, 179, 217, 52, 200, 202, 79,
255, 79, 202, 200, 52, 217, 179, 55, 72, 180, 82, 71, 212, 124, 205,
79, 63, 182, 232, 48, 188, 190, 54, 232, 197, 90, 245, 75, 219, 188,
56, 76, 175, 68, 57, 184, 228, 68, 224, 108, 203, 118, 57, 188, 192,
47, 212, 182, 59, 82, 197, 106, 229, 75, 94, 183, 66, 58, 177, 239,
51, 192, 202, 71, 247, 94, 205, 207, 55, 206, 181, 52, 78, 178, 73,
68, 202, 250, 218, 80, 71, 183, 105, 50, 185, 193, 51, 215, 192, 77,
115, 86, 217, 192, 57, 89, 176, 62, 59, 181, 255, 63, 211, 241, 212,
102, 61, 187, 200, 47, 202, 182, 56, 88, 191, 92, 116, 83, 113, 187,
63, 62, 176, 95, 51, 188, 203, 63, 231, 252, 211, 219, 57, 201, 185,
50, 91, 177, 65, 68, 194, 123, 248, 86, 79, 185, 87, 52, 182, 200,
49, 204, 191, 70, 110, 109, 218, 200, 58, 113, 178, 59, 62, 178, 95,
61, 202, 229, 231, 98, 66, 188, 208, 48, 194, 184, 52, 101, 188, 79,
96, 98, 245, 191, 63, 68, 176, 79, 52, 184, 206, 60, 218, 223, 223,
233, 61, 197, 188, 49,
};

676
channel.c
View File

@@ -28,7 +28,6 @@
#include <asterisk/translate.h>
/* XXX Lock appropriately in more functions XXX */
#ifdef DEBUG_MUTEX
/* Convenient mutex debugging functions */
@@ -37,16 +36,16 @@
static int __PTHREAD_MUTEX_LOCK(char *f, pthread_mutex_t *a) {
ast_log(LOG_DEBUG, "Locking %p (%s)\n", a, f);
return ast_pthread_mutex_lock(a);
return pthread_mutex_lock(a);
}
static int __PTHREAD_MUTEX_UNLOCK(char *f, pthread_mutex_t *a) {
ast_log(LOG_DEBUG, "Unlocking %p (%s)\n", a, f);
return ast_pthread_mutex_unlock(a);
return pthread_mutex_unlock(a);
}
#else
#define PTHREAD_MUTEX_LOCK(a) ast_pthread_mutex_lock(a)
#define PTHREAD_MUTEX_UNLOCK(a) ast_pthread_mutex_unlock(a)
#define PTHREAD_MUTEX_LOCK(a) pthread_mutex_lock(a)
#define PTHREAD_MUTEX_UNLOCK(a) pthread_mutex_unlock(a)
#endif
struct chanlist {
@@ -104,35 +103,10 @@ int ast_channel_register(char *type, char *description, int capabilities,
return 0;
}
char *ast_state2str(int state)
{
switch(state) {
case AST_STATE_DOWN:
return "Down";
case AST_STATE_RESERVED:
return "Rsrvd";
case AST_STATE_OFFHOOK:
return "OffHook";
case AST_STATE_DIALING:
return "Dialing";
case AST_STATE_RING:
return "Ring";
case AST_STATE_RINGING:
return "Ringing";
case AST_STATE_UP:
return "Up";
case AST_STATE_BUSY:
return "Busy";
default:
return "Unknown";
}
}
struct ast_channel *ast_channel_alloc(void)
{
struct ast_channel *tmp;
struct ast_channel_pvt *pvt;
int x;
PTHREAD_MUTEX_LOCK(&chlock);
tmp = malloc(sizeof(struct ast_channel));
memset(tmp, 0, sizeof(struct ast_channel));
@@ -142,8 +116,7 @@ struct ast_channel *ast_channel_alloc(void)
memset(pvt, 0, sizeof(struct ast_channel_pvt));
tmp->sched = sched_context_create();
if (tmp->sched) {
for (x=0;x<AST_MAX_FDS;x++)
tmp->fds[x] = -1;
tmp->fd = -1;
strncpy(tmp->name, "**Unknown**", sizeof(tmp->name));
tmp->pvt = pvt;
tmp->state = AST_STATE_DOWN;
@@ -213,11 +186,8 @@ void ast_channel_free(struct ast_channel *chan)
ast_log(LOG_WARNING, "Unable to find channel in list\n");
if (chan->pvt->pvt)
ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
/* Free translatosr */
if (chan->pvt->readtrans)
ast_translator_free_path(chan->pvt->readtrans);
if (chan->pvt->writetrans)
ast_translator_free_path(chan->pvt->writetrans);
if (chan->trans)
ast_log(LOG_WARNING, "Hard hangup called on '%s' while a translator is in place! Expect a failure.\n", chan->name);
if (chan->pbx)
ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
if (chan->dnid)
@@ -225,7 +195,6 @@ void ast_channel_free(struct ast_channel *chan)
if (chan->callerid)
free(chan->callerid);
pthread_mutex_destroy(&chan->lock);
free(chan->pvt);
free(chan);
PTHREAD_MUTEX_UNLOCK(&chlock);
}
@@ -233,10 +202,18 @@ void ast_channel_free(struct ast_channel *chan)
int ast_softhangup(struct ast_channel *chan)
{
int res = 0;
if (chan->stream)
ast_stopstream(chan);
if (option_debug)
ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
/* Inform channel driver that we need to be hung up, if it cares */
chan->softhangup = 1;
if (chan->trans)
ast_log(LOG_WARNING, "Soft hangup called on '%s' while a translator is in place! Expect a failure.\n", chan->name);
if (chan->pvt->hangup)
res = chan->pvt->hangup(chan);
if (chan->pvt->pvt)
ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
if (chan->pbx)
ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
/* Interrupt any select call or such */
if (chan->blocking)
pthread_kill(chan->blocker, SIGURG);
@@ -246,35 +223,16 @@ int ast_softhangup(struct ast_channel *chan)
int ast_hangup(struct ast_channel *chan)
{
int res = 0;
/* Don't actually hang up a channel that will masquerade as someone else, or
if someone is going to masquerade as us */
if (chan->masq)
return 0;
/* If this channel is one which will be masqueraded into something,
mark it as a zombie already, so we know to free it later */
if (chan->masqr) {
chan->zombie=1;
return 0;
}
if (chan->stream)
ast_stopstream(chan);
if (chan->sched)
sched_context_destroy(chan->sched);
if (chan->blocking) {
ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
"is blocked by thread %ld in procedure %s! Expect a failure\n",
pthread_self(), chan->name, chan->blocker, chan->blockproc);
CRASH;
}
if (!chan->zombie) {
if (option_debug)
ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
if (chan->pvt->hangup)
res = chan->pvt->hangup(chan);
} else
if (option_debug)
ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
if (chan->blocking)
ast_log(LOG_WARNING, "Hard hangup called, while fd is blocking! Expect a failure\n");
if (option_debug)
ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
if (chan->pvt->hangup)
res = chan->pvt->hangup(chan);
ast_channel_free(chan);
return res;
}
@@ -307,23 +265,15 @@ void ast_channel_unregister(char *type)
int ast_answer(struct ast_channel *chan)
{
/* Stop if we're a zombie or need a soft hangup */
if (chan->zombie || chan->softhangup)
return -1;
switch(chan->state) {
case AST_STATE_RING:
case AST_STATE_RINGING:
/* Answer the line, if possible */
if (chan->state == AST_STATE_RING) {
if (chan->pvt->answer)
return chan->pvt->answer(chan);
chan->state = AST_STATE_UP;
break;
case AST_STATE_UP:
break;
}
return 0;
}
int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
int ast_waitfor_n_fd(int *fds, int n, int *ms)
{
/* Wait for x amount of time on a file descriptor to have input. */
struct timeval tv;
@@ -337,125 +287,77 @@ int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
FD_ZERO(&rfds);
FD_ZERO(&efds);
for (x=0;x<n;x++) {
if (fds[x] > -1) {
FD_SET(fds[x], &rfds);
FD_SET(fds[x], &efds);
if (fds[x] > max)
max = fds[x];
}
FD_SET(fds[x], &rfds);
FD_SET(fds[x], &efds);
if (fds[x] > max)
max = fds[x];
}
if (*ms >= 0)
res = select(max + 1, &rfds, NULL, &efds, &tv);
else
res = select(max + 1, &rfds, NULL, &efds, NULL);
if (res < 0) {
/* Simulate a timeout if we were interrupted */
if (errno != EINTR)
*ms = -1;
else
*ms = 0;
return -1;
}
for (x=0;x<n;x++) {
if ((fds[x] > -1) && (FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && (winner < 0)) {
if (exception)
*exception = FD_ISSET(fds[x], &efds);
if ((FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && (winner < 0))
winner = fds[x];
}
}
*ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
if (res < 0)
*ms = -10;
return winner;
}
static int ast_do_masquerade(struct ast_channel *original);
struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
{
/* Wait for x amount of time on a file descriptor to have input. */
struct timeval tv;
fd_set rfds, efds;
int res;
int x, y, max=-1;
int x, max=-1;
struct ast_channel *winner = NULL;
/* Perform any pending masquerades */
for (x=0;x<n;x++) {
if (c[x]->masq) {
if (ast_do_masquerade(c[x])) {
ast_log(LOG_WARNING, "Masquerade failed\n");
*ms = -1;
return NULL;
}
}
}
tv.tv_sec = *ms / 1000;
tv.tv_usec = (*ms % 1000) * 1000;
FD_ZERO(&rfds);
FD_ZERO(&efds);
for (x=0;x<n;x++) {
for (y=0;y<AST_MAX_FDS;y++) {
if (c[x]->fds[y] > 0) {
FD_SET(c[x]->fds[y], &rfds);
FD_SET(c[x]->fds[y], &efds);
if (c[x]->fds[y] > max)
max = c[x]->fds[y];
}
}
FD_SET(c[x]->fd, &rfds);
FD_SET(c[x]->fd, &efds);
CHECK_BLOCKING(c[x]);
if (c[x]->fd > max)
max = c[x]->fd;
}
if (*ms >= 0)
res = select(max + 1, &rfds, NULL, &efds, &tv);
else
res = select(max + 1, &rfds, NULL, &efds, NULL);
if (res < 0) {
for (x=0;x<n;x++)
c[x]->blocking = 0;
/* Simulate a timeout if we were interrupted */
if (errno != EINTR)
*ms = -1;
else
*ms = 0;
return NULL;
}
for (x=0;x<n;x++) {
c[x]->blocking = 0;
for (y=0;y<AST_MAX_FDS;y++) {
if (c[x]->fds[y] > -1) {
if ((FD_ISSET(c[x]->fds[y], &rfds) || FD_ISSET(c[x]->fds[y], &efds)) && !winner) {
/* Set exception flag if appropriate */
if (FD_ISSET(c[x]->fds[y], &efds))
c[x]->exception = 1;
c[x]->fdno = y;
winner = c[x];
}
}
}
if ((FD_ISSET(c[x]->fd, &rfds) || FD_ISSET(c[x]->fd, &efds)) && !winner)
winner = c[x];
}
*ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
if (res < 0)
*ms = -10;
return winner;
}
int ast_waitfor(struct ast_channel *c, int ms)
{
struct ast_channel *chan;
chan = ast_waitfor_n(&c, 1, &ms);
if (ms < 0)
if (ast_waitfor_n(&c, 1, &ms)) {
if (ms < 0)
return -ms;
return ms;
}
/* Error if ms < 0 */
if (ms < 0)
return -1;
return ms;
return 0;
}
char ast_waitfordigit(struct ast_channel *c, int ms)
{
struct ast_frame *f;
char result = 0;
/* Stop if we're a zombie or need a soft hangup */
if (c->zombie || c->softhangup)
return -1;
/* Wait for a digit, no more than ms milliseconds total. */
while(ms && !result) {
ms = ast_waitfor(c, ms);
@@ -478,77 +380,17 @@ char ast_waitfordigit(struct ast_channel *c, int ms)
struct ast_frame *ast_read(struct ast_channel *chan)
{
struct ast_frame *f = NULL;
static struct ast_frame null_frame =
{
AST_FRAME_NULL,
};
pthread_mutex_lock(&chan->lock);
if (chan->masq) {
if (ast_do_masquerade(chan)) {
ast_log(LOG_WARNING, "Failed to perform masquerade\n");
f = NULL;
} else
f = &null_frame;
pthread_mutex_unlock(&chan->lock);
return f;
}
/* Stop if we're a zombie or need a soft hangup */
if (chan->zombie || chan->softhangup) {
pthread_mutex_unlock(&chan->lock);
return NULL;
}
chan->blocker = pthread_self();
if (chan->exception) {
if (chan->pvt->exception)
f = chan->pvt->exception(chan);
else
ast_log(LOG_WARNING, "Exception flag set, but no exception handler\n");
/* Clear the exception flag */
chan->exception = 0;
} else
if (chan->pvt->read)
f = chan->pvt->read(chan);
else
ast_log(LOG_WARNING, "No read routine on channel %s\n", chan);
if (f && (f->frametype == AST_FRAME_VOICE)) {
if (chan->pvt->readtrans) {
f = ast_translate(chan->pvt->readtrans, f, 1);
if (!f)
f = &null_frame;
}
}
/* Make sure we always return NULL in the future */
if (!f)
chan->softhangup = 1;
pthread_mutex_unlock(&chan->lock);
return f;
}
int ast_indicate(struct ast_channel *chan, int condition)
{
int res = -1;
/* Stop if we're a zombie or need a soft hangup */
if (chan->zombie || chan->softhangup)
return -1;
if (chan->pvt->indicate) {
res = chan->pvt->indicate(chan, condition);
if (res)
ast_log(LOG_WARNING, "Driver for channel '%s' failed to indicate condition %d\n", chan->name, condition);
} else
ast_log(LOG_WARNING, "Driver for channel '%s' does not support indication\n", chan->name);
return res;
}
int ast_sendtext(struct ast_channel *chan, char *text)
{
int res = 0;
/* Stop if we're a zombie or need a soft hangup */
if (chan->zombie || chan->softhangup)
return -1;
CHECK_BLOCKING(chan);
if (chan->pvt->send_text)
res = chan->pvt->send_text(chan, text);
@@ -559,19 +401,6 @@ int ast_sendtext(struct ast_channel *chan, char *text)
int ast_write(struct ast_channel *chan, struct ast_frame *fr)
{
int res = -1;
struct ast_frame *f;
/* Stop if we're a zombie or need a soft hangup */
if (chan->zombie || chan->softhangup)
return -1;
/* Handle any pending masquerades */
if (chan->masq) {
if (ast_do_masquerade(chan)) {
ast_log(LOG_WARNING, "Failed to perform masquerade\n");
return -1;
}
}
if (chan->masqr)
return 0;
CHECK_BLOCKING(chan);
switch(fr->frametype) {
case AST_FRAME_CONTROL:
@@ -584,84 +413,17 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
res = chan->pvt->send_digit(chan, fr->subclass);
break;
default:
if (chan->pvt->write) {
if (chan->pvt->writetrans) {
f = ast_translate(chan->pvt->writetrans, fr, 1);
} else
f = fr;
if (f)
res = chan->pvt->write(chan, f);
else
res = 0;
}
if (chan->pvt->write)
res = chan->pvt->write(chan, fr);
}
chan->blocking = 0;
return res;
}
int ast_set_write_format(struct ast_channel *chan, int fmts)
{
int fmt;
int native;
int res;
native = chan->nativeformats;
fmt = fmts;
res = ast_translator_best_choice(&native, &fmt);
if (res < 0) {
ast_log(LOG_NOTICE, "Unable to find a path from %d to %d\n", fmts, chan->nativeformats);
return -1;
}
/* Now we have a good choice for both. We'll write using our native format. */
chan->pvt->rawwriteformat = native;
/* User perspective is fmt */
chan->writeformat = fmt;
/* Free any write translation we have right now */
if (chan->pvt->writetrans)
ast_translator_free_path(chan->pvt->writetrans);
/* Build a translation path from the user write format to the raw writing format */
chan->pvt->writetrans = ast_translator_build_path(chan->pvt->rawwriteformat, chan->writeformat);
if (option_debug)
ast_log(LOG_DEBUG, "Set channel %s to format %d\n", chan->name, chan->writeformat);
return 0;
}
int ast_set_read_format(struct ast_channel *chan, int fmts)
{
int fmt;
int native;
int res;
native = chan->nativeformats;
fmt = fmts;
/* Find a translation path from the native read format to one of the user's read formats */
res = ast_translator_best_choice(&fmt, &native);
if (res < 0) {
ast_log(LOG_NOTICE, "Unable to find a path from %d to %d\n", chan->nativeformats, fmts);
return -1;
}
/* Now we have a good choice for both. We'll write using our native format. */
chan->pvt->rawreadformat = native;
/* User perspective is fmt */
chan->readformat = fmt;
/* Free any read translation we have right now */
if (chan->pvt->readtrans)
ast_translator_free_path(chan->pvt->readtrans);
/* Build a translation path from the raw read format to the user reading format */
chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat);
return 0;
}
struct ast_channel *ast_request(char *type, int format, void *data)
{
struct chanlist *chan;
struct ast_channel *c = NULL;
int capabilities;
int fmt;
int res;
if (PTHREAD_MUTEX_LOCK(&chlock)) {
ast_log(LOG_WARNING, "Unable to lock channel list\n");
return NULL;
@@ -669,17 +431,12 @@ struct ast_channel *ast_request(char *type, int format, void *data)
chan = backends;
while(chan) {
if (!strcasecmp(type, chan->type)) {
capabilities = chan->capabilities;
fmt = format;
res = ast_translator_best_choice(&fmt, &capabilities);
if (res < 0) {
ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format);
PTHREAD_MUTEX_UNLOCK(&chlock);
return NULL;
if (!(chan->capabilities & format)) {
format = ast_translator_best_choice(format, chan->capabilities);
}
PTHREAD_MUTEX_UNLOCK(&chlock);
if (chan->requester)
c = chan->requester(type, capabilities, data);
c = chan->requester(type, format, data);
return c;
}
chan = chan->next;
@@ -696,12 +453,8 @@ int ast_call(struct ast_channel *chan, char *addr, int timeout)
If the remote end does not answer within the timeout, then do NOT hang up, but
return anyway. */
int res = -1;
/* Stop if we're a zombie or need a soft hangup */
pthread_mutex_lock(&chan->lock);
if (!chan->zombie && !chan->softhangup)
if (chan->pvt->call)
res = chan->pvt->call(chan, addr, timeout);
pthread_mutex_unlock(&chan->lock);
if (chan->pvt->call)
res = chan->pvt->call(chan, addr, timeout);
return res;
}
@@ -710,13 +463,10 @@ int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int fti
int pos=0;
int to = ftimeout;
char d;
/* Stop if we're a zombie or need a soft hangup */
if (c->zombie || c->softhangup)
return -1;
if (!len)
return -1;
do {
if (c->streamid > -1) {
if ((c->streamid > -1) || (c->trans && (c->trans->streamid > -1))) {
d = ast_waitstream(c, AST_DIGIT_ANY);
ast_stopstream(c);
usleep(1000);
@@ -738,313 +488,3 @@ int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int fti
/* Never reached */
return 0;
}
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
{
int peerf;
int chanf;
int res;
peerf = peer->nativeformats;
chanf = chan->nativeformats;
res = ast_translator_best_choice(&peerf, &chanf);
if (res < 0) {
ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan, chan->nativeformats, peer, peer->nativeformats);
return -1;
}
/* Set read format on channel */
res = ast_set_read_format(chan, peerf);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan, chanf);
return -1;
}
/* Set write format on peer channel */
res = ast_set_write_format(peer, peerf);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer, peerf);
return -1;
}
/* Now we go the other way */
peerf = peer->nativeformats;
chanf = chan->nativeformats;
res = ast_translator_best_choice(&chanf, &peerf);
if (res < 0) {
ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer, peer->nativeformats, chan, chan->nativeformats);
return -1;
}
/* Set writeformat on channel */
res = ast_set_write_format(chan, chanf);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan, chanf);
return -1;
}
/* Set read format on peer channel */
res = ast_set_read_format(peer, chanf);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer, peerf);
return -1;
}
return 0;
}
int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
{
ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n",
clone->name, original->name);
if (original->masq) {
ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
original->masq->name, original->name);
return -1;
}
if (clone->masqr) {
ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
clone->name, clone->masqr->name);
return -1;
}
original->masq = clone;
clone->masqr = original;
return 0;
}
static int ast_do_masquerade(struct ast_channel *original)
{
int x;
int res=0;
char *tmp;
struct ast_channel_pvt *p;
struct ast_channel *clone = original->masq;
ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
clone->name, clone->state, original->name, original->state);
/* XXX This is a seriously wacked out operation. We're essentially putting the guts of
the clone channel into the original channel. Start by killing off the original
channel's backend. I'm not sure we're going to keep this function, because
while the features are nice, the cost is very high in terms of pure nastiness. XXX */
/* We need the clone's lock, too */
pthread_mutex_lock(&clone->lock);
/* Unlink the masquerade */
original->masq = NULL;
clone->masqr = NULL;
/* Copy the name from the clone channel */
strncpy(original->name, clone->name, sizeof(original->name));
/* Mangle the name of the clone channel */
strncat(clone->name, "<MASQ>", sizeof(clone->name));
/* Swap the guts */
p = original->pvt;
original->pvt = clone->pvt;
clone->pvt = p;
/* Start by disconnecting the original's physical side */
if (clone->pvt->hangup)
res = clone->pvt->hangup(clone);
if (res) {
ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n");
pthread_mutex_unlock(&clone->lock);
return -1;
}
/* Mangle the name of the clone channel */
snprintf(clone->name, sizeof(clone->name), "%s<ZOMBIE>", original->name);
/* Keep the same language. */
/* Update the type. */
original->type = clone->type;
/* Copy the FD's */
for (x=0;x<AST_MAX_FDS;x++)
original->fds[x] = clone->fds[x];
/* Bridge remains the same */
/* CDR fields remain the same */
/* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
/* Application and data remain the same */
/* Clone exception becomes real one, as with fdno */
original->exception = clone->exception;
original->fdno = clone->fdno;
/* Schedule context remains the same */
/* Stream stuff stays the same */
/* Keep the original state. The fixup code will need to work with it most likely */
/* dnid and callerid change to become the new, HOWEVER, we also link the original's
fields back into the defunct 'clone' so that they will be freed when
ast_frfree is eventually called */
tmp = original->dnid;
original->dnid = clone->dnid;
clone->dnid = tmp;
tmp = original->callerid;
original->callerid = clone->callerid;
clone->callerid = tmp;
/* Context, extension, priority, app data, jump table, remain the same */
/* pvt switches. pbx stays the same, as does next */
/* Now, at this point, the "clone" channel is totally F'd up. We mark it as
a zombie so nothing tries to touch it. If it's already been marked as a
zombie, then free it now (since it already is considered invalid). */
if (clone->zombie) {
pthread_mutex_unlock(&clone->lock);
ast_channel_free(clone);
} else {
clone->zombie=1;
pthread_mutex_unlock(&clone->lock);
}
/* Set the write format */
ast_set_write_format(original, original->writeformat);
/* Set the read format */
ast_set_read_format(original, original->readformat);
/* Okay. Last thing is to let the channel driver know about all this mess, so he
can fix up everything as best as possible */
if (original->pvt->fixup) {
res = original->pvt->fixup(clone, original);
if (res) {
ast_log(LOG_WARNING, "Driver for '%s' could not fixup channel %s\n",
original->type, original->name);
return -1;
}
} else
ast_log(LOG_WARNING, "Driver '%s' does not have a fixup routine (for %s)! Bad things may happen.\n",
original->type, original->name);
/* Signal any blocker */
if (original->blocking)
pthread_kill(original->blocker, SIGURG);
return 0;
}
int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
{
/* Copy voice back and forth between the two channels. Give the peer
the ability to transfer calls with '#<extension' syntax. */
struct ast_channel *cs[3];
int to = -1;
struct ast_frame *f;
struct ast_channel *who;
int res;
/* Stop if we're a zombie or need a soft hangup */
if (c0->zombie || c0->softhangup || c1->zombie || c1->softhangup)
return -1;
if (c0->bridge) {
ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
c0->name, c0->bridge->name);
return -1;
}
if (c1->bridge) {
ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
c1->name, c1->bridge->name);
return -1;
}
/* Keep track of bridge */
c0->bridge = c1;
c1->bridge = c0;
if (c0->pvt->bridge &&
(c0->pvt->bridge == c1->pvt->bridge)) {
/* Looks like they share a bridge code */
if (!c0->pvt->bridge(c0, c1, flags, fo, rc)) {
c0->bridge = NULL;
c1->bridge = NULL;
return 0;
}
ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name);
/* If they return non-zero then continue on normally */
}
cs[0] = c0;
cs[1] = c1;
for (/* ever */;;) {
who = ast_waitfor_n(cs, 2, &to);
if (!who) {
ast_log(LOG_WARNING, "Nobody there??\n");
continue;
}
f = ast_read(who);
if (!f) {
*fo = NULL;
*rc = who;
res = 0;
break;
}
if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
*fo = f;
*rc = who;
res = 0;
break;
}
if ((f->frametype == AST_FRAME_VOICE) ||
(f->frametype == AST_FRAME_TEXT) ||
(f->frametype == AST_FRAME_VIDEO) ||
(f->frametype == AST_FRAME_IMAGE) ||
(f->frametype == AST_FRAME_DTMF)) {
if ((f->frametype == AST_FRAME_DTMF) &&
(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
if ((who == c0)) {
if ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
*rc = c0;
*fo = f;
/* Take out of conference mode */
res = 0;
break;
} else
goto tackygoto;
} else
if ((who == c1)) {
if (flags & AST_BRIDGE_DTMF_CHANNEL_1) {
*rc = c1;
*fo = f;
res = 0;
break;
} else
goto tackygoto;
}
} else {
#if 0
ast_log(LOG_DEBUG, "Read from %s\n", who->name);
if (who == last)
ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
last = who;
#endif
tackygoto:
if (who == c0)
ast_write(c1, f);
else
ast_write(c0, f);
}
ast_frfree(f);
} else
ast_frfree(f);
/* Swap who gets priority */
cs[2] = cs[0];
cs[0] = cs[1];
cs[1] = cs[2];
}
c0->bridge = NULL;
c1->bridge = NULL;
return res;
}
int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
{
int res;
if (chan->pvt->setoption) {
res = chan->pvt->setoption(chan, option, data, datalen);
if (res < 0)
return res;
} else {
errno = ENOSYS;
return -1;
}
if (block) {
/* XXX Implement blocking -- just wait for our option frame reply, discarding
intermediate packets. XXX */
ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
return -1;
}
return 0;
}

View File

@@ -12,45 +12,29 @@
#
CHANNEL_LIBS=chan_vofr.so chan_modem.so \
chan_modem_aopen.so chan_iax.so chan_oss.so \
chan_modem_i4l.so
chan_modem_aopen.so chan_iax.so chan_oss.so
CHANNEL_LIBS+=$(shell [ -f /usr/include/linux/ixjuser.h ] && echo chan_phone.so)
CFLAGS+=-Wno-missing-prototypes -Wno-missing-declarations
CFLAGS+=$(shell [ ! -f /usr/include/linux/if_wanpipe.h ] && echo " -DOLD_SANGOMA_API")
CFLAGS+=$(shell [ -f /usr/lib/libpri.so.1 ] && echo " -DTORMENTA_PRI")
TORPRI=$(shell [ -f /usr/lib/libpri.so.1 ] && echo "-lpri")
CFLAGS+=#-DVOFRDUMPER
ZAPDIR=/usr/lib
CHANNEL_LIBS+=$(shell [ -f $(ZAPDIR)/libzap.a ] && echo "chan_tor.so")
CFLAGS+=$(shell [ -f $(ZAPDIR)/libzap.a ] && echo "-I$(ZAPDIR)")
all: $(CHANNEL_LIBS)
clean:
rm -f *.so *.o
rm -f busy.h ringtone.h gentone
%.so : %.o
$(CC) -shared -Xlinker -x -o $@ $<
gentone: gentone.c
$(CC) -o gentone gentone.c -lm
#libiax.a: libiax.o
# rm -f libiax.a
# $(AR) cr libiax.a libiax.o
busy.h: gentone
./gentone busy 480 620
ringtone.h: gentone
./gentone ringtone 440 480
chan_oss.o: chan_oss.c busy.h ringtone.h
chan_tor.so: chan_tor.o
$(CC) -shared -Xlinker -x -o $@ $< $(TORPRI) -lzap -ltonezone
#chan_iax.so: chan_iax.o libiax.a
# $(CC) -shared -Xlinker -x -o $@ $< -L. -liax
#chan_modem.so : chan_modem.o
# $(CC) -rdynamic -shared -Xlinker -x -o $@ $<

View File

@@ -1,566 +0,0 @@
/*
Copyright (c) 1997 Kolja Waschk
Name: alaw.h
Version: 1.0
Author: Marco Budde
Description: Converts a-law signals to signed linear signals and
vice versa.
This file is part of isdn2h323.
This is public domain, but if you take more from this source than
just the idea, it would be neat to see my name mentioned in your
source or readme.
*/
#define ALAW2INT(x) alaw2int[x]
#define INT2ALAW(x) int2alaw[(x>>4)+4096]
// table to convert unsigned a-law bytes to signed linear integers
const int alaw2int[256] = {
-5504,5504,-344,344,-22016,22016,-1376,1376,-2752,2752,-88,88,-11008,11008,
-688,688,-7552,7552,-472,472,-30208,30208,-1888,1888,-3776,3776,-216,216,
-15104,15104,-944,944,-4480,4480,-280,280,-17920,17920,-1120,1120,-2240,2240,
-24, 24,-8960,8960,-560,560,-6528,6528,-408,408,-26112,26112,-1632,1632,
-3264,3264,-152,152,-13056,13056,-816,816,-6016,6016,-376,376,-24064,24064,
-1504,1504,-3008,3008,-120,120,-12032,12032,-752,752,-8064,8064,-504,504,
-32256,32256,-2016,2016,-4032,4032,-248,248,-16128,16128,-1008,1008,-4992,
4992,-312,312,-19968,19968,-1248,1248,-2496,2496,-56,56,-9984,9984,-624,624,
-7040,7040,-440,440,-28160,28160,-1760,1760,-3520,3520,-184,184,-14080,14080,
-880,880,-5248,5248,-328,328,-20992,20992,-1312,1312,-2624,2624,-72,72,
-10496,10496,-656,656,-7296,7296,-456,456,-29184,29184,-1824,1824,-3648,3648,
-200,200,-14592,14592,-912,912,-4224,4224,-264,264,-16896,16896,-1056,1056,
-2112,2112, -8, 8,-8448,8448,-528,528,-6272,6272,-392,392,-25088,25088,
-1568,1568,-3136,3136,-136,136,-12544,12544,-784,784,-5760,5760,-360,360,
-23040,23040,-1440,1440,-2880,2880,-104,104,-11520,11520,-720,720,-7808,7808,
-488,488,-31232,31232,-1952,1952,-3904,3904,-232,232,-15616,15616,-976,976,
-4736,4736,-296,296,-18944,18944,-1184,1184,-2368,2368,-40,40,-9472,9472,
-592,592,-6784,6784,-424,424,-27136,27136,-1696,1696,-3392,3392,-168,168,
-13568,13568,-848,848
};
// table to convert linear shorts to a-law bytes
// shift the integer to be 12+1 bit first, then add 4096 to get
// the right index
const unsigned char int2alaw[8192] = {
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,
172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
88,88,88,88,88,88,88,88,216,216,216,216,216,216,216,216,
24,24,24,24,24,24,24,24,152,152,152,152,152,152,152,152,
120,120,120,120,120,120,120,120,248,248,248,248,248,248,248,248,
56,56,56,56,56,56,56,56,184,184,184,184,184,184,184,184,
72,72,72,72,72,72,72,72,200,200,200,200,200,200,200,200,
8,8,8,8,8,8,8,8,136,136,136,136,136,136,136,136,
104,104,104,104,104,104,104,104,232,232,232,232,232,232,232,232,
40,40,40,40,40,40,40,40,168,168,168,168,168,168,168,168,
86,86,86,86,214,214,214,214,22,22,22,22,150,150,150,150,
118,118,118,118,246,246,246,246,54,54,54,54,182,182,182,182,
70,70,70,70,198,198,198,198,6,6,6,6,134,134,134,134,
102,102,102,102,230,230,230,230,38,38,38,38,166,166,166,166,
94,94,222,222,30,30,158,158,126,126,254,254,62,62,190,190,
78,78,206,206,14,14,142,142,110,110,238,238,46,46,174,174,
82,210,18,146,114,242,50,178,66,194,2,130,98,226,34,162,
90,218,26,154,122,250,58,186,74,202,10,138,106,234,42,170,
171,43,235,107,139,11,203,75,187,59,251,123,155,27,219,91,
163,35,227,99,131,3,195,67,179,51,243,115,147,19,211,83,
175,175,47,47,239,239,111,111,143,143,15,15,207,207,79,79,
191,191,63,63,255,255,127,127,159,159,31,31,223,223,95,95,
167,167,167,167,39,39,39,39,231,231,231,231,103,103,103,103,
135,135,135,135,7,7,7,7,199,199,199,199,71,71,71,71,
183,183,183,183,55,55,55,55,247,247,247,247,119,119,119,119,
151,151,151,151,23,23,23,23,215,215,215,215,87,87,87,87,
169,169,169,169,169,169,169,169,41,41,41,41,41,41,41,41,
233,233,233,233,233,233,233,233,105,105,105,105,105,105,105,105,
137,137,137,137,137,137,137,137,9,9,9,9,9,9,9,9,
201,201,201,201,201,201,201,201,73,73,73,73,73,73,73,73,
185,185,185,185,185,185,185,185,57,57,57,57,57,57,57,57,
249,249,249,249,249,249,249,249,121,121,121,121,121,121,121,121,
153,153,153,153,153,153,153,153,25,25,25,25,25,25,25,25,
217,217,217,217,217,217,217,217,89,89,89,89,89,89,89,89,
161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85
};

View File

@@ -1,237 +0,0 @@
/*
* Signed 16-bit audio data
*
* Source: answer.raw
*
* Copyright (C) 1999, Mark Spencer and Linux Support Services
*
* Distributed under the terms of the GNU General Public License
*
*/
static signed short answer[] = {
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 0x19b7, 0x0245, 0xeee5, 0xb875, 0xd9a4, 0x6018, 0x660a, 0xc3c6,
0x8741, 0xff55, 0x4c2e, 0x2146, 0xfed2, 0xf079, 0xcbd4, 0xe561, 0x3c41, 0x3166,
0xd425, 0xdc59, 0x2748, 0x087d, 0xc72b, 0xfe3a, 0x4681, 0x14c6, 0xcf45, 0xdd38,
0xf8dd, 0x0a39, 0x3a5a, 0x32b9, 0xbfec, 0x957f, 0x15a3, 0x70f4, 0x1d95, 0xbfc4,
0xd367, 0xfda0, 0x0dc0, 0x29eb, 0x1fc2, 0xd684, 0xcab1, 0x19c7, 0x29ef, 0xe679,
0xe9d0, 0x2b82, 0x151a, 0xca9f, 0xdb68, 0x1f4a, 0x271c, 0x0e2a, 0xfb32, 0xd1b2,
0xc8ff, 0x2382, 0x6380, 0x0a52, 0xa118, 0xccbf, 0x2ddc, 0x33fd, 0x0964, 0xf2a4,
0xdd81, 0xe092, 0x1a00, 0x325c, 0xf5e3, 0xd6a1, 0x0b6c, 0x1c75, 0xe4f8, 0xe07c,
0x2082, 0x2b3e, 0xf445, 0xdaa9, 0xea13, 0xff3c, 0x245c, 0x35c1, 0xf308, 0xab53,
0xdf59, 0x4698, 0x3f3b, 0xe7f7, 0xca84, 0xed4d, 0x0c3f, 0x1e94, 0x1c2d, 0xf06f,
0xd4df, 0xff34, 0x23d8, 0x001e, 0xe3f1, 0x0b15, 0x2113, 0xf3fd, 0xd768, 0xf9a0,
0x1d31, 0x1c6e, 0x0797, 0xe3a0, 0xce6c, 0xfd7b, 0x422a, 0x2c4c, 0xd364, 0xbf42,
0x0278, 0x303e, 0x1c51, 0xf737, 0xe25a, 0xe75f, 0x0a8f, 0x22ab, 0x05f4, 0xe3f9,
0xf8c4, 0x1705, 0x0162, 0xe49f, 0xfb8b, 0x1e2b, 0x13ac, 0xf044, 0xe07b, 0xf01a,
0x1567, 0x2cbf, 0x0b75, 0xd01b, 0xd206, 0x1563, 0x38d7, 0x0f2e, 0xdb32, 0xdc30,
0x023b, 0x1e44, 0x16eb, 0xf5f7, 0xe425, 0xfa33, 0x14d5, 0x0968, 0xeff2, 0xf762,
0x1137, 0x0e59, 0xf13a, 0xe651, 0xff41, 0x1d60, 0x18fd, 0xf1e6, 0xd75f, 0xf097,
0x20ec, 0x27fa, 0xfba4, 0xd5b8, 0xe68e, 0x1657, 0x2518, 0x04f6, 0xe5a3, 0xe976,
0x0578, 0x18fa, 0x0a92, 0xec0a, 0xef2a, 0x111f, 0x12f4, 0xeec3, 0xe95e, 0x0d3a,
0x18fd, 0xff72, 0xeefc, 0xf114, 0xfaaa, 0x14ee, 0x21db, 0xf56e, 0xcb49, 0xf621,
0x3323, 0x1947, 0xe017, 0xe7e9, 0x0819, 0x0707, 0x084c, 0x0f57, 0xf152, 0xdf92,
0x104a, 0x28eb, 0xedcc, 0xd4ad, 0x1415, 0x296d, 0xed9a, 0xdf57, 0x0cc2, 0x0d95,
0xf7b5, 0x0deb, 0x0b34, 0xd713, 0xea08, 0x38d6, 0x216d, 0xc727, 0xdc32, 0x2cd2,
0x1822, 0xe2d5, 0xfeb3, 0x106c, 0xe6e5, 0xf81e, 0x2fe8, 0x01af, 0xc180, 0x037a,
0x42d8, 0xf88d, 0xc344, 0x0a4f, 0x2c4e, 0xf19d, 0xebeb, 0x162c, 0xf9e9, 0xde93,
0x1b56, 0x2c60, 0xd8aa, 0xce3e, 0x2a41, 0x2eeb, 0xdab1, 0xde32, 0x1c32, 0x0aba,
0xeabe, 0x1008, 0x136d, 0xda2f, 0xec3b, 0x31dd, 0x1130, 0xca79, 0xf5b8, 0x3423,
0x0274, 0xd27d, 0x035e, 0x1e68, 0xf641, 0xf904, 0x1691, 0xef7d, 0xd57a, 0x1c3b,
0x3c23, 0xe881, 0xc274, 0x0af5, 0x2962, 0xfa34, 0xf676, 0x0f71, 0xefcc, 0xe01f,
0x19e7, 0x276f, 0xe694, 0xe134, 0x1c3a, 0x0e8b, 0xd8e7, 0xfa81, 0x2f8b, 0x07c5,
0xd904, 0xf6fa, 0x0ca5, 0xf9a2, 0x0dc7, 0x2623, 0xec54, 0xbe23, 0x02b6, 0x4296,
0x10cd, 0xda61, 0xf11c, 0x0103, 0xf41c, 0x10b4, 0x2a03, 0xf63c, 0xce1a, 0xfdbd,
0x1fb4, 0xfc51, 0xf727, 0x1c8a, 0x04ff, 0xcf41, 0xec05, 0x2913, 0x1ce8, 0xf70c,
0xf744, 0xede8, 0xdd77, 0x0d99, 0x43f1, 0x119c, 0xc14f, 0xd60e, 0x17cb, 0x1e19,
0x0d4e, 0x0c95, 0xeed1, 0xcdf4, 0xf7a5, 0x331f, 0x1cd0, 0xeb17, 0xf082, 0xfb19,
0xe899, 0xfdeb, 0x323c, 0x2036, 0xdad3, 0xd134, 0xfd03, 0x1345, 0x1c10, 0x2239,
0xf656, 0xbc22, 0xdc3f, 0x3392, 0x3d59, 0xfd77, 0xdb4d, 0xe23f, 0xedbe, 0x0f7e,
0x35cc, 0x1947, 0xd5dc, 0xd1bf, 0x035d, 0x16fc, 0x1174, 0x1675, 0x0249, 0xd2d4,
0xd851, 0x184d, 0x32fe, 0x0f91, 0xee14, 0xe1e6, 0xdf9b, 0x016b, 0x3668, 0x2b2b,
0xe20c, 0xc554, 0xf257, 0x1c05, 0x1fc5, 0x14f0, 0xf891, 0xd41c, 0xdf83, 0x1865,
0x2de1, 0x0b16, 0xed58, 0xea0c, 0xea79, 0xfbd9, 0x22af, 0x2732, 0xf62f, 0xd389,
0xe7d9, 0x0b39, 0x1cdc, 0x1de3, 0x038a, 0xd809, 0xd5f7, 0x0b55, 0x305e, 0x1910,
0xf02e, 0xe089, 0xe7c7, 0x0195, 0x2265, 0x21da, 0xf743, 0xd8f2, 0xe978, 0x09a1,
0x190a, 0x17c5, 0x045a, 0xe46d, 0xdd06, 0xffb2, 0x2293, 0x1cfe, 0xfd4d, 0xe4f9,
0xe310, 0xfaf1, 0x1d22, 0x2376, 0x0113, 0xde3a, 0xe21b, 0x0204, 0x1ba1, 0x1bd6,
0x0333, 0xe563, 0xe104, 0xfd51, 0x1bc1, 0x1ccf, 0x0285, 0xe757, 0xe35e, 0xfaf2,
0x185d, 0x1d46, 0x06b7, 0xec13, 0xe108, 0xef6e, 0x121d, 0x2a17, 0x16a6, 0xe32c,
0xc9a9, 0xf070, 0x2f48, 0x3788, 0xfa4e, 0xc32a, 0xd9c2, 0x1fa1, 0x36fe, 0x07fa,
0xd9e4, 0xe577, 0x0e5e, 0x1755, 0xfb53, 0xed71, 0x0540, 0x19e0, 0x0301, 0xdc97,
0xe391, 0x1937, 0x367c, 0x0bc9, 0xca4c, 0xc96b, 0x105d, 0x461f, 0x2416, 0xd481,
0xbc97, 0xf8b7, 0x39af, 0x2ec9, 0xecc6, 0xcb50, 0xeee3, 0x1ffe, 0x1e8e, 0xf700,
0xe66a, 0xff58, 0x149f, 0x02e5, 0xe792, 0xf2d8, 0x1a4d, 0x225a, 0xf642, 0xce7f,
0xe6a6, 0x25e2, 0x38f5, 0x01d0, 0xc50f, 0xd243, 0x19bd, 0x3fc6, 0x14f0, 0xd2d7,
0xcdb6, 0x069a, 0x2ffe, 0x1847, 0xe6f8, 0xdf0a, 0x0337, 0x1a90, 0x067a, 0xeb5b,
0xf541, 0x143b, 0x14f2, 0xf092, 0xdc02, 0xfb91, 0x28a3, 0x2274, 0xeaa8, 0xc9e7,
0xef48, 0x2d01, 0x322e, 0xf6d2, 0xc7cb, 0xe13b, 0x1fda, 0x3217, 0x0458, 0xd690,
0xe2bf, 0x11c4, 0x21d5, 0x0291, 0xe5c8, 0xf3a9, 0x12ba, 0x11aa, 0xf22b, 0xe627,
0x03ec, 0x219a, 0x1036, 0xe2f2, 0xd93f, 0x059c, 0x2ed6, 0x1b75, 0xe227, 0xce55,
0xfb19, 0x2de0, 0x2477, 0xed08, 0xd148, 0xf307, 0x21d4, 0x2002, 0xf543, 0xdeac,
0xf7f9, 0x18a9, 0x11d6, 0xf0ef, 0xe8e4, 0x05ea, 0x1ba5, 0x0727, 0xe448, 0xe748,
0x100e, 0x265e, 0x07fc, 0xdbae, 0xde78, 0x0efa, 0x2ce0, 0x0f94, 0xddf1, 0xd9ea,
0x0797, 0x28f6, 0x12eb, 0xe60c, 0xdf46, 0x0469, 0x1fbb, 0x0ced, 0xe9f6, 0xe95f,
0x09fe, 0x1ab9, 0x02cb, 0xe5a4, 0xef2a, 0x1327, 0x1d7b, 0xfd07, 0xde3d, 0xed9c,
0x17e5, 0x22e7, 0xfe3a, 0xdb38, 0xe9b9, 0x161a, 0x2416, 0x0175, 0xde3d, 0xe9de,
0x1294, 0x1fc9, 0x00ea, 0xe2a7, 0xeee2, 0x1298, 0x1a7d, 0xfc1d, 0xe3bb, 0xf47a,
0x1642, 0x185e, 0xf727, 0xe1af, 0xf709, 0x19c3, 0x18e7, 0xf50d, 0xe010, 0xf75b,
0x1a9c, 0x18d8, 0xf4c5, 0xe0c9, 0xf865, 0x1a1c, 0x16d5, 0xf3a6, 0xe257, 0xfaf2,
0x1a44, 0x14d5, 0xf34f, 0xe4b6, 0xfc77, 0x17d5, 0x0ff8, 0xf133, 0xe8b7, 0x0344,
0x1a37, 0x0ad5, 0xe95e, 0xe61a, 0x08a5, 0x227e, 0x0e33, 0xe4a7, 0xdd70, 0x03b0,
0x25f4, 0x17b2, 0xec0a, 0xdb4e, 0xf898, 0x1ba3, 0x18f6, 0xf973, 0xe87f, 0xf77a,
0x0b93, 0x096c, 0xfb0e, 0xfb03, 0x0896, 0x0940, 0xf51d, 0xe904, 0xfdc7, 0x1dda,
0x1bf9, 0xf29b, 0xd37f, 0xea1b, 0x1f37, 0x3175, 0x07eb, 0xd3f7, 0xd46b, 0x077d,
0x2eeb, 0x1e67, 0xeeae, 0xd8c7, 0xef85, 0x1119, 0x18d3, 0x088e, 0xf953, 0xf5ad,
0xf556, 0xf63d, 0x0234, 0x167a, 0x19a1, 0xfbf9, 0xd873, 0xdd4b, 0x0f06, 0x3748,
0x21e6, 0xe181, 0xc032, 0xe79a, 0x2bec, 0x3e76, 0x0b1b, 0xce41, 0xcb23, 0xff96,
0x2d79, 0x26d1, 0xfcc7, 0xdf8a, 0xe525, 0xfd83, 0x10f1, 0x16d7, 0x0f50, 0xfaea,
0xe3f1, 0xe20f, 0x0158, 0x27d9, 0x2866, 0xf96f, 0xcb34, 0xd563, 0x11d6, 0x3d25,
0x2424, 0xe254, 0xc2c9, 0xe7cd, 0x248d, 0x34f5, 0x0c42, 0xdcd0, 0xd827, 0xfa65,
0x19eb, 0x1b50, 0x0721, 0xf396, 0xeb9c, 0xefde, 0x0016, 0x1594, 0x1cc1, 0x0658,
0xe22b, 0xd852, 0xfb3e, 0x2923, 0x2c78, 0xfc87, 0xcdb5, 0xd69c, 0x0e3c, 0x3527,
0x201f, 0xe993, 0xcf9e, 0xeb21, 0x183f, 0x25ea, 0x0c93, 0xed4d, 0xe5f9, 0xf548,
0x07fb, 0x117c, 0x0ff2, 0x0398, 0xf08c, 0xe628, 0xf489, 0x143b, 0x2419, 0x0ccf,
0xe2cc, 0xd5a6, 0xf861, 0x2615, 0x2a1b, 0xfeb4, 0xd543, 0xdc53, 0x09b4, 0x2901,
0x19ff, 0xf24a, 0xde86, 0xeec4, 0x0b7b, 0x1733, 0x0d0a, 0xfc24, 0xf1bb, 0xf110,
0xfa03, 0x0a0f, 0x15d4, 0x0e21, 0xf435, 0xe17e, 0xee90, 0x1225, 0x2527, 0x0efa,
0xe61f, 0xd916, 0xf7b8, 0x1f50, 0x2326, 0x0099, 0xe01e, 0xe473, 0x0491, 0x1b37,
0x1360, 0xfb17, 0xecd9, 0xf20d, 0x0051, 0x0aec, 0x0d4a, 0x073d, 0xfa5a, 0xeeb8,
0xf165, 0x0516, 0x17dc, 0x12da, 0xf71b, 0xe213, 0xed85, 0x0eef, 0x20c8, 0x0e09,
0xebcc, 0xe0d4, 0xf848, 0x1637, 0x19d6, 0x026b, 0xec09, 0xed00, 0xff9b, 0x0e5a,
0x0d6b, 0x026c, 0xf865, 0xf4da, 0xf888, 0x025a, 0x0cbb, 0x0d53, 0xff96, 0xeefa,
0xee80, 0x021c, 0x15d6, 0x126a, 0xf9c1, 0xe724, 0xf017, 0x0aa1, 0x18b6, 0x0b4e,
0xf2d7, 0xea91, 0xf957, 0x0cac, 0x1061, 0x03f4, 0xf6ad, 0xf476, 0xfbdf, 0x0489,
0x08b1, 0x06df, 0xffcf, 0xf766, 0xf537, 0xfddf, 0x0ad4, 0x0e15, 0x01da, 0xf205,
0xf0a0, 0x0082, 0x1066, 0x0e41, 0xfc71, 0xef1b, 0xf4ad, 0x05cd, 0x0f32, 0x07ed,
0xf9c8, 0xf401, 0xfa93, 0x04af, 0x088c, 0x04a7, 0xfe15, 0xf9f1, 0xfa64, 0xff1e,
0x0539, 0x078c, 0x02af, 0xfa1a, 0xf69d, 0xfd09, 0x075b, 0x0a3d, 0x01f2, 0xf761,
0xf642, 0xffa7, 0x08f3, 0x0830, 0xff05, 0xf7db, 0xf9bc, 0x0174, 0x068b, 0x04b2,
0xfeff, 0xfb39, 0xfc1a, 000000, 0x0371, 0x03d7, 0x00fe, 0xfd37, 0xfbe0, 0xfe78,
0x02af, 0x044a, 0x0180, 0xfd43, 0xfc00, 0xfed1, 0x02aa, 0x0346, 0x00dd, 0xfde0,
0xfbfe, 0x0114, 0x0987, 0x04bc, 0xf49d, 0xf23a, 0x06ab, 0x162e, 0x0544, 0xe76b,
0xea25, 0x1015, 0x2474, 0x0431, 0xd7d3, 0xe1ec, 0x1923, 0x2df5, 0x01cd, 0xd386,
0xe3d9, 0x1b9d, 0x2c62, 0xfeb8, 0xd31a, 0xe6ba, 0x1dbd, 0x2abb, 0xfbab, 0xd2ed,
0xe9ab, 0x1fa7, 0x28ef, 0xf8b3, 0xd2f5, 0xeca5, 0x2160, 0x26fd, 0xf5d7, 0xd334,
0xefa1, 0x22e5, 0x24ea, 0xf31b, 0xd3a9, 0xf29f, 0x2435, 0x22b6, 0xf07e, 0xd44e,
0xf59b, 0x2551, 0x2067, 0xee08, 0xd527, 0xf88e, 0x2639, 0x1e00, 0xebb6, 0xd62d,
0xfb77, 0x26eb, 0x1b85, 0xe98b, 0xd75f, 0xfe51, 0x276b, 0x18f9, 0xe78e, 0xd8b9,
0x011a, 0x27b6, 0x1660, 0xe5bb, 0xda3a, 0x03cc, 0x27cf, 0x13bd, 0xe415, 0xdbdf,
0x066a, 0x27b7, 0x1117, 0xe29e, 0xdda5, 0x08ec, 0x276e, 0x0e6d, 0xe154, 0xdf89,
0x0b52, 0x26f6, 0x0bc7, 0xe039, 0xe185, 0x0d96, 0x2653, 0x0924, 0xdf4e, 0xe399,
0x0fb9, 0x2584, 0x068b, 0xde93, 0xe5c0, 0x11b8, 0x248e, 0x03fd, 0xde08, 0xe7f8,
0x1390, 0x2372, 0x0180, 0xddaa, 0xea3c, 0x1544, 0x2231, 0xff12, 0xdd7a, 0xec89,
0x16cf, 0x20d0, 0xfcb9, 0xdd77, 0xeedb, 0x1831, 0x1f52, 0xfa77, 0xdd9f, 0xf132,
0x1969, 0x1db7, 0xf850, 0xddf1, 0xf385, 0x1a75, 0x1c06, 0xf645, 0xde6b, 0xf5d7,
0x1b5b, 0x1a3f, 0xf457, 0xdf0d, 0xf820, 0x1c13, 0x1867, 0xf288, 0xdfd2, 0xfa5f,
0x1ca1, 0x167f, 0xf0db, 0xe0ba, 0xfc92, 0x1d06, 0x148b, 0xef50, 0xe1c1, 0xfeb5,
0x1d43, 0x1290, 0xede9, 0xe2e6, 0x00c6, 0x1d58, 0x108e, 0xeca7, 0xe426, 0x02c4,
0x1d45, 0x0e8a, 0xeb8a, 0xe57f, 0x04a9, 0x1d0e, 0x0c87, 0xea92, 0xe6ec, 0x0677,
0x1cb2, 0x0a87, 0xe9be, 0xe86e, 0x082a, 0x1c34, 0x088b, 0xe912, 0xe9fe, 0x09c1,
0x1b95, 0x069c, 0xe88c, 0xeb9c, 0x0b3a, 0x1ad9, 0x04b6, 0xe82a, 0xed43, 0x0c96,
0x1a00, 0x02df, 0xe7eb, 0xeef3, 0x0dd0, 0x190d, 0x0116, 0xe7d0, 0xf0a8, 0x0eec,
0x1804, 0xff61, 0xe7d8, 0xf25d, 0x0fe6, 0x16e3, 0xfdc0, 0xe800, 0xf412, 0x10bf,
0x15b1, 0xfc36, 0xe848, 0xf5c5, 0x1176, 0x146e, 0xfac2, 0xe8ad, 0xf771, 0x120d,
0x1320, 0xf969, 0xe92e, 0xf913, 0x1282, 0x11c4, 0xf828, 0xe9cb, 0xfaac, 0x12d8,
0x1062, 0xf703, 0xea7e, 0xfc38, 0x130e, 0x0efa, 0xf5fb, 0xeb49, 0xfdb5, 0x1325,
0x0d8e, 0xf50e, 0xec26, 0xff20, 0x131e, 0x0c21, 0xf43f, 0xed15, 0x007a, 0x12fa,
0x0ab6, 0xf38d, 0xee15, 0x01be, 0x12bd, 0x094f, 0xf2f9, 0xef22, 0x02ef, 0x1265,
0x07f0, 0xf283, 0xf037, 0x0408, 0x11f6, 0x0699, 0xf226, 0xf156, 0x050a, 0x1170,
0x054b, 0xf1e8, 0xf27a, 0x05f4, 0x10d8, 0x040c, 0xf1c5, 0xf3a3, 0x06c2, 0x102c,
0x02da, 0xf1bc, 0xf4cc, 0x0779, 0x0f71, 0x01b7, 0xf1cc, 0xf5f5, 0x0815, 0x0ea7,
0x00a8, 0xf1f4, 0xf719, 0x0899, 0x0dd2, 0xffab, 0xf233, 0xf839, 0x0902, 0x0cf4,
0xfec0, 0xf288, 0xf950, 0x0952, 0x0c0e, 0xfdec, 0xf2ee, 0xfa5d, 0x0989, 0x0b23,
0xfd2d, 0xf368, 0xfb62, 0x09a7, 0x0a35, 0xfc85, 0xf3f1, 0xfc58, 0x09af, 0x0946,
0xfbf2, 0xf488, 0xfd3f, 0x09a1, 0x0859, 0xfb77, 0xf52c, 0xfe17, 0x097d, 0x076f,
0xfb14, 0xf5d8, 0xfede, 0x0945, 0x068a, 0xfac6, 0xf68d, 0xff93, 0x08fb, 0x05ad,
0xfa8e, 0xf747, 0x0034, 0x08a1, 0x04da, 0xfa6f, 0xf805, 0x00c2, 0x0836, 0x0410,
0xfa63, 0xf8c6, 0x013c, 0x07bf, 0x0354, 0xfa6c, 0xf985, 0x01a1, 0x073b, 0x02a4,
0xfa8a, 0xfa43, 0x01f1, 0x06af, 0x0204, 0xfab9, 0xfafc, 0x022c, 0x0619, 0x0175,
0xfafa, 0xfbae, 0x0252, 0x057f, 0x00f6, 0xfb4b, 0xfc5a, 0x0263, 0x04e0, 0x008b,
0xfbaa, 0xfcfa, 0x0262, 0x0440, 0x0032, 0xfc16, 0xfd90, 0x024b, 0x03a0, 0xffec,
0xfc8c, 0xfe19, 0x0225, 0x0301, 0xffb9, 0xfd0c, 0xfe93, 0x01ea, 0x0267, 0xff9c,
0xfd95, 0xfefe, 0x01a0, 0x01d3, 0xff90, 0xfe22, 0xff5a, 0x0147, 0x0145, 0xff99,
0xfeb3, 0xffa1, 0x00e0, 0x00c3, 0xffb6, 0xff46, 0xffd9, 0x006d, 0x004b, 0xffe5,
0xffda, 0xfffc, 000000, 0xfffe, 000000, 0xffff, 000000, 0xffff, 0xffff, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
000000 };

File diff suppressed because it is too large Load Diff

View File

@@ -55,9 +55,6 @@ static char language[MAX_LANGUAGE] = "";
/* Initialization String */
static char initstr[AST_MAX_INIT_STR] = "ATE1Q0";
/* Default MSN */
static char msn[AST_MAX_EXTENSION]="";
static int usecnt =0;
static int baudrate = 115200;
@@ -227,7 +224,7 @@ int ast_modem_read_response(struct ast_modem_pvt *p, int timeout)
timeout *= 1000;
strncpy(p->response, "(No Response)", sizeof(p->response));
do {
res = ast_waitfor_n_fd(&p->fd, 1, &timeout, NULL);
res = ast_waitfor_n_fd(&p->fd, 1, &timeout);
if (res < 0) {
return -1;
}
@@ -244,7 +241,7 @@ int ast_modem_expect(struct ast_modem_pvt *p, char *result, int timeout)
timeout *= 1000;
strncpy(p->response, "(No Response)", sizeof(p->response));
do {
res = ast_waitfor_n_fd(&p->fd, 1, &timeout, NULL);
res = ast_waitfor_n_fd(&p->fd, 1, &timeout);
if (res < 0) {
return -1;
}
@@ -351,8 +348,7 @@ static int modem_setup(struct ast_modem_pvt *p, int baudrate)
static int modem_hangup(struct ast_channel *ast)
{
struct ast_modem_pvt *p;
if (option_debug)
ast_log(LOG_DEBUG, "modem_hangup(%s)\n", ast->name);
ast_log(LOG_DEBUG, "modem_hangup(%s)\n", ast->name);
p = ast->pvt->pvt;
/* Hang up */
if (p->mc->hangup)
@@ -363,11 +359,11 @@ static int modem_hangup(struct ast_channel *ast)
ast->state = AST_STATE_DOWN;
memset(p->cid, 0, sizeof(p->cid));
((struct ast_modem_pvt *)(ast->pvt->pvt))->owner = NULL;
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
usecnt--;
if (usecnt < 0)
ast_log(LOG_WARNING, "Usecnt < 0???\n");
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
@@ -381,8 +377,7 @@ static int modem_answer(struct ast_channel *ast)
{
struct ast_modem_pvt *p;
int res=0;
if (option_debug)
ast_log(LOG_DEBUG, "modem_answer(%s)\n", ast->name);
ast_log(LOG_DEBUG, "modem_hangup(%s)\n", ast->name);
p = ast->pvt->pvt;
if (p->mc->answer) {
res = p->mc->answer(p);
@@ -431,8 +426,8 @@ struct ast_channel *ast_modem_new(struct ast_modem_pvt *i, int state)
if (tmp) {
snprintf(tmp->name, sizeof(tmp->name), "Modem[%s]/%s", i->mc->name, i->dev + 5);
tmp->type = type;
tmp->fds[0] = i->fd;
tmp->nativeformats = i->mc->formats;
tmp->fd = i->fd;
tmp->format = i->mc->formats;
tmp->state = state;
if (state == AST_STATE_RING)
tmp->rings = 1;
@@ -449,9 +444,9 @@ struct ast_channel *ast_modem_new(struct ast_modem_pvt *i, int state)
if (strlen(i->language))
strncpy(tmp->language,i->language, sizeof(tmp->language));
i->owner = tmp;
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
usecnt++;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
if (state != AST_STATE_DOWN) {
if (ast_pbx_start(tmp)) {
@@ -472,6 +467,7 @@ static void modem_mini_packet(struct ast_modem_pvt *i)
if (fr->frametype == AST_FRAME_CONTROL) {
if (fr->subclass == AST_CONTROL_RING) {
ast_modem_new(i, AST_STATE_RING);
restart_monitor();
}
}
}
@@ -493,14 +489,14 @@ static void *do_monitor(void *data)
for(;;) {
/* Don't let anybody kill us right away. Nobody should lock the interface list
and wait for the monitor list, but the other way around is okay. */
if (ast_pthread_mutex_lock(&monlock)) {
if (pthread_mutex_lock(&monlock)) {
ast_log(LOG_ERROR, "Unable to grab monitor lock\n");
return NULL;
}
/* Lock the interface list */
if (ast_pthread_mutex_lock(&iflock)) {
if (pthread_mutex_lock(&iflock)) {
ast_log(LOG_ERROR, "Unable to grab interface lock\n");
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
return NULL;
}
/* Build the stuff we're going to select on, that is the socket of every
@@ -523,10 +519,10 @@ static void *do_monitor(void *data)
i = i->next;
}
/* Okay, now that we know what to do, release the interface lock */
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
/* And from now on, we're okay to be killed, so release the monitor lock as well */
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
#if 0
ast_log(LOG_DEBUG, "In monitor, n=%d, pid=%d\n", n, getpid());
#endif
@@ -541,7 +537,7 @@ static void *do_monitor(void *data)
}
/* Alright, lock the interface list again, and let's look and see what has
happened */
if (ast_pthread_mutex_lock(&iflock)) {
if (pthread_mutex_lock(&iflock)) {
ast_log(LOG_WARNING, "Unable to lock the interface list\n");
continue;
}
@@ -557,7 +553,7 @@ static void *do_monitor(void *data)
}
i=i->next;
}
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
}
/* Never reached */
return NULL;
@@ -569,12 +565,12 @@ static int restart_monitor()
/* If we're supposed to be stopped -- stay stopped */
if (monitor_thread == -2)
return 0;
if (ast_pthread_mutex_lock(&monlock)) {
if (pthread_mutex_lock(&monlock)) {
ast_log(LOG_WARNING, "Unable to lock monitor\n");
return -1;
}
if (monitor_thread == pthread_self()) {
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
ast_log(LOG_WARNING, "Cannot kill myself\n");
return -1;
}
@@ -586,29 +582,14 @@ static int restart_monitor()
}
/* Start a new monitor */
if (pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
return -1;
}
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
return 0;
}
static void stty(struct ast_modem_pvt *p)
{
struct termios mode;
memset(&mode, 0, sizeof(mode));
if (tcgetattr(p->fd, &mode)) {
ast_log(LOG_WARNING, "Unable to get serial parameters on %s: %s\n", p->dev, strerror(errno));
return;
}
cfmakeraw(&mode);
cfsetspeed(&mode, B115200);
if (tcsetattr(p->fd, TCSANOW, &mode))
ast_log(LOG_WARNING, "Unable to set serial parameters on %s: %s\n", p->dev, strerror(errno));
}
static struct ast_modem_pvt *mkif(char *iface)
{
/* Make a ast_modem_pvt structure for this interface */
@@ -618,7 +599,6 @@ static struct ast_modem_pvt *mkif(char *iface)
#endif
tmp = malloc(sizeof(struct ast_modem_pvt));
memset(tmp, 0, sizeof(struct ast_modem_pvt));
if (tmp) {
tmp->fd = open(iface, O_RDWR | O_NONBLOCK);
if (tmp->fd < 0) {
@@ -627,11 +607,6 @@ static struct ast_modem_pvt *mkif(char *iface)
return NULL;
}
strncpy(tmp->language, language, sizeof(tmp->language));
strncpy(tmp->msn, msn, sizeof(tmp->msn));
strncpy(tmp->dev, iface, sizeof(tmp->dev));
/* Maybe in the future we want to allow variable
serial settings */
stty(tmp);
tmp->f = fdopen(tmp->fd, "w+");
/* Disable buffering */
setvbuf(tmp->f, NULL, _IONBF,0);
@@ -650,6 +625,7 @@ static struct ast_modem_pvt *mkif(char *iface)
tmp->dialtype = dialtype;
tmp->mode = gmode;
memset(tmp->cid, 0, sizeof(tmp->cid));
strncpy(tmp->dev, iface, sizeof(tmp->dev));
strncpy(tmp->context, context, sizeof(tmp->context));
strncpy(tmp->initstr, initstr, sizeof(tmp->initstr));
tmp->next = NULL;
@@ -674,7 +650,7 @@ static struct ast_channel *modem_request(char *type, int format, void *data)
strtok(dev, ":");
oldformat = format;
/* Search for an unowned channel */
if (ast_pthread_mutex_lock(&iflock)) {
if (pthread_mutex_lock(&iflock)) {
ast_log(LOG_ERROR, "Unable to lock interface list???\n");
return NULL;
}
@@ -697,7 +673,7 @@ static struct ast_channel *modem_request(char *type, int format, void *data)
if (!p)
ast_log(LOG_WARNING, "Requested device '%s' does not exist\n", p->dev);
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
return tmp;
}
@@ -714,7 +690,7 @@ int load_module()
ast_log(LOG_ERROR, "Unable to load config %s\n", config);
return -1;
}
if (ast_pthread_mutex_lock(&iflock)) {
if (pthread_mutex_lock(&iflock)) {
/* It's a little silly to lock it, but we mind as well just to be sure */
ast_log(LOG_ERROR, "Unable to lock interface list???\n");
return -1;
@@ -731,9 +707,9 @@ int load_module()
} else {
ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
ast_destroy(cfg);
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
unload_module();
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
return -1;
}
} else if (!strcasecmp(v->name, "driver")) {
@@ -744,7 +720,7 @@ int load_module()
if (ast_load_resource(driver)) {
ast_log(LOG_ERROR, "Failed to load driver %s\n", driver);
ast_destroy(cfg);
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
unload_module();
return -1;
}
@@ -767,16 +743,13 @@ int load_module()
dialtype = toupper(v->value[0]);
} else if (!strcasecmp(v->name, "context")) {
strncpy(context, v->value, sizeof(context));
} else if (!strcasecmp(v->name, "msn")) {
strncpy(msn, v->value, sizeof(msn));
} else if (!strcasecmp(v->name, "language")) {
strncpy(language, v->value, sizeof(language));
}
v = v->next;
}
ast_pthread_mutex_unlock(&iflock);
if (ast_channel_register(type, tdesc, /* XXX Don't know our types -- maybe we should register more than one XXX */
AST_FORMAT_SLINEAR, modem_request)) {
pthread_mutex_unlock(&iflock);
if (ast_channel_register(type, tdesc, /* XXX Don't know our types -- maybe we should register more than one XXX */ AST_FORMAT_SLINEAR, modem_request)) {
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
ast_destroy(cfg);
unload_module();
@@ -793,7 +766,7 @@ int unload_module()
struct ast_modem_pvt *p, *pl;
/* First, take us out of the channel loop */
ast_channel_unregister(type);
if (!ast_pthread_mutex_lock(&iflock)) {
if (!pthread_mutex_lock(&iflock)) {
/* Hangup all interfaces if they have an owner */
p = iflist;
while(p) {
@@ -802,24 +775,24 @@ int unload_module()
p = p->next;
}
iflist = NULL;
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
return -1;
}
if (!ast_pthread_mutex_lock(&monlock)) {
if (!pthread_mutex_lock(&monlock)) {
if (monitor_thread > -1) {
pthread_cancel(monitor_thread);
pthread_join(monitor_thread, NULL);
}
monitor_thread = -2;
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
return -1;
}
if (!ast_pthread_mutex_lock(&iflock)) {
if (!pthread_mutex_lock(&iflock)) {
/* Destroy all the interfaces and free their memory */
p = iflist;
while(p) {
@@ -832,7 +805,7 @@ int unload_module()
free(pl);
}
iflist = NULL;
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
return -1;
@@ -844,9 +817,9 @@ int unload_module()
int usecount(void)
{
int res;
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
res = usecnt;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
return res;
}
@@ -855,8 +828,3 @@ char *description()
return desc;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -363,17 +363,17 @@ static char *aopen_identify(struct ast_modem_pvt *p)
static void aopen_incusecnt()
{
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
usecnt++;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
}
static void aopen_decusecnt()
{
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
usecnt++;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
}
@@ -457,9 +457,9 @@ static struct ast_modem_driver aopen_driver =
int usecount(void)
{
int res;
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
res = usecnt;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
return res;
}
@@ -478,7 +478,3 @@ char *description()
return desc;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,578 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* ISDN4Linux TTY Driver
*
* Copyright (C) 2001, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <asterisk/vmodem.h>
#include <asterisk/module.h>
#include <asterisk/frame.h>
#include <asterisk/logger.h>
#include <asterisk/options.h>
#include "alaw.h"
#define STATE_COMMAND 0
#define STATE_VOICE 1
static char *breakcmd = "\0x10\0x14\0x10\0x3";
static char *desc = "ISDN4Linux Emulated Modem Driver";
int usecnt;
pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
static char *i4l_idents[] = {
/* Identify ISDN4Linux Driver */
"Linux ISDN",
NULL
};
static int i4l_setdev(struct ast_modem_pvt *p, int dev)
{
char cmd[80];
if ((dev != MODEM_DEV_TELCO) && (dev != MODEM_DEV_TELCO_SPK)) {
ast_log(LOG_WARNING, "ISDN4Linux only supports telco device, not %d.\n", dev);
return -1;
} else /* Convert DEV to our understanding of it */
dev = 2;
if (ast_modem_send(p, "AT+VLS?", 0)) {
ast_log(LOG_WARNING, "Unable to select current mode %d\n", dev);
return -1;
}
if (ast_modem_read_response(p, 5)) {
ast_log(LOG_WARNING, "Unable to select device %d\n", dev);
return -1;
}
ast_modem_trim(p->response);
strncpy(cmd, p->response, sizeof(cmd));
if (ast_modem_expect(p, "OK", 5)) {
ast_log(LOG_WARNING, "Modem did not respond properly\n");
return -1;
}
if (dev == atoi(cmd)) {
/* We're already in the right mode, don't bother changing for fear of
hanging up */
return 0;
}
snprintf(cmd, sizeof(cmd), "AT+VLS=%d", dev);
if (ast_modem_send(p, cmd, 0)) {
ast_log(LOG_WARNING, "Unable to select device %d\n", dev);
return -1;
}
if (ast_modem_read_response(p, 5)) {
ast_log(LOG_WARNING, "Unable to select device %d\n", dev);
return -1;
}
ast_modem_trim(p->response);
if (strcasecmp(p->response, "VCON") && strcasecmp(p->response, "OK")) {
ast_log(LOG_WARNING, "Unexpected reply: %s\n", p->response);
return -1;
}
return 0;
}
static int i4l_startrec(struct ast_modem_pvt *p)
{
if (ast_modem_send(p, "AT+VRX+VTX", 0) ||
ast_modem_expect(p, "CONNECT", 5)) {
ast_log(LOG_WARNING, "Unable to start recording\n");
return -1;
}
p->ministate = STATE_VOICE;
return 0;
}
static int i4l_break(struct ast_modem_pvt *p)
{
if (ast_modem_send(p, breakcmd, 2)) {
ast_log(LOG_WARNING, "Failed to break\n");
return -1;
}
if (ast_modem_send(p, "\r\n", 2)) {
ast_log(LOG_WARNING, "Failed to send enter?\n");
return -1;
}
#if 0
/* Read any outstanding junk */
while(!ast_modem_read_response(p, 1));
#endif
if (ast_modem_send(p, "AT", 0)) {
/* Modem might be stuck in some weird mode, try to get it out */
ast_modem_send(p, "+++", 3);
if (ast_modem_expect(p, "OK", 10)) {
ast_log(LOG_WARNING, "Modem is not responding\n");
return -1;
}
if (ast_modem_send(p, "AT", 0)) {
ast_log(LOG_WARNING, "Modem is not responding\n");
return -1;
}
}
if (ast_modem_expect(p, "OK", 5)) {
ast_log(LOG_WARNING, "Modem did not respond properly\n");
return -1;
}
return 0;
}
static int i4l_init(struct ast_modem_pvt *p)
{
char cmd[256];
if (option_debug)
ast_log(LOG_DEBUG, "i4l_init()\n");
if (i4l_break(p))
return -1;
/* Force into command mode */
p->ministate = STATE_COMMAND;
if (ast_modem_send(p, "AT+FCLASS=8", 0) ||
ast_modem_expect(p, "OK", 5)) {
ast_log(LOG_WARNING, "Unable to set to voice mode\n");
return -1;
}
if (strlen(p->msn)) {
snprintf(cmd, sizeof(cmd), "AT&E%s", p->msn);
if (ast_modem_send(p, cmd, 0) ||
ast_modem_expect(p, "OK", 5)) {
ast_log(LOG_WARNING, "Unable to set MSN to %s\n", p->msn);
return -1;
}
}
if (ast_modem_send(p, "ATS18=1", 0) ||
ast_modem_expect(p, "OK", 5)) {
ast_log(LOG_WARNING, "Unable to set to audio only mode\n");
return -1;
}
if (ast_modem_send(p, "ATS14=4", 0) ||
ast_modem_expect(p, "OK", 5)) {
ast_log(LOG_WARNING, "Unable to set to transparent mode\n");
return -1;
}
if (ast_modem_send(p, "ATS23=1", 0) ||
ast_modem_expect(p, "OK", 5)) {
ast_log(LOG_WARNING, "Unable to set to transparent mode\n");
return -1;
}
if (ast_modem_send(p, "AT+VSM=5", 0) ||
ast_modem_expect(p, "OK", 5)) {
ast_log(LOG_WARNING, "Unable to set to aLAW mode\n");
return -1;
}
if (ast_modem_send(p, "AT+VLS=2", 0) ||
ast_modem_expect(p, "OK", 5)) {
ast_log(LOG_WARNING, "Unable to set to phone line interface\n");
return -1;
}
p->escape = 0;
return 0;
}
static struct ast_frame *i4l_handle_escape(struct ast_modem_pvt *p, char esc)
{
/* Handle escaped characters -- but sometimes we call it directly as
a quick way to cause known responses */
p->fr.frametype = AST_FRAME_NULL;
p->fr.subclass = 0;
p->fr.data = NULL;
p->fr.datalen = 0;
p->fr.timelen = 0;
p->fr.offset = 0;
p->fr.mallocd = 0;
if (esc && option_debug)
ast_log(LOG_DEBUG, "Escaped character '%c'\n", esc);
switch(esc) {
case 'R': /* Pseudo ring */
p->fr.frametype = AST_FRAME_CONTROL;
p->fr.subclass = AST_CONTROL_RING;
return &p->fr;
case 'X': /* Pseudo connect */
p->fr.frametype = AST_FRAME_CONTROL;
p->fr.subclass = AST_CONTROL_ANSWER;
if (p->owner)
p->owner->state = AST_STATE_UP;
if (i4l_startrec(p))
return NULL;
return &p->fr;
case 'b': /* Busy signal */
p->fr.frametype = AST_FRAME_CONTROL;
p->fr.subclass = AST_CONTROL_BUSY;
return &p->fr;
case 'o': /* Overrun */
ast_log(LOG_WARNING, "Overflow on modem, flushing buffers\n");
if (ast_modem_send(p, "\0x10E", 2))
ast_log(LOG_WARNING, "Unable to flush buffers\n");
return &p->fr;
case CHAR_ETX: /* End Transmission */
return NULL;
case 'u': /* Underrun */
ast_log(LOG_WARNING, "Data underrun\n");
/* Fall Through */
case 'd': /* Dialtone */
case 'c': /* Calling Tone */
case 'e': /* European version */
case 'a': /* Answer Tone */
case 'f': /* Bell Answer Tone */
case 'T': /* Timing mark */
case 't': /* Handset off hook */
case 'h': /* Handset hungup */
/* Ignore */
if (option_debug)
ast_log(LOG_DEBUG, "Ignoring Escaped character '%c' (%d)\n", esc, esc);
return &p->fr;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '*':
case '#':
ast_log(LOG_DEBUG, "DTMF: '%c' (%d)\n", esc, esc);
p->fr.frametype=AST_FRAME_DTMF;
p->fr.subclass=esc;
return &p->fr;
case 0: /* Pseudo signal */
return &p->fr;
default:
ast_log(LOG_DEBUG, "Unknown Escaped character '%c' (%d)\n", esc, esc);
}
return &p->fr;
}
static struct ast_frame *i4l_read(struct ast_modem_pvt *p)
{
char result[256];
short *b;
struct ast_frame *f=NULL;
int res;
int x;
if (p->ministate == STATE_COMMAND) {
/* Read the first two bytes, first, in case it's a control message */
read(p->fd, result, 2);
if (result[0] == CHAR_DLE) {
return i4l_handle_escape(p, result[1]);
} else {
if ((result[0] == '\n') || (result[0] == '\r'))
return i4l_handle_escape(p, 0);
/* Read the rest of the line */
fgets(result + 2, sizeof(result) - 2, p->f);
ast_modem_trim(result);
if (!strcasecmp(result, "VCON")) {
/* If we're in immediate mode, reply now */
if (p->mode == MODEM_MODE_IMMEDIATE)
return i4l_handle_escape(p, 'X');
} else
if (!strcasecmp(result, "BUSY")) {
/* Same as a busy signal */
return i4l_handle_escape(p, 'b');
} else
if (!strncasecmp(result, "CALLER NUMBER: ", 15 )) {
strncpy(p->cid, result + 15, sizeof(p->cid));
return i4l_handle_escape(p, 'R');
} else
if (!strncasecmp(result, "RING", 4)) {
if (result[4]=='/')
strncpy(p->dnid, result + 4, sizeof(p->dnid));
return i4l_handle_escape(p, 'R');
} else
if (!strcasecmp(result, "NO CARRIER")) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "%s hung up on\n", p->dev);
return NULL;
} else
if (!strcasecmp(result, "NO DIALTONE")) {
/* There's no dialtone, so the line isn't working */
ast_log(LOG_WARNING, "Device '%s' lacking dialtone\n", p->dev);
return NULL;
}
if (option_debug)
ast_log(LOG_DEBUG, "Modem said '%s'\n", result);
return i4l_handle_escape(p, 0);
}
} else {
/* We have to be more efficient in voice mode */
b = (short *)(p->obuf + p->obuflen);
while (p->obuflen/2 < 240) {
/* Read ahead the full amount */
res = read(p->fd, result, 240 - p->obuflen/2);
if (res < 1) {
/* If there's nothing there, just continue on */
if (errno == EAGAIN)
return i4l_handle_escape(p, 0);
ast_log(LOG_WARNING, "Read failed: %s\n", strerror(errno));
}
for (x=0;x<res;x++) {
/* Process all the bytes that we've read */
switch(result[x]) {
case CHAR_DLE:
#if 0
ast_log(LOG_DEBUG, "Ooh, an escape at %d...\n", x);
#endif
if (!p->escape) {
/* Note that next value is
an escape, and continue. */
p->escape++;
break;
} else {
/* Send as is -- fallthrough */
p->escape = 0;
}
default:
if (p->escape) {
ast_log(LOG_DEBUG, "Value of escape is %c (%d)...\n", result[x] < 32 ? '^' : result[x], result[x]);
p->escape = 0;
if (f)
ast_log(LOG_WARNING, "Warning: Dropped a signal frame\n");
f = i4l_handle_escape(p, result[x]);
/* If i4l_handle_escape says NULL, say it now, doesn't matter
what else is there, the connection is dead. */
if (!f)
return NULL;
} else {
*(b++) = ALAW2INT(result[x] & 0xff);
p->obuflen += 2;
}
}
}
if (f)
break;
}
if (f)
return f;
/* If we get here, we have a complete voice frame */
p->fr.frametype = AST_FRAME_VOICE;
p->fr.subclass = AST_FORMAT_SLINEAR;
p->fr.timelen = 30;
p->fr.data = p->obuf;
p->fr.datalen = p->obuflen;
p->fr.mallocd = 0;
p->fr.offset = AST_FRIENDLY_OFFSET;
p->fr.src = __FUNCTION__;
p->obuflen = 0;
return &p->fr;
}
return NULL;
}
static int i4l_write(struct ast_modem_pvt *p, struct ast_frame *f)
{
#define MAX_WRITE_SIZE 512
unsigned char result[MAX_WRITE_SIZE << 1];
unsigned char b;
int bpos=0, x;
int res;
if (f->datalen > MAX_WRITE_SIZE) {
ast_log(LOG_WARNING, "Discarding too big frame of size %d\n", f->datalen);
return -1;
}
if (f->frametype != AST_FRAME_VOICE) {
ast_log(LOG_WARNING, "Don't know how to handle %d type frames\n", f->frametype);
return -1;
}
if (f->subclass != AST_FORMAT_SLINEAR) {
ast_log(LOG_WARNING, "Don't know how to handle anything but signed linear frames\n");
return -1;
}
for (x=0;x<f->datalen/2;x++) {
b = INT2ALAW(((short *)f->data)[x]);
result[bpos++] = b;
if (b == CHAR_DLE)
result[bpos++]=b;
}
#if 0
res = fwrite(result, bpos, 1, p->f);
res *= bpos;
#else
res = write(p->fd, result, bpos);
#endif
if (res < 1) {
ast_log(LOG_WARNING, "Failed to write buffer\n");
return -1;
}
#if 0
printf("Result of write is %d\n", res);
#endif
return 0;
}
static char *i4l_identify(struct ast_modem_pvt *p)
{
return strdup("Linux ISDN");
}
static void i4l_incusecnt()
{
ast_pthread_mutex_lock(&usecnt_lock);
usecnt++;
ast_pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
}
static void i4l_decusecnt()
{
ast_pthread_mutex_lock(&usecnt_lock);
usecnt++;
ast_pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
}
static int i4l_answer(struct ast_modem_pvt *p)
{
if (ast_modem_send(p, "ATA", 0) ||
ast_modem_expect(p, "VCON", 10)) {
ast_log(LOG_WARNING, "Unable to answer: %s", p->response);
return -1;
}
#if 1
if (ast_modem_send(p, "AT+VDD=0,8", 0) ||
ast_modem_expect(p, "OK", 5)) {
ast_log(LOG_WARNING, "Unable to set to phone line interface\n");
return -1;
}
#endif
if (ast_modem_send(p, "AT+VTX+VRX", 0) ||
ast_modem_expect(p, "CONNECT", 10)) {
ast_log(LOG_WARNING, "Unable to answer: %s", p->response);
return -1;
}
p->ministate = STATE_VOICE;
return 0;
}
static int i4l_dialdigit(struct ast_modem_pvt *p, char digit)
{
char c[2];
if (p->ministate == STATE_VOICE) {
c[0] = CHAR_DLE;
c[1] = digit;
write(p->fd, c, 2);
} else
ast_log(LOG_DEBUG, "Asked to send digit but call not up on %s\n", p->dev);
return 0;
}
static int i4l_dial(struct ast_modem_pvt *p, char *stuff)
{
char cmd[80];
snprintf(cmd, sizeof(cmd), "ATD%c %s", p->dialtype,stuff);
if (ast_modem_send(p, cmd, 0)) {
ast_log(LOG_WARNING, "Unable to dial\n");
return -1;
}
return 0;
}
static int i4l_hangup(struct ast_modem_pvt *p)
{
char dummy[50];
sprintf(dummy, "%c%c", 0x10, 0x3);
if (write(p->fd, dummy, 2) < 0) {
ast_log(LOG_WARNING, "Failed to break\n");
return -1;
}
/* Read anything outstanding */
while(read(p->fd, dummy, sizeof(dummy)) > 0);
sprintf(dummy, "%c%c", 0x10, 0x14);
if (write(p->fd, dummy, 2) < 0) {
ast_log(LOG_WARNING, "Failed to break\n");
return -1;
}
ast_modem_expect(p, "VCON", 1);
#if 0
if (ast_modem_expect(p, "VCON", 8)) {
ast_log(LOG_WARNING, "Didn't get expected VCON\n");
return -1;
}
#endif
write(p->fd, "\n\n", 2);
read(p->fd, dummy, sizeof(dummy));
/* Hangup by switching to data, then back to voice */
if (ast_modem_send(p, "ATH", 0) ||
ast_modem_expect(p, "NO CARRIER", 8)) {
ast_log(LOG_WARNING, "Unable to hang up\n");
return -1;
}
if (ast_modem_expect(p, "OK", 5)) {
ast_log(LOG_WARNING, "Final 'OK' not received\n");
return -1;
}
return 0;
}
static struct ast_modem_driver i4l_driver =
{
"i4l",
i4l_idents,
AST_FORMAT_SLINEAR,
0, /* Not full duplex */
i4l_incusecnt, /* incusecnt */
i4l_decusecnt, /* decusecnt */
i4l_identify, /* identify */
i4l_init, /* init */
i4l_setdev, /* setdev */
i4l_read,
i4l_write,
i4l_dial, /* dial */
i4l_answer, /* answer */
i4l_hangup, /* hangup */
i4l_startrec, /* start record */
NULL, /* stop record */
NULL, /* start playback */
NULL, /* stop playback */
NULL, /* set silence supression */
i4l_dialdigit, /* dialdigit */
};
int usecount(void)
{
int res;
ast_pthread_mutex_lock(&usecnt_lock);
res = usecnt;
ast_pthread_mutex_unlock(&usecnt_lock);
return res;
}
int load_module(void)
{
return ast_register_modem_driver(&i4l_driver);
}
int unload_module(void)
{
return ast_unregister_modem_driver(&i4l_driver);
}
char *description()
{
return desc;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -33,10 +33,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <linux/soundcard.h>
#include "busy.h"
#include "ringtone.h"
#include "ring10.h"
#include "answer.h"
/* Which device to use */
#define DEV_DSP "/dev/dsp"
@@ -47,7 +43,7 @@
/* When you set the frame size, you have to come up with
the right buffer format as well. */
/* 5 64-byte frames = one frame */
#define BUFFER_FMT ((buffersize * 10) << 16) | (0x0006);
#define BUFFER_FMT ((buffersize * 5) << 16) | (0x0006);
/* Don't switch between read/write modes faster than every 300 ms */
#define MIN_SWITCH_TIME 600
@@ -74,32 +70,10 @@ static char context[AST_MAX_EXTENSION] = "default";
static char language[MAX_LANGUAGE] = "";
static char exten[AST_MAX_EXTENSION] = "s";
/* Command pipe */
static int cmd[2];
int hookstate=0;
static short silence[FRAME_SIZE] = {0, };
struct sound {
int ind;
short *data;
int datalen;
int samplen;
int silencelen;
int repeat;
};
static struct sound sounds[] = {
{ AST_CONTROL_RINGING, ringtone, sizeof(ringtone)/2, 16000, 32000, 1 },
{ AST_CONTROL_BUSY, busy, sizeof(busy)/2, 4000, 4000, 1 },
{ AST_CONTROL_CONGESTION, busy, sizeof(busy)/2, 2000, 2000, 1 },
{ AST_CONTROL_RING, ring10, sizeof(ring10)/2, 16000, 32000, 1 },
{ AST_CONTROL_ANSWER, answer, sizeof(answer)/2, 2200, 0, 0 },
};
/* Sound command pipe */
static int sndcmd[2];
/* Some pipes to prevent overflow */
static int funnel[2];
static pthread_mutex_t sound_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_t silly;
static struct chan_oss_pvt {
/* We only have one OSS structure -- near sighted perhaps, but it
@@ -125,7 +99,6 @@ static int time_has_passed()
with 160 sample frames, and a buffer size of 3, we have a 60ms buffer,
usually plenty. */
pthread_t sthread;
#define MAX_BUFFER_SIZE 100
static int buffersize = 3;
@@ -154,108 +127,6 @@ static int calc_loudness(short *frame)
return sum;
}
static int cursound = -1;
static int sampsent = 0;
static int silencelen=0;
static int offset=0;
static int nosound=0;
static int send_sound(void)
{
short myframe[FRAME_SIZE];
int total = FRAME_SIZE;
short *frame = NULL;
int amt=0;
int res;
int myoff;
audio_buf_info abi;
if (cursound > -1) {
res = ioctl(sounddev, SNDCTL_DSP_GETOSPACE ,&abi);
if (res) {
ast_log(LOG_WARNING, "Unable to read output space\n");
return -1;
}
/* Calculate how many samples we can send, max */
if (total > (abi.fragments * abi.fragsize / 2))
total = abi.fragments * abi.fragsize / 2;
res = total;
if (sampsent < sounds[cursound].samplen) {
myoff=0;
while(total) {
amt = total;
if (amt > (sounds[cursound].datalen - offset))
amt = sounds[cursound].datalen - offset;
memcpy(myframe + myoff, sounds[cursound].data + offset, amt * 2);
total -= amt;
offset += amt;
sampsent += amt;
myoff += amt;
if (offset >= sounds[cursound].datalen)
offset = 0;
}
/* Set it up for silence */
if (sampsent >= sounds[cursound].samplen)
silencelen = sounds[cursound].silencelen;
frame = myframe;
} else {
if (silencelen > 0) {
frame = silence;
silencelen -= res;
} else {
if (sounds[cursound].repeat) {
/* Start over */
sampsent = 0;
offset = 0;
} else {
cursound = -1;
nosound = 0;
}
}
}
res = write(sounddev, frame, res * 2);
if (res > 0)
return 0;
return res;
}
return 0;
}
static void *sound_thread(void *unused)
{
fd_set rfds;
fd_set wfds;
int max;
int res;
for(;;) {
FD_ZERO(&rfds);
FD_ZERO(&wfds);
max = sndcmd[0];
FD_SET(sndcmd[0], &rfds);
if (cursound > -1) {
FD_SET(sounddev, &wfds);
if (sounddev > max)
max = sounddev;
}
res = select(max + 1, &rfds, &wfds, NULL, NULL);
if (res < 1) {
ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
continue;
}
if (FD_ISSET(sndcmd[0], &rfds)) {
read(sndcmd[0], &cursound, sizeof(cursound));
silencelen = 0;
offset = 0;
sampsent = 0;
}
if (FD_ISSET(sounddev, &wfds))
if (send_sound())
ast_log(LOG_WARNING, "Failed to write sound\n");
}
/* Never reached */
return NULL;
}
#if 0
static int silence_suppress(short *buf)
{
#define SILBUF 3
@@ -288,23 +159,57 @@ static int silence_suppress(short *buf)
/* Write any buffered silence we have, it may have something
important */
if (silbufcnt) {
write(sounddev, silbuf, silbufcnt * FRAME_SIZE);
write(funnel[1], silbuf, silbufcnt * FRAME_SIZE);
silbufcnt = 0;
}
}
return 0;
}
#endif
static void *silly_thread(void *ignore)
{
char buf[FRAME_SIZE * 2];
int pos=0;
int res=0;
/* Read from the sound device, and write to the pipe. */
for (;;) {
/* Give the writer a better shot at the lock */
#if 0
usleep(1000);
#endif
pthread_testcancel();
pthread_mutex_lock(&sound_lock);
res = read(sounddev, buf + pos, FRAME_SIZE * 2 - pos);
pthread_mutex_unlock(&sound_lock);
if (res > 0) {
pos += res;
if (pos == FRAME_SIZE * 2) {
if (needhangup || needanswer || strlen(digits) ||
!silence_suppress((short *)buf)) {
res = write(funnel[1], buf, sizeof(buf));
}
pos = 0;
}
} else {
close(funnel[1]);
break;
}
pthread_testcancel();
}
return NULL;
}
static int setformat(void)
{
int fmt, desired, res, fd = sounddev;
static int warnedalready = 0;
static int warnedalready2 = 0;
pthread_mutex_lock(&sound_lock);
fmt = AFMT_S16_LE;
res = ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set format to 16-bit signed\n");
pthread_mutex_unlock(&sound_lock);
return -1;
}
res = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
@@ -317,6 +222,7 @@ static int setformat(void)
res = ioctl(fd, SNDCTL_DSP_STEREO, &fmt);
if (res < 0) {
ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
pthread_mutex_unlock(&sound_lock);
return -1;
}
/* 8000 Hz desired */
@@ -325,6 +231,7 @@ static int setformat(void)
res = ioctl(fd, SNDCTL_DSP_SPEED, &fmt);
if (res < 0) {
ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
pthread_mutex_unlock(&sound_lock);
return -1;
}
if (fmt != desired) {
@@ -339,6 +246,7 @@ static int setformat(void)
ast_log(LOG_WARNING, "Unable to set fragment size -- sound may be choppy\n");
}
#endif
pthread_mutex_unlock(&sound_lock);
return 0;
}
@@ -348,6 +256,7 @@ static int soundcard_setoutput(int force)
int fd = sounddev;
if (full_duplex || (!readmode && !force))
return 0;
pthread_mutex_lock(&sound_lock);
readmode = 0;
if (force || time_has_passed()) {
ioctl(sounddev, SNDCTL_DSP_RESET);
@@ -355,21 +264,26 @@ static int soundcard_setoutput(int force)
time. */
/* dup2(0, sound); */
close(sounddev);
fd = open(DEV_DSP, O_WRONLY |O_NONBLOCK);
fd = open(DEV_DSP, O_WRONLY);
if (fd < 0) {
ast_log(LOG_WARNING, "Unable to re-open DSP device: %s\n", strerror(errno));
pthread_mutex_unlock(&sound_lock);
return -1;
}
/* dup2 will close the original and make fd be sound */
if (dup2(fd, sounddev) < 0) {
ast_log(LOG_WARNING, "dup2() failed: %s\n", strerror(errno));
pthread_mutex_unlock(&sound_lock);
return -1;
}
if (setformat()) {
pthread_mutex_unlock(&sound_lock);
return -1;
}
pthread_mutex_unlock(&sound_lock);
return 0;
}
pthread_mutex_unlock(&sound_lock);
return 1;
}
@@ -378,35 +292,41 @@ static int soundcard_setinput(int force)
int fd = sounddev;
if (full_duplex || (readmode && !force))
return 0;
pthread_mutex_lock(&sound_lock);
readmode = -1;
if (force || time_has_passed()) {
ioctl(sounddev, SNDCTL_DSP_RESET);
close(sounddev);
/* dup2(0, sound); */
fd = open(DEV_DSP, O_RDONLY | O_NONBLOCK);
fd = open(DEV_DSP, O_RDONLY);
if (fd < 0) {
ast_log(LOG_WARNING, "Unable to re-open DSP device: %s\n", strerror(errno));
pthread_mutex_unlock(&sound_lock);
return -1;
}
/* dup2 will close the original and make fd be sound */
if (dup2(fd, sounddev) < 0) {
ast_log(LOG_WARNING, "dup2() failed: %s\n", strerror(errno));
pthread_mutex_unlock(&sound_lock);
return -1;
}
if (setformat()) {
pthread_mutex_unlock(&sound_lock);
return -1;
}
pthread_mutex_unlock(&sound_lock);
return 0;
}
pthread_mutex_unlock(&sound_lock);
return 1;
}
static int soundcard_init()
{
/* Assume it's full duplex for starters */
int fd = open(DEV_DSP, O_RDWR | O_NONBLOCK);
int fd = open(DEV_DSP, O_RDWR);
if (fd < 0) {
ast_log(LOG_WARNING, "Unable to open %s: %s\n", DEV_DSP, strerror(errno));
ast_log(LOG_ERROR, "Unable to open %s: %s\n", DEV_DSP, strerror(errno));
return fd;
}
gettimeofday(&lasttime, NULL);
@@ -431,52 +351,33 @@ static int oss_text(struct ast_channel *c, char *text)
static int oss_call(struct ast_channel *c, char *dest, int timeout)
{
int res = 3;
ast_verbose( " << Call placed to '%s' on console >> \n", dest);
if (autoanswer) {
ast_verbose( " << Auto-answered >> \n" );
needanswer = 1;
} else {
ast_verbose( " << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
write(sndcmd[1], &res, sizeof(res));
}
return 0;
}
static void answer_sound(void)
{
int res;
nosound = 1;
res = 4;
write(sndcmd[1], &res, sizeof(res));
}
static int oss_answer(struct ast_channel *c)
{
ast_verbose( " << Console call has been answered >> \n");
answer_sound();
c->state = AST_STATE_UP;
cursound = -1;
return 0;
}
static int oss_hangup(struct ast_channel *c)
{
int res;
cursound = -1;
c->pvt->pvt = NULL;
oss.owner = NULL;
ast_verbose( " << Hangup on console >> \n");
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
usecnt--;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
needhangup = 0;
needanswer = 0;
if (hookstate) {
res = 2;
write(sndcmd[1], &res, sizeof(res));
}
return 0;
}
@@ -484,11 +385,12 @@ static int soundcard_writeframe(short *data)
{
/* Write an exactly FRAME_SIZE sized of frame */
static int bufcnt = 0;
static short buffer[FRAME_SIZE * MAX_BUFFER_SIZE * 5];
static char buffer[FRAME_SIZE * 2 * MAX_BUFFER_SIZE * 5];
struct audio_buf_info info;
int res;
int fd = sounddev;
static int warned=0;
pthread_mutex_lock(&sound_lock);
if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info)) {
if (!warned)
ast_log(LOG_WARNING, "Error reading output space\n");
@@ -505,12 +407,13 @@ static int soundcard_writeframe(short *data)
} else {
/* Copy the data into our buffer */
res = FRAME_SIZE * 2;
memcpy(buffer + (bufcnt * FRAME_SIZE), data, FRAME_SIZE * 2);
memcpy(buffer + (bufcnt * FRAME_SIZE * 2), data, FRAME_SIZE * 2);
bufcnt++;
if (bufcnt == buffersize) {
res = write(fd, ((void *)buffer), FRAME_SIZE * 2 * buffersize);
}
}
pthread_mutex_unlock(&sound_lock);
return res;
}
@@ -522,11 +425,6 @@ static int oss_write(struct ast_channel *chan, struct ast_frame *f)
static int sizpos = 0;
int len = sizpos;
int pos;
/* Immediately return if no sound is enabled */
if (nosound)
return 0;
/* Stop any currently playing sound */
cursound = -1;
if (!full_duplex && (strlen(digits) || needhangup || needanswer)) {
/* If we're half duplex, we have to switch to read mode
to honor immediate needs if necessary */
@@ -570,18 +468,11 @@ static struct ast_frame *oss_read(struct ast_channel *chan)
static char buf[FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET];
static int readpos = 0;
int res;
int b;
int nonull=0;
#if 0
ast_log(LOG_DEBUG, "oss_read()\n");
#endif
/* Acknowledge any pending cmd */
res = read(cmd[0], &b, sizeof(b));
if (res > 0)
nonull = 1;
f.frametype = AST_FRAME_NULL;
f.subclass = 0;
f.timelen = 0;
@@ -618,9 +509,6 @@ static struct ast_frame *oss_read(struct ast_channel *chan)
return &f;
}
if (nonull)
return &f;
res = soundcard_setinput(0);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set input mode\n");
@@ -630,15 +518,14 @@ static struct ast_frame *oss_read(struct ast_channel *chan)
/* Theoretically shouldn't happen, but anyway, return a NULL frame */
return &f;
}
res = read(sounddev, buf + AST_FRIENDLY_OFFSET + readpos, FRAME_SIZE * 2 - readpos);
res = read(funnel[0], buf + AST_FRIENDLY_OFFSET + readpos, FRAME_SIZE * 2 - readpos);
if (res < 0) {
ast_log(LOG_WARNING, "Error reading from sound device: %s\n", strerror(errno));
CRASH;
return NULL;
}
readpos += res;
if (readpos >= FRAME_SIZE * 2) {
if (readpos == FRAME_SIZE * 2) {
/* A real frame */
readpos = 0;
f.frametype = AST_FRAME_VOICE;
@@ -649,47 +536,10 @@ static struct ast_frame *oss_read(struct ast_channel *chan)
f.offset = AST_FRIENDLY_OFFSET;
f.src = type;
f.mallocd = 0;
#if 0
{ static int fd = -1;
if (fd < 0)
fd = open("output.raw", O_RDWR | O_TRUNC | O_CREAT);
write(fd, f.data, f.datalen);
}
#endif
}
return &f;
}
static int oss_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
{
struct chan_oss_pvt *p = newchan->pvt->pvt;
p->owner = newchan;
return 0;
}
static int oss_indicate(struct ast_channel *chan, int cond)
{
int res;
switch(cond) {
case AST_CONTROL_BUSY:
res = 1;
break;
case AST_CONTROL_CONGESTION:
res = 2;
break;
case AST_CONTROL_RINGING:
res = 0;
break;
default:
ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, chan->name);
return -1;
}
if (res > -1) {
write(sndcmd[1], &res, sizeof(res));
}
return 0;
}
static struct ast_channel *oss_new(struct chan_oss_pvt *p, int state)
{
struct ast_channel *tmp;
@@ -697,9 +547,8 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *p, int state)
if (tmp) {
snprintf(tmp->name, sizeof(tmp->name), "OSS/%s", DEV_DSP + 5);
tmp->type = type;
tmp->fds[0] = sounddev;
tmp->fds[1] = cmd[0];
tmp->nativeformats = AST_FORMAT_SLINEAR;
tmp->fd = funnel[0];
tmp->format = AST_FORMAT_SLINEAR;
tmp->pvt->pvt = p;
tmp->pvt->send_digit = oss_digit;
tmp->pvt->send_text = oss_text;
@@ -708,8 +557,6 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *p, int state)
tmp->pvt->read = oss_read;
tmp->pvt->call = oss_call;
tmp->pvt->write = oss_write;
tmp->pvt->indicate = oss_indicate;
tmp->pvt->fixup = oss_fixup;
if (strlen(p->context))
strncpy(tmp->context, p->context, sizeof(tmp->context));
if (strlen(p->exten))
@@ -718,9 +565,9 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *p, int state)
strncpy(tmp->language, language, sizeof(tmp->language));
p->owner = tmp;
tmp->state = state;
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
usecnt++;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
if (state != AST_STATE_DOWN) {
if (ast_pbx_start(tmp)) {
@@ -803,10 +650,7 @@ static int console_answer(int fd, int argc, char *argv[])
ast_cli(fd, "No one is calling us\n");
return RESULT_FAILURE;
}
hookstate = 1;
cursound = -1;
needanswer++;
answer_sound();
return RESULT_SUCCESS;
}
@@ -842,14 +686,11 @@ static int console_hangup(int fd, int argc, char *argv[])
{
if (argc != 1)
return RESULT_SHOWUSAGE;
cursound = -1;
if (!oss.owner && !hookstate) {
if (!oss.owner) {
ast_cli(fd, "No call to hangup up\n");
return RESULT_FAILURE;
}
hookstate = 0;
if (oss.owner)
needhangup++;
needhangup++;
return RESULT_SUCCESS;
}
@@ -862,15 +703,12 @@ static int console_dial(int fd, int argc, char *argv[])
{
char tmp[256], *tmp2;
char *mye, *myc;
int b = 0;
if ((argc != 1) && (argc != 2))
return RESULT_SHOWUSAGE;
if (oss.owner) {
if (argc == 2) {
if (argc == 2)
strncat(digits, argv[1], sizeof(digits) - strlen(digits));
/* Wake up the polling thread */
write(cmd[1], &b, sizeof(b));
} else {
else {
ast_cli(fd, "You're already in a call. You can use this only to dial digits until you hangup\n");
return RESULT_FAILURE;
}
@@ -890,7 +728,6 @@ static int console_dial(int fd, int argc, char *argv[])
if (ast_exists_extension(NULL, myc, mye, 1)) {
strncpy(oss.exten, mye, sizeof(oss.exten));
strncpy(oss.context, myc, sizeof(oss.context));
hookstate = 1;
oss_new(&oss, AST_STATE_UP);
} else
ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
@@ -917,28 +754,28 @@ int load_module()
int flags;
struct ast_config *cfg = ast_load(config);
struct ast_variable *v;
res = pipe(cmd);
res = pipe(sndcmd);
res = pipe(funnel);
if (res) {
ast_log(LOG_ERROR, "Unable to create pipe\n");
return -1;
}
flags = fcntl(cmd[0], F_GETFL);
fcntl(cmd[0], F_SETFL, flags | O_NONBLOCK);
flags = fcntl(cmd[1], F_GETFL);
fcntl(cmd[1], F_SETFL, flags | O_NONBLOCK);
/* We make the funnel so that writes to the funnel don't block...
Our "silly" thread can read to its heart content, preventing
recording overruns */
flags = fcntl(funnel[1], F_GETFL);
#if 0
fcntl(funnel[0], F_SETFL, flags | O_NONBLOCK);
#endif
fcntl(funnel[1], F_SETFL, flags | O_NONBLOCK);
res = soundcard_init();
if (res < 0) {
close(cmd[1]);
close(cmd[0]);
if (option_verbose > 1) {
ast_verbose(VERBOSE_PREFIX_2 "No sound card detected -- console channel will be unavailable\n");
ast_verbose(VERBOSE_PREFIX_2 "Turn off OSS support by adding 'noload=chan_oss.so' in /etc/asterisk/modules.conf\n");
}
return 0;
close(funnel[1]);
close(funnel[0]);
return -1;
}
if (!full_duplex)
ast_log(LOG_WARNING, "XXX I don't work right with non-full duplex sound cards XXX\n");
pthread_create(&silly, NULL, silly_thread, NULL);
res = ast_channel_register(type, tdesc, AST_FORMAT_SLINEAR, oss_request);
if (res < 0) {
ast_log(LOG_ERROR, "Unable to register channel class '%s'\n", type);
@@ -965,7 +802,6 @@ int load_module()
}
ast_destroy(cfg);
}
pthread_create(&sthread, NULL, sound_thread, NULL);
return 0;
}
@@ -977,13 +813,13 @@ int unload_module()
for (x=0;x<sizeof(myclis)/sizeof(struct ast_cli_entry); x++)
ast_cli_unregister(myclis + x);
close(sounddev);
if (cmd[0] > 0) {
close(cmd[0]);
close(cmd[1]);
if (funnel[0] > 0) {
close(funnel[0]);
close(funnel[1]);
}
if (sndcmd[0] > 0) {
close(sndcmd[0]);
close(sndcmd[1]);
if (silly) {
pthread_cancel(silly);
pthread_join(silly, NULL);
}
if (oss.owner)
ast_softhangup(oss.owner);
@@ -1000,13 +836,8 @@ char *description()
int usecount()
{
int res;
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
res = usecnt;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -126,7 +126,6 @@ static int phone_digit(struct ast_channel *ast, char digit)
return -1;
}
ioctl(p->fd, PHONE_PLAY_TONE, digit);
p->lastformat = -1;
return 0;
}
@@ -141,7 +140,7 @@ static int phone_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 */
if (option_debug)
ast_log(LOG_DEBUG, "Ringing %s on %s (%d)\n", dest, ast->name, ast->fds[0]);
ast_log(LOG_DEBUG, "Ringing %s on %s (%d)\n", dest, ast->name, ast->fd);
ioctl(p->fd, PHONE_RING_START);
ast->state = AST_STATE_RINGING;
return 0;
@@ -187,11 +186,11 @@ static int phone_hangup(struct ast_channel *ast)
p->dialtone = 0;
memset(p->ext, 0, sizeof(p->ext));
((struct phone_pvt *)(ast->pvt->pvt))->owner = NULL;
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
usecnt--;
if (usecnt < 0)
ast_log(LOG_WARNING, "Usecnt < 0???\n");
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
@@ -207,7 +206,7 @@ static int phone_setup(struct ast_channel *ast)
p = ast->pvt->pvt;
ioctl(p->fd, PHONE_CPT_STOP);
/* Nothing to answering really, just start recording */
if (ast->pvt->rawreadformat == AST_FORMAT_G723_1) {
if (ast->format & AST_FORMAT_G723_1) {
/* Prefer g723 */
ioctl(p->fd, PHONE_REC_STOP);
if (p->lastinput != AST_FORMAT_G723_1) {
@@ -217,7 +216,7 @@ static int phone_setup(struct ast_channel *ast)
return -1;
}
}
} else if (ast->pvt->rawreadformat == AST_FORMAT_SLINEAR) {
} else if (ast->format & AST_FORMAT_SLINEAR) {
ioctl(p->fd, PHONE_REC_STOP);
if (p->lastinput != AST_FORMAT_SLINEAR) {
p->lastinput = AST_FORMAT_SLINEAR;
@@ -227,7 +226,7 @@ static int phone_setup(struct ast_channel *ast)
}
}
} else {
ast_log(LOG_WARNING, "Can't do format %d\n", ast->pvt->rawreadformat);
ast_log(LOG_WARNING, "Can't do format %d\n", ast->format);
return -1;
}
if (ioctl(p->fd, PHONE_REC_START)) {
@@ -268,7 +267,7 @@ static char phone_2digit(char c)
return '?';
}
static struct ast_frame *phone_exception(struct ast_channel *ast)
static struct ast_frame *phone_read(struct ast_channel *ast)
{
int res;
union telephony_exception phonee;
@@ -285,8 +284,7 @@ static struct ast_frame *phone_exception(struct ast_channel *ast)
phonee.bytes = ioctl(p->fd, PHONE_EXCEPTION);
if (phonee.bits.dtmf_ready) {
if (option_debug)
ast_log(LOG_DEBUG, "phone_exception(): DTMF\n");
ast_log(LOG_DEBUG, "phone_read(): DTMF\n");
/* We've got a digit -- Just handle this nicely and easily */
digit = ioctl(p->fd, PHONE_GET_DTMF_ASCII);
@@ -295,12 +293,10 @@ static struct ast_frame *phone_exception(struct ast_channel *ast)
return &p->fr;
}
if (phonee.bits.hookstate) {
if (option_debug)
ast_log(LOG_DEBUG, "Hookstate changed\n");
ast_log(LOG_DEBUG, "Hookstate changed\n");
res = ioctl(p->fd, PHONE_HOOKSTATE);
/* See if we've gone on hook, if so, notify by returning NULL */
if (option_debug)
ast_log(LOG_DEBUG, "New hookstate: %d\n", res);
ast_log(LOG_DEBUG, "New hookstate: %d\n", res);
if (!res && (p->mode != MODE_FXO))
return NULL;
else {
@@ -324,25 +320,6 @@ static struct ast_frame *phone_exception(struct ast_channel *ast)
if (phonee.bits.pstn_wink)
ast_verbose("Detected Wink\n");
#endif
/* Strange -- nothing there.. */
p->fr.frametype = AST_FRAME_NULL;
p->fr.subclass = 0;
return &p->fr;
}
static struct ast_frame *phone_read(struct ast_channel *ast)
{
int res;
struct phone_pvt *p = ast->pvt->pvt;
/* Some nice norms */
p->fr.datalen = 0;
p->fr.timelen = 0;
p->fr.data = NULL;
p->fr.src = type;
p->fr.offset = 0;
p->fr.mallocd=0;
/* Try to read some data... */
CHECK_BLOCKING(ast);
res = read(p->fd, p->buf, PHONE_MAX_BUF);
@@ -419,7 +396,6 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
char *pos;
int sofar;
int expected;
int codecset = 0;
char tmpbuf[4];
/* Write a frame of (presumably voice) data */
if (frame->frametype != AST_FRAME_VOICE) {
@@ -453,7 +429,6 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
p->lastinput = AST_FORMAT_G723_1;
/* Reset output buffer */
p->obuflen = 0;
codecset = 1;
}
if (frame->datalen > 24) {
ast_log(LOG_WARNING, "Frame size too large for G.723.1 (%d bytes)\n", frame->datalen);
@@ -474,23 +449,20 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
}
p->lastformat = AST_FORMAT_SLINEAR;
p->lastinput = AST_FORMAT_SLINEAR;
codecset = 1;
/* Reset output buffer */
p->obuflen = 0;
}
maxfr = 480;
}
if (codecset) {
ioctl(p->fd, PHONE_REC_DEPTH, 3);
ioctl(p->fd, PHONE_PLAY_DEPTH, 3);
if (ioctl(p->fd, PHONE_PLAY_START)) {
ast_log(LOG_WARNING, "Failed to start playback\n");
return -1;
}
if (ioctl(p->fd, PHONE_REC_START)) {
ast_log(LOG_WARNING, "Failed to start recording\n");
return -1;
}
ioctl(p->fd, PHONE_REC_DEPTH, 3);
ioctl(p->fd, PHONE_PLAY_DEPTH, 3);
if (ioctl(p->fd, PHONE_PLAY_START)) {
ast_log(LOG_WARNING, "Failed to start playback\n");
return -1;
}
if (ioctl(p->fd, PHONE_REC_START)) {
ast_log(LOG_WARNING, "Failed to start recording\n");
return -1;
}
/* If we get here, we have a voice frame of Appropriate data */
sofar = 0;
@@ -534,9 +506,9 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *conte
if (tmp) {
snprintf(tmp->name, sizeof(tmp->name), "Phone/%s", i->dev + 5);
tmp->type = type;
tmp->fds[0] = i->fd;
tmp->fd = i->fd;
/* XXX Switching formats silently causes kernel panics XXX */
tmp->nativeformats = prefformat;
tmp->format = prefformat;
tmp->state = state;
if (state == AST_STATE_RING)
tmp->rings = 1;
@@ -547,20 +519,19 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *conte
tmp->pvt->answer = phone_answer;
tmp->pvt->read = phone_read;
tmp->pvt->write = phone_write;
tmp->pvt->exception = phone_exception;
strncpy(tmp->context, context, sizeof(tmp->context));
if (strlen(i->ext))
strncpy(tmp->exten, i->ext, sizeof(tmp->exten));
if (strlen(i->language))
strncpy(tmp->language, i->language, sizeof(tmp->language));
i->owner = tmp;
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
usecnt++;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
if (state != AST_STATE_DOWN) {
if (state == AST_STATE_RING) {
ioctl(tmp->fds[0], PHONE_RINGBACK);
ioctl(tmp->fd, PHONE_RINGBACK);
}
if (ast_pbx_start(tmp)) {
ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
@@ -608,9 +579,9 @@ static void phone_check_exception(struct phone_pvt *i)
phone_new(i, AST_STATE_RING, i->context);
/* No need to restart monitor, we are the monitor */
if (i->owner) {
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
usecnt--;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
}
} else if (!ast_canmatch_extension(NULL, i->context, i->ext, 1)) {
@@ -620,9 +591,9 @@ static void phone_check_exception(struct phone_pvt *i)
/* Check the default, too... */
phone_new(i, AST_STATE_RING, "default");
if (i->owner) {
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
usecnt--;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
}
/* XXX This should probably be justified better XXX */
@@ -644,9 +615,9 @@ static void phone_check_exception(struct phone_pvt *i)
if (i->mode == MODE_IMMEDIATE) {
phone_new(i, AST_STATE_RING, i->context);
} else if (i->mode == MODE_DIALTONE) {
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
usecnt++;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
/* Reset the extension */
i->ext[0] = '\0';
@@ -655,13 +626,12 @@ static void phone_check_exception(struct phone_pvt *i)
ioctl(i->fd, PHONE_PLAY_STOP);
ioctl(i->fd, PHONE_PLAY_CODEC, ULAW);
ioctl(i->fd, PHONE_PLAY_START);
i->lastformat = -1;
}
} else {
if (i->dialtone) {
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
usecnt--;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
}
memset(i->ext, 0, sizeof(i->ext));
@@ -669,7 +639,6 @@ static void phone_check_exception(struct phone_pvt *i)
ioctl(i->fd, PHONE_PLAY_STOP);
ioctl(i->fd, PHONE_REC_STOP);
i->dialtone = 0;
i->lastformat = -1;
}
}
if (phonee.bits.pstn_ring) {
@@ -701,14 +670,14 @@ static void *do_monitor(void *data)
for(;;) {
/* Don't let anybody kill us right away. Nobody should lock the interface list
and wait for the monitor list, but the other way around is okay. */
if (ast_pthread_mutex_lock(&monlock)) {
if (pthread_mutex_lock(&monlock)) {
ast_log(LOG_ERROR, "Unable to grab monitor lock\n");
return NULL;
}
/* Lock the interface list */
if (ast_pthread_mutex_lock(&iflock)) {
if (pthread_mutex_lock(&iflock)) {
ast_log(LOG_ERROR, "Unable to grab interface lock\n");
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
return NULL;
}
/* Build the stuff we're going to select on, that is the socket of every
@@ -742,10 +711,10 @@ static void *do_monitor(void *data)
i = i->next;
}
/* Okay, now that we know what to do, release the interface lock */
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
/* And from now on, we're okay to be killed, so release the monitor lock as well */
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
/* Wait indefinitely for something to happen */
if (dotone) {
/* If we're ready to recycle the time, set it to 30 ms */
@@ -774,7 +743,7 @@ static void *do_monitor(void *data)
continue;
/* Alright, lock the interface list again, and let's look and see what has
happened */
if (ast_pthread_mutex_lock(&iflock)) {
if (pthread_mutex_lock(&iflock)) {
ast_log(LOG_WARNING, "Unable to lock the interface list\n");
continue;
}
@@ -796,7 +765,7 @@ static void *do_monitor(void *data)
}
i=i->next;
}
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
}
/* Never reached */
return NULL;
@@ -808,12 +777,12 @@ static int restart_monitor()
/* If we're supposed to be stopped -- stay stopped */
if (monitor_thread == -2)
return 0;
if (ast_pthread_mutex_lock(&monlock)) {
if (pthread_mutex_lock(&monlock)) {
ast_log(LOG_WARNING, "Unable to lock monitor\n");
return -1;
}
if (monitor_thread == pthread_self()) {
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
ast_log(LOG_WARNING, "Cannot kill myself\n");
return -1;
}
@@ -825,11 +794,11 @@ static int restart_monitor()
}
/* Start a new monitor */
if (pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
return -1;
}
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
return 0;
}
@@ -900,7 +869,7 @@ static struct ast_channel *phone_request(char *type, int format, void *data)
return NULL;
}
/* Search for an unowned channel */
if (ast_pthread_mutex_lock(&iflock)) {
if (pthread_mutex_lock(&iflock)) {
ast_log(LOG_ERROR, "Unable to lock interface list???\n");
return NULL;
}
@@ -914,7 +883,7 @@ static struct ast_channel *phone_request(char *type, int format, void *data)
}
p = p->next;
}
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
restart_monitor();
return tmp;
}
@@ -932,7 +901,7 @@ int load_module()
ast_log(LOG_ERROR, "Unable to load config %s\n", config);
return -1;
}
if (ast_pthread_mutex_lock(&iflock)) {
if (pthread_mutex_lock(&iflock)) {
/* It's a little silly to lock it, but we mind as well just to be sure */
ast_log(LOG_ERROR, "Unable to lock interface list???\n");
return -1;
@@ -949,7 +918,7 @@ int load_module()
} else {
ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
ast_destroy(cfg);
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
unload_module();
return -1;
}
@@ -973,9 +942,7 @@ int load_module()
prefformat = AST_FORMAT_G723_1;
} else if (!strcasecmp(v->value, "slinear")) {
prefformat = AST_FORMAT_SLINEAR;
} else if (!strcasecmp(v->value, "ulaw")) {
prefformat = AST_FORMAT_ULAW;
} else
} else
ast_log(LOG_WARNING, "Unknown format '%s'\n", v->value);
} else if (!strcasecmp(v->name, "echocancel")) {
if (!strcasecmp(v->value, "off")) {
@@ -991,7 +958,7 @@ int load_module()
}
v = v->next;
}
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
/* Make sure we can register our Adtranphone channel type */
if (ast_channel_register(type, tdesc, AST_FORMAT_G723_1, phone_request)) {
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
@@ -1012,7 +979,7 @@ int unload_module()
struct phone_pvt *p, *pl;
/* First, take us out of the channel loop */
ast_channel_unregister(type);
if (!ast_pthread_mutex_lock(&iflock)) {
if (!pthread_mutex_lock(&iflock)) {
/* Hangup all interfaces if they have an owner */
p = iflist;
while(p) {
@@ -1021,24 +988,24 @@ int unload_module()
p = p->next;
}
iflist = NULL;
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
return -1;
}
if (!ast_pthread_mutex_lock(&monlock)) {
if (!pthread_mutex_lock(&monlock)) {
if (monitor_thread > -1) {
pthread_cancel(monitor_thread);
pthread_join(monitor_thread, NULL);
}
monitor_thread = -2;
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
return -1;
}
if (!ast_pthread_mutex_lock(&iflock)) {
if (!pthread_mutex_lock(&iflock)) {
/* Destroy all the interfaces and free their memory */
p = iflist;
while(p) {
@@ -1051,7 +1018,7 @@ int unload_module()
free(pl);
}
iflist = NULL;
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
return -1;
@@ -1063,9 +1030,9 @@ int unload_module()
int usecount()
{
int res;
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
res = usecnt;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
return res;
}
@@ -1074,7 +1041,3 @@ char *description()
return desc;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

File diff suppressed because it is too large Load Diff

View File

@@ -253,8 +253,6 @@ static void vofr_dump_packet(struct vofr_hdr *vh, int len)
#endif
static struct ast_frame *vofr_read(struct ast_channel *ast);
static int vofr_xmit(struct vofr_pvt *p, char *data, int len)
{
int res;
@@ -362,7 +360,7 @@ static int vofr_call(struct ast_channel *ast, char *dest, int timeout)
/* Musta gotten hung up, or no ack on off hook */
return -1;
}
f = vofr_read(ast);
f = ast_read(ast);
if (!f)
return -1;
if ((f->frametype == AST_FRAME_CONTROL) &&
@@ -392,7 +390,7 @@ static int vofr_call(struct ast_channel *ast, char *dest, int timeout)
/* Musta gotten hung up, or no ack on off hook */
return -1;
}
f = vofr_read(ast);
f = ast_read(ast);
if (!f)
return -1;
@@ -420,7 +418,7 @@ static int vofr_call(struct ast_channel *ast, char *dest, int timeout)
timeout = res;
if (res) {
/* Ooh, read what's there. */
f = vofr_read(ast);
f = ast_read(ast);
if (!f)
return -1;
if ((f->frametype == AST_FRAME_CONTROL) &&
@@ -456,11 +454,11 @@ static int vofr_hangup(struct ast_channel *ast)
ast->state = AST_STATE_DOWN;
((struct vofr_pvt *)(ast->pvt->pvt))->owner = NULL;
((struct vofr_pvt *)(ast->pvt->pvt))->ringgothangup = 0;
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
usecnt--;
if (usecnt < 0)
ast_log(LOG_WARNING, "Usecnt < 0???\n");
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
@@ -486,7 +484,7 @@ static int vofr_answer(struct ast_channel *ast)
while(cnt > 0) {
cnt = ast_waitfor(ast, cnt);
if (cnt > 0) {
res = read(ast->fds[0], buf, sizeof(buf));
res = read(ast->fd, buf, sizeof(buf));
#ifdef VOFRDUMPER
vofr_dump_packet((void *)(buf +FR_API_MESS), res - FR_API_MESS);
#endif
@@ -784,17 +782,6 @@ static int vofr_write(struct ast_channel *ast, struct ast_frame *frame)
return 0;
}
static int vofr_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
{
struct vofr_pvt *p = newchan->pvt->pvt;
if (p->owner != oldchan) {
ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
return -1;
}
p->owner = newchan;
return 0;
}
static struct ast_channel *vofr_new(struct vofr_pvt *i, int state)
{
struct ast_channel *tmp;
@@ -806,14 +793,12 @@ static struct ast_channel *vofr_new(struct vofr_pvt *i, int state)
snprintf(tmp->name, sizeof(tmp->name), "AdtranVoFR/%s", i->sa.sll_device);
#endif
tmp->type = type;
tmp->fds[0] = i->s;
tmp->fd = i->s;
/* Adtran VoFR supports only G723.1 format data. G711 (ulaw) would be nice too */
tmp->nativeformats = AST_FORMAT_G723_1;
tmp->format = AST_FORMAT_G723_1;
tmp->state = state;
if (state == AST_STATE_RING)
tmp->rings = 1;
tmp->writeformat = AST_FORMAT_G723_1;
tmp->readformat = AST_FORMAT_G723_1;
tmp->pvt->pvt = i;
tmp->pvt->send_digit = vofr_digit;
tmp->pvt->call = vofr_call;
@@ -821,13 +806,12 @@ static struct ast_channel *vofr_new(struct vofr_pvt *i, int state)
tmp->pvt->answer = vofr_answer;
tmp->pvt->read = vofr_read;
tmp->pvt->write = vofr_write;
tmp->pvt->fixup = vofr_fixup;
if (strlen(i->language))
strncpy(tmp->language, i->language, sizeof(tmp->language));
i->owner = tmp;
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
usecnt++;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
strncpy(tmp->context, i->context, sizeof(tmp->context));
if (state != AST_STATE_DOWN) {
@@ -915,14 +899,14 @@ static void *do_monitor(void *data)
for(;;) {
/* Don't let anybody kill us right away. Nobody should lock the interface list
and wait for the monitor list, but the other way around is okay. */
if (ast_pthread_mutex_lock(&monlock)) {
if (pthread_mutex_lock(&monlock)) {
ast_log(LOG_ERROR, "Unable to grab monitor lock\n");
return NULL;
}
/* Lock the interface list */
if (ast_pthread_mutex_lock(&iflock)) {
if (pthread_mutex_lock(&iflock)) {
ast_log(LOG_ERROR, "Unable to grab interface lock\n");
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
return NULL;
}
/* Build the stuff we're going to select on, that is the socket of every
@@ -946,10 +930,10 @@ static void *do_monitor(void *data)
i = i->next;
}
/* Okay, now that we know what to do, release the interface lock */
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
/* And from now on, we're okay to be killed, so release the monitor lock as well */
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
pthread_testcancel();
/* Wait indefinitely for something to happen */
res = select(n + 1, &rfds, NULL, NULL, NULL);
@@ -962,7 +946,7 @@ static void *do_monitor(void *data)
}
/* Alright, lock the interface list again, and let's look and see what has
happened */
if (ast_pthread_mutex_lock(&iflock)) {
if (pthread_mutex_lock(&iflock)) {
ast_log(LOG_WARNING, "Unable to lock the interface list\n");
continue;
}
@@ -986,7 +970,7 @@ static void *do_monitor(void *data)
}
i=i->next;
}
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
}
/* Never reached */
return NULL;
@@ -998,27 +982,32 @@ static int restart_monitor(void)
/* If we're supposed to be stopped -- stay stopped */
if (monitor_thread == -2)
return 0;
if (ast_pthread_mutex_lock(&monlock)) {
if (pthread_mutex_lock(&monlock)) {
ast_log(LOG_WARNING, "Unable to lock monitor\n");
return -1;
}
if (monitor_thread == pthread_self()) {
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
ast_log(LOG_WARNING, "Cannot kill myself\n");
return -1;
}
if (monitor_thread) {
/* Wake up the thread */
#if 0
pthread_cancel(monitor_thread);
#endif
pthread_kill(monitor_thread, SIGURG);
} else {
/* Start a new monitor */
if (pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
ast_pthread_mutex_unlock(&monlock);
ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
return -1;
}
#if 0
pthread_join(monitor_thread, NULL);
#endif
}
ast_pthread_mutex_unlock(&monlock);
if (!monitor_thread)
/* Start a new monitor */
if (pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
pthread_mutex_unlock(&monlock);
ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
return -1;
}
pthread_mutex_unlock(&monlock);
return 0;
}
@@ -1118,7 +1107,7 @@ static struct ast_channel *vofr_request(char *type, int format, void *data)
return NULL;
}
/* Search for an unowned channel */
if (ast_pthread_mutex_lock(&iflock)) {
if (pthread_mutex_lock(&iflock)) {
ast_log(LOG_ERROR, "Unable to lock interface list???\n");
return NULL;
}
@@ -1130,7 +1119,7 @@ static struct ast_channel *vofr_request(char *type, int format, void *data)
}
p = p->next;
}
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
restart_monitor();
return tmp;
}
@@ -1147,7 +1136,7 @@ int load_module()
ast_log(LOG_ERROR, "Unable to load config %s\n", config);
return -1;
}
if (ast_pthread_mutex_lock(&iflock)) {
if (pthread_mutex_lock(&iflock)) {
/* It's a little silly to lock it, but we mind as well just to be sure */
ast_log(LOG_ERROR, "Unable to lock interface list???\n");
return -1;
@@ -1164,7 +1153,7 @@ int load_module()
} else {
ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
ast_destroy(cfg);
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
unload_module();
return -1;
}
@@ -1175,7 +1164,7 @@ int load_module()
}
v = v->next;
}
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
/* Make sure we can register our AdtranVoFR channel type */
if (ast_channel_register(type, tdesc, AST_FORMAT_G723_1, vofr_request)) {
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
@@ -1194,7 +1183,7 @@ int unload_module()
struct vofr_pvt *p, *pl;
/* First, take us out of the channel loop */
ast_channel_unregister(type);
if (!ast_pthread_mutex_lock(&iflock)) {
if (!pthread_mutex_lock(&iflock)) {
/* Hangup all interfaces if they have an owner */
p = iflist;
while(p) {
@@ -1203,25 +1192,25 @@ int unload_module()
p = p->next;
}
iflist = NULL;
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
return -1;
}
if (!ast_pthread_mutex_lock(&monlock)) {
if (!pthread_mutex_lock(&monlock)) {
if (monitor_thread) {
pthread_cancel(monitor_thread);
pthread_kill(monitor_thread, SIGURG);
pthread_join(monitor_thread, NULL);
}
monitor_thread = -2;
ast_pthread_mutex_unlock(&monlock);
pthread_mutex_unlock(&monlock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
return -1;
}
if (!ast_pthread_mutex_lock(&iflock)) {
if (!pthread_mutex_lock(&iflock)) {
/* Destroy all the interfaces and free their memory */
p = iflist;
while(p) {
@@ -1234,7 +1223,7 @@ int unload_module()
free(pl);
}
iflist = NULL;
ast_pthread_mutex_unlock(&iflock);
pthread_mutex_unlock(&iflock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
return -1;
@@ -1246,17 +1235,12 @@ int unload_module()
int usecount()
{
int res;
ast_pthread_mutex_lock(&usecnt_lock);
pthread_mutex_lock(&usecnt_lock);
res = usecnt;
ast_pthread_mutex_unlock(&usecnt_lock);
pthread_mutex_unlock(&usecnt_lock);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}
char *description()
{
return desc;

View File

@@ -1,95 +0,0 @@
/* Generate a header file for a particular
single or double frequency */
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define CLIP 32635
#define BIAS 0x84
static float loudness=16384.0;
static int calc_samples(int freq)
{
int x, samples;
/* Calculate the number of samples at 8000hz sampling
we need to have this wave form */
samples = 8000;
/* Take out common 2's up to six times */
for (x=0;x<6;x++)
if (!(freq % 2)) {
freq /= 2;
samples /= 2;
}
/* Take out common 5's (up to three times */
for (x=0;x<3;x++)
if (!(freq % 5)) {
freq /= 5;
samples /=5;
}
/* No more common factors. */
return samples;
}
int main(int argc, char *argv[])
{
FILE *f;
int freq1, freq2;
float wlen1, wlen2;
float val;
int x, samples1, samples2, samples=0;
char fn[256];
if (argc < 3) {
fprintf(stderr, "Usage: gensound <name> <freq1> [freq2]\n");
exit(1);
}
freq1 = atoi(argv[2]);
if (argc > 3)
freq2 = atoi(argv[3]);
else
freq2 = 0;
wlen1 = 8000.0/(float)freq1;
samples1 = calc_samples(freq1);
printf("Wavelength 1 (in samples): %10.5f\n", wlen1);
printf("Minimum samples (1): %d (%f.3 wavelengths)\n", samples1, samples1 / wlen1);
if (freq2) {
wlen2 = 8000.0/(float)freq2;
samples2 = calc_samples(freq2);
printf("Wavelength 1 (in samples): %10.5f\n", wlen2);
printf("Minimum samples (1): %d (%f.3 wavelengths)\n", samples2, samples2 / wlen2);
}
samples = samples1;
if (freq2) {
while(samples % samples2)
samples += samples1;
}
printf("Need %d samples\n", samples);
snprintf(fn, sizeof(fn), "%s.h", argv[1]);
if ((f = fopen(fn, "w"))) {
if (freq2)
fprintf(f, "/* %s: Generated from frequencies %d and %d \n"
" by gensound. %d samples */\n", fn, freq1, freq2, samples);
else
fprintf(f, "/* %s: Generated from frequency %d\n"
" by gensound. %d samples */\n", fn, freq1, samples);
fprintf(f, "static short %s[%d] = {\n\t", argv[1], samples);
for (x=0;x<samples;x++) {
val = loudness * sin((freq1 * 2.0 * M_PI * x)/8000.0);
if (freq2)
val += loudness * sin((freq2 * 2.0 * M_PI * x)/8000.0);
fprintf(f, "%5d, ", (int)val);
if (!((x+1) % 8))
fprintf(f, "\n\t");
}
if (x % 15)
fprintf(f, "\n");
fprintf(f, "};\n");
fclose(f);
printf("Wrote %s\n", fn);
} else {
fprintf(stderr, "Unable to open %s for writing\n", fn);
return 1;
}
return 0;
}

View File

@@ -38,17 +38,6 @@
#define AST_IAX_COMMAND_INVAL 10
#define AST_IAX_COMMAND_LAGRQ 11
#define AST_IAX_COMMAND_LAGRP 12
#define AST_IAX_COMMAND_REGREQ 13 /* Registration request */
#define AST_IAX_COMMAND_REGAUTH 14 /* Registration authentication required */
#define AST_IAX_COMMAND_REGACK 15 /* Registration accepted */
#define AST_IAX_COMMAND_REGREJ 16 /* Registration rejected */
#define AST_IAX_COMMAND_REGREL 17 /* Force release of registration */
#define AST_IAX_COMMAND_VNAK 18 /* If we receive voice before valid first voice frame, send this */
#define AST_IAX_COMMAND_DPREQ 19 /* Request status of a dialplan entry */
#define AST_IAX_COMMAND_DPREP 20 /* Request status of a dialplan entry */
#define AST_IAX_COMMAND_DIAL 21 /* Request a dial on channel brought up TBD */
#define AST_DEFAULT_REG_EXPIRE 60 /* By default require re-registration once per minute */
#define AST_DEFAULT_IAX_PORTNO 5036

View File

@@ -1,8 +1,8 @@
/******************************************************************************
$Id$
$Log$
Revision 1.9 1999/12/01 05:25:58 markster
Version 0.1.8 from FTP
Revision 1.5 1999/12/01 05:25:58 markster
Version 0.1.4 from FTP
Revision 1.1 1999/12/01 05:25:58 markster
Start on the Internet Phone Jack channel

File diff suppressed because it is too large Load Diff

189
cli.c
View File

@@ -27,11 +27,6 @@
#include <readline/readline.h>
/* For module directory */
#include "asterisk.h"
#include "build.h"
#define VERSION_INFO "Asterisk " ASTERISK_VERSION " built by " BUILD_USER "@" BUILD_HOSTNAME \
" on a " BUILD_MACHINE " running " BUILD_OS
void ast_cli(int fd, char *fmt, ...)
{
@@ -71,21 +66,6 @@ static char chanlist_help[] =
" Lists currently defined channels and some information about\n"
" them.\n";
static char reload_help[] =
"Usage: reload\n"
" Reloads configuration files for all modules which support\n"
" reloading.\n";
static char set_verbose_help[] =
"Usage: set verbose <level>\n"
" Sets level of verbose messages to be displayed. 0 means\n"
" no messages should be displayed.\n";
static char softhangup_help[] =
"Usage: soft hangup <channel>\n"
" Request that a channel be hung up. The hangup takes effect\n"
" the next time the driver reads or writes from the channel\n";
static int handle_load(int fd, int argc, char *argv[])
{
if (argc != 2)
@@ -97,32 +77,6 @@ static int handle_load(int fd, int argc, char *argv[])
return RESULT_SUCCESS;
}
static int handle_reload(int fd, int argc, char *argv[])
{
if (argc != 1)
return RESULT_SHOWUSAGE;
ast_module_reload();
return RESULT_SUCCESS;
}
static int handle_set_verbose(int fd, int argc, char *argv[])
{
int val;
/* Has a hidden 'at least' argument */
if ((argc != 3) && (argc != 4))
return RESULT_SHOWUSAGE;
if ((argc == 4) && strcasecmp(argv[2], "atleast"))
return RESULT_SHOWUSAGE;
if (argc == 3)
option_verbose = atoi(argv[2]);
else {
val = atoi(argv[3]);
if (val > option_verbose)
option_verbose = val;
}
return RESULT_SUCCESS;
}
static int handle_unload(int fd, int argc, char *argv[])
{
int x;
@@ -168,41 +122,30 @@ static char modlist_help[] =
" Shows Asterisk modules currently in use, and usage "
"statistics.\n";
static char version_help[] =
"Usage: show version\n"
" Shows Asterisk version information.\n ";
static int handle_modlist(int fd, int argc, char *argv[])
{
if (argc != 2)
return RESULT_SHOWUSAGE;
ast_pthread_mutex_lock(&climodentrylock);
pthread_mutex_lock(&climodentrylock);
climodentryfd = fd;
ast_cli(fd, MODLIST_FORMAT2, "Module", "Description", "Use Count");
ast_update_module_list(modlist_modentry);
climodentryfd = -1;
ast_pthread_mutex_unlock(&climodentrylock);
pthread_mutex_unlock(&climodentrylock);
return RESULT_SUCCESS;
}
static int handle_version(int fd, int argc, char *argv[])
{
if (argc != 2)
return RESULT_SHOWUSAGE;
ast_cli(fd, VERSION_INFO);
return RESULT_SUCCESS;
}
static int handle_chanlist(int fd, int argc, char *argv[])
{
#define FORMAT_STRING "%15s (%-10s %-12s %-4d) %7s %-12s %-15s\n"
#define FORMAT_STRING2 "%15s (%-10s %-12s %-4s) %7s %-12s %-15s\n"
#define FORMAT_STRING "%15s (%-10s %-12s %-4d) %-12s %-15s\n"
#define FORMAT_STRING2 "%15s (%-10s %-12s %-4s) %-12s %-15s\n"
struct ast_channel *c=NULL;
if (argc != 2)
return RESULT_SHOWUSAGE;
c = ast_channel_walk(NULL);
ast_cli(fd, FORMAT_STRING2, "Channel", "Context", "Extension", "Pri", "State", "Appl.", "Data");
ast_cli(fd, FORMAT_STRING2, "Channel", "Context", "Extension", "Pri", "Appl.", "Data");
while(c) {
ast_cli(fd, FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->state),
ast_cli(fd, FORMAT_STRING, c->name, c->context, c->exten, c->priority,
c->appl ? c->appl : "(None)", c->data ? ( strlen(c->data) ? c->data : "(Empty)" ): "(None)");
c = ast_channel_walk(c);
}
@@ -213,52 +156,6 @@ static char showchan_help[] =
"Usage: show channel <channel>\n"
" Shows lots of information about the specified channel.\n";
static char commandcomplete_help[] =
"Usage: _command complete \"<line>\" text state\n"
" This function is used internally to help with command completion and should.\n"
" never be called by the user directly.\n";
static int handle_softhangup(int fd, int argc, char *argv[])
{
struct ast_channel *c=NULL;
if (argc != 3)
return RESULT_SHOWUSAGE;
c = ast_channel_walk(NULL);
while(c) {
if (!strcasecmp(c->name, argv[2])) {
ast_cli(fd, "Requested Hangup on channel '%s'\n", c->name);
c->softhangup = 1;
break;
}
c = ast_channel_walk(c);
}
if (!c)
ast_cli(fd, "%s is not a known channel\n", argv[2]);
return RESULT_SUCCESS;
}
static char *__ast_cli_generator(char *text, char *word, int state, int lock);
static int handle_commandcomplete(int fd, int argc, char *argv[])
{
char *buf;
#if 0
printf("Search for %d args: '%s', '%s', '%s', '%s'\n", argc, argv[0], argv[1], argv[2], argv[3]);
#endif
if (argc != 5)
return RESULT_SHOWUSAGE;
buf = __ast_cli_generator(argv[2], argv[3], atoi(argv[4]), 0);
#if 0
printf("Search for '%s' %s %d got '%s'\n", argv[2], argv[3], atoi(argv[4]), buf);
#endif
if (buf) {
ast_cli(fd, buf);
free(buf);
} else
ast_cli(fd, "NULL\n");
return RESULT_SUCCESS;
}
static int handle_showchan(int fd, int argc, char *argv[])
{
struct ast_channel *c=NULL;
@@ -271,14 +168,14 @@ static int handle_showchan(int fd, int argc, char *argv[])
" -- General --\n"
" Name: %s\n"
" Type: %s\n"
" Translator: %s\n"
" Master: %s\n"
" Caller ID: %s\n"
" DNID Digits: %s\n"
" State: %s (%d)\n"
" State: %d\n"
" Rings: %d\n"
" WriteFormat: %d\n"
" ReadFormat: %d\n"
" NativeFormat: %d\n"
"1st File Descriptor: %d\n"
" Format: %d\n"
"File Descriptor: %d\n"
" -- PBX --\n"
" Context: %s\n"
" Extension: %s\n"
@@ -287,10 +184,10 @@ static int handle_showchan(int fd, int argc, char *argv[])
" Data: %s\n"
" Stack: %d\n"
" Blocking in: %s\n",
c->name, c->type,
(c->callerid ? c->callerid : "(N/A)"),
(c->dnid ? c->dnid : "(N/A)" ), ast_state2str(c->state), c->state, c->rings, c->nativeformats, c->writeformat, c->readformat,
c->fds[0], c->context, c->exten, c->priority, ( c->appl ? c->appl : "(N/A)" ),
c->name, c->type, (c->trans ? c->trans->name : "(N/A)"),
(c->master ? c->master->name : "(N/A)"), (c->callerid ? c->callerid : "(N/A)"),
(c->dnid ? c->dnid : "(N/A)" ), c->state, c->rings, c->format,
c->fd, c->context, c->exten, c->priority, ( c->appl ? c->appl : "(N/A)" ),
( c-> data ? (strlen(c->data) ? c->data : "(Empty)") : "(None)"),
c->stack, (c->blocking ? c->blockproc : "(Not Blocking)"));
@@ -309,10 +206,8 @@ static char *complete_ch(char *line, char *word, int pos, int state)
int which=0;
c = ast_channel_walk(NULL);
while(c) {
if (!strncasecmp(word, c->name, strlen(word))) {
if (++which > state)
break;
}
if (++which > state)
break;
c = ast_channel_walk(c);
}
return c ? strdup(c->name) : NULL;
@@ -328,7 +223,7 @@ static char *complete_fn(char *line, char *word, int pos, int state)
strncpy(filename, word, sizeof(filename));
else
snprintf(filename, sizeof(filename), "%s/%s", AST_MODULE_DIR, word);
c = (char*)filename_completion_function(filename, state);
c = filename_completion_function(filename, state);
if (c && word[0] != '/')
c += (strlen(AST_MODULE_DIR) + 1);
return c ? strdup(c) : c;
@@ -339,16 +234,11 @@ static int handle_help(int fd, int argc, char *argv[]);
static struct ast_cli_entry builtins[] = {
/* Keep alphabetized */
{ { "help", NULL }, handle_help, "Display help list, or specific help on a command", help_help },
{ { "_command", "complete", NULL }, handle_commandcomplete, "Command complete", commandcomplete_help },
{ { "load", NULL }, handle_load, "Load a dynamic module by name", load_help, complete_fn },
{ { "reload", NULL }, handle_reload, "Reload configuration", reload_help },
{ { "set", "verbose", NULL }, handle_set_verbose, "Set level of verboseness", set_verbose_help },
{ { "show", "channel", NULL }, handle_showchan, "Display information on a specific channel", showchan_help, complete_ch },
{ { "show", "channels", NULL }, handle_chanlist, "Display information on channels", chanlist_help },
{ { "show", "modules", NULL }, handle_modlist, "List modules and info", modlist_help },
{ { "soft", "hangup", NULL }, handle_softhangup, "Request a hangup on a given channel", softhangup_help, complete_ch },
{ { "unload", NULL }, handle_unload, "Unload a dynamic module by name", unload_help, complete_fn },
{ { "version", NULL }, handle_version, "Display version info", version_help },
{ { NULL }, NULL, NULL, NULL }
};
@@ -437,7 +327,7 @@ static char *find_best(char *argv[])
int ast_cli_unregister(struct ast_cli_entry *e)
{
struct ast_cli_entry *cur, *l=NULL;
ast_pthread_mutex_lock(&clilock);
pthread_mutex_lock(&clilock);
cur = helpers;
while(cur) {
if (e == cur) {
@@ -452,7 +342,7 @@ int ast_cli_unregister(struct ast_cli_entry *e)
l = cur;
cur = cur->next;
}
ast_pthread_mutex_unlock(&clilock);
pthread_mutex_unlock(&clilock);
return 0;
}
@@ -461,11 +351,11 @@ int ast_cli_register(struct ast_cli_entry *e)
struct ast_cli_entry *cur, *l=NULL;
char fulle[80], fulltst[80];
static int len;
ast_pthread_mutex_lock(&clilock);
pthread_mutex_lock(&clilock);
join2(fulle, sizeof(fulle), e->cmda);
if (find_cli(e->cmda, -1)) {
ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", fulle);
ast_pthread_mutex_unlock(&clilock);
pthread_mutex_unlock(&clilock);
return -1;
}
cur = helpers;
@@ -494,7 +384,7 @@ int ast_cli_register(struct ast_cli_entry *e)
helpers = e;
e->next = NULL;
}
ast_pthread_mutex_unlock(&clilock);
pthread_mutex_unlock(&clilock);
return 0;
}
@@ -527,9 +417,6 @@ static int help_workhorse(int fd, char *match[])
fullcmd = fullcmd1;
e1++;
}
/* Hide commands that start with '_' */
if (fullcmd[0] == '_')
continue;
if (match) {
if (strncasecmp(matchstr, fullcmd, strlen(matchstr))) {
continue;
@@ -582,11 +469,6 @@ static char *parse_args(char *s, int *max, char *argv[])
goto normal;
else
quoted = !quoted;
if (quoted && whitespace) {
/* If we're starting a quote, coming off white space start a new word, too */
argv[x++] = cur;
whitespace=0;
}
escaped = 0;
break;
case ' ':
@@ -632,7 +514,7 @@ normal:
return dup;
}
static char *__ast_cli_generator(char *text, char *word, int state, int lock)
char *ast_cli_generator(char *text, char *word, int state)
{
char *argv[AST_MAX_ARGS];
struct ast_cli_entry *e, *e1, *e2;
@@ -646,8 +528,7 @@ static char *__ast_cli_generator(char *text, char *word, int state, int lock)
if ((dup = parse_args(text, &x, argv))) {
join(matchstr, sizeof(matchstr), argv);
if (lock)
ast_pthread_mutex_lock(&clilock);
pthread_mutex_lock(&clilock);
e1 = builtins;
e2 = helpers;
while(e1->cmda[0] || e2) {
@@ -668,7 +549,7 @@ static char *__ast_cli_generator(char *text, char *word, int state, int lock)
fullcmd = fullcmd1;
e1++;
}
if ((fullcmd[0] != '_') && !strncasecmp(matchstr, fullcmd, strlen(matchstr))) {
if (!strncasecmp(matchstr, fullcmd, strlen(matchstr))) {
/* We contain the first part of one or more commands */
matchnum++;
if (matchnum > state) {
@@ -679,8 +560,7 @@ static char *__ast_cli_generator(char *text, char *word, int state, int lock)
res = e->cmda[x];
}
if (res) {
if (lock)
ast_pthread_mutex_unlock(&clilock);
pthread_mutex_unlock(&clilock);
return res ? strdup(res) : NULL;
}
}
@@ -689,24 +569,17 @@ static char *__ast_cli_generator(char *text, char *word, int state, int lock)
/* We have a command in its entirity within us -- theoretically only one
command can have this occur */
fullcmd = e->generator(text, word, (strlen(word) ? (x - 1) : (x)), state);
if (lock)
ast_pthread_mutex_unlock(&clilock);
pthread_mutex_unlock(&clilock);
return fullcmd;
}
}
if (lock)
ast_pthread_mutex_unlock(&clilock);
pthread_mutex_unlock(&clilock);
free(dup);
}
return NULL;
}
char *ast_cli_generator(char *text, char *word, int state)
{
return __ast_cli_generator(text, word, state, 1);
}
int ast_cli_command(int fd, char *s)
{
char *argv[AST_MAX_ARGS];
@@ -717,7 +590,7 @@ int ast_cli_command(int fd, char *s)
if ((dup = parse_args(s, &x, argv))) {
/* We need at least one entry, or ignore */
if (x > 0) {
ast_pthread_mutex_lock(&clilock);
pthread_mutex_lock(&clilock);
e = find_cli(argv, 0);
if (e) {
switch(e->handler(fd, x, argv)) {
@@ -728,7 +601,7 @@ int ast_cli_command(int fd, char *s)
}
} else
ast_cli(fd, "No such command '%s' (type 'help' for help)\n", find_best(argv));
ast_pthread_mutex_unlock(&clilock);
pthread_mutex_unlock(&clilock);
}
free(dup);
} else {

View File

@@ -28,7 +28,7 @@ LIBGSM=gsm/lib/libgsm.a
LIBMP3=mp3/libmp3.a
LIBLPC10=lpc10/liblpc10.a
CODECS+=$(MODG723) codec_gsm.so codec_mp3_d.so codec_lpc10.so codec_adpcm.so codec_ulaw.so
CODECS+=$(MODG723) codec_gsm.so codec_mp3_d.so codec_lpc10.so
all: $(CODECS)
@@ -71,7 +71,7 @@ codec_lpc10.so: codec_lpc10.o $(LIBLPC10)
$(CC) -shared -Xlinker -x -o $@ $< $(LIBLPC10) -lm
codec_mp3_d.so: codec_mp3_d.o $(LIBMP3)
$(CC) -lm -shared -Xlinker -x -o $@ $< $(LIBMP3)
$(CC) -shared -Xlinker -x -o $@ $< $(LIBMP3)
%.so : %.o
$(CC) -shared -Xlinker -x -o $@ $<

View File

@@ -1,25 +0,0 @@
/*
* adpcm_slin_ex.h --
*
* 4-bit ADPCM data, 20 milliseconds worth at 8 kHz.
*
* Source: g723.example
*
* Copyright (C) 2001, Linux Support Services, Inc.
*
* Distributed under the terms of the GNU General Public License
*
*/
static unsigned char adpcm_slin_ex[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

View File

@@ -1,546 +0,0 @@
/* codec_adpcm.c - translate between signed linear and Dialogic ADPCM
*
* Asterisk -- A telephony toolkit for Linux.
*
* Based on frompcm.c and topcm.c from the Emiliano MIPL browser/
* interpreter. See http://www.bsdtelephony.com.mx
*
* Copyright (c) 2001 Linux Support Services, Inc. All rights reserved.
*
* Karl Sackett <krs@linux-support.net>, 2001-3-21
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/logger.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/channel.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BUFFER_SIZE 8096 /* size for the translation buffers */
static pthread_mutex_t localuser_lock = PTHREAD_MUTEX_INITIALIZER;
static int localusecnt = 0;
static char *tdesc = "Adaptive Differential PCM Coder/Decoder";
/* Sample frame data */
#include "slin_adpcm_ex.h"
#include "adpcm_slin_ex.h"
/*
* Step size index shift table
*/
static short indsft[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
/*
* Step size table, where stpsz[i]=floor[16*(11/10)^i]
*/
static short stpsz[49] = {
16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73,
80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279,
307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
1060, 1166, 1282, 1411, 1552
};
/*
* Nibble to bit map
*/
static short nbl2bit[16][4] = {
{1, 0, 0, 0}, {1, 0, 0, 1}, {1, 0, 1, 0}, {1, 0, 1, 1},
{1, 1, 0, 0}, {1, 1, 0, 1}, {1, 1, 1, 0}, {1, 1, 1, 1},
{-1, 0, 0, 0}, {-1, 0, 0, 1}, {-1, 0, 1, 0}, {-1, 0, 1, 1},
{-1, 1, 0, 0}, {-1, 1, 0, 1}, {-1, 1, 1, 0}, {-1, 1, 1, 1}
};
/*
* Decode(encoded)
* Decodes the encoded nibble from the adpcm file.
*
* Results:
* Returns the encoded difference.
*
* Side effects:
* Sets the index to the step size table for the next encode.
*/
static inline short
decode (unsigned char encoded, short *ssindex)
{
short diff, step;
step = stpsz[*ssindex];
diff = nbl2bit[encoded][0] * (step * nbl2bit[encoded][1] +
(step >> 1) * nbl2bit[encoded][2] +
(step >> 2) * nbl2bit[encoded][3] +
(step >> 3));
*ssindex = *ssindex + indsft[(encoded & 7)];
if (*ssindex < 0)
*ssindex = 0;
else if (*ssindex > 48)
*ssindex = 48;
return (diff);
}
/*
* Adpcm
* Takes a signed linear signal and encodes it as ADPCM
* For more information see http://support.dialogic.com/appnotes/adpcm.pdf
*
* Results:
* Foo.
*
* Side effects:
* signal gets updated with each pass.
*/
static inline unsigned char
adpcm (short csig, short *ssindex, short *signal)
{
short diff, step;
unsigned char encoded;
step = stpsz[*ssindex];
/*
* Clip csig if too large or too small
*/
csig >>= 4;
diff = csig - *signal;
if (diff < 0)
{
encoded = 8;
diff = -diff;
}
else
encoded = 0;
if (diff >= step)
{
encoded |= 4;
diff -= step;
}
step >>= 1;
if (diff >= step)
{
encoded |= 2;
diff -= step;
}
step >>= 1;
if (diff >= step)
encoded |= 1;
*signal += decode (encoded, ssindex);
return (encoded);
}
/*
* Private workspace for translating signed linear signals to ADPCM.
*/
struct adpcm_encoder_pvt
{
struct ast_frame f;
char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
short inbuf[BUFFER_SIZE]; /* Unencoded signed linear values */
unsigned char outbuf[BUFFER_SIZE]; /* Encoded ADPCM, two nibbles to a word */
short ssindex;
short signal;
int tail;
};
/*
* Private workspace for translating ADPCM signals to signed linear.
*/
struct adpcm_decoder_pvt
{
struct ast_frame f;
char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
short outbuf[BUFFER_SIZE]; /* Decoded signed linear values */
int tail;
};
/*
* AdpcmToLin_New
* Create a new instance of adpcm_decoder_pvt.
*
* Results:
* Returns a pointer to the new instance.
*
* Side effects:
* None.
*/
static struct ast_translator_pvt *
adpcmtolin_new ()
{
struct adpcm_decoder_pvt *tmp;
tmp = malloc (sizeof (struct adpcm_decoder_pvt));
if (tmp)
{
memset(tmp, 0, sizeof(*tmp));
tmp->tail = 0;
localusecnt++;
ast_update_use_count ();
}
return (struct ast_translator_pvt *) tmp;
}
/*
* LinToAdpcm_New
* Create a new instance of adpcm_encoder_pvt.
*
* Results:
* Returns a pointer to the new instance.
*
* Side effects:
* None.
*/
static struct ast_translator_pvt *
lintoadpcm_new ()
{
struct adpcm_encoder_pvt *tmp;
tmp = malloc (sizeof (struct adpcm_encoder_pvt));
if (tmp)
{
memset(tmp, 0, sizeof(*tmp));
localusecnt++;
ast_update_use_count ();
tmp->tail = 0;
}
return (struct ast_translator_pvt *) tmp;
}
/*
* AdpcmToLin_FrameIn
* Fill an input buffer with packed 4-bit ADPCM values if there is room
* left.
*
* Results:
* Foo
*
* Side effects:
* tmp->tail is the number of packed values in the buffer.
*/
static int
adpcmtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
{
struct adpcm_decoder_pvt *tmp = (struct adpcm_decoder_pvt *) pvt;
int x;
short signal;
short ssindex;
unsigned char *b;
if (f->datalen < 3) {
ast_log(LOG_WARNING, "Didn't have at least three bytes of input\n");
return -1;
}
if ((f->datalen - 3) * 4 > sizeof(tmp->outbuf)) {
ast_log(LOG_WARNING, "Out of buffer space\n");
return -1;
}
/* Reset ssindex and signal to frame's specified values */
b = f->data;
ssindex = b[0];
if (ssindex < 0)
ssindex = 0;
if (ssindex > 48)
ssindex = 48;
signal = (b[1] << 8) | b[2];
for (x=3;x<f->datalen;x++) {
signal += decode(b[x] >> 4, &ssindex);
if (signal > 2047)
signal = 2047;
if (signal < -2048)
signal = -2048;
tmp->outbuf[tmp->tail++] = signal << 4;
signal += decode(b[x] & 0x0f, &ssindex);
if (signal > 2047)
signal = 2047;
if (signal < -2048)
signal = -2048;
tmp->outbuf[tmp->tail++] = signal << 4;
}
return 0;
}
/*
* AdpcmToLin_FrameOut
* Convert 4-bit ADPCM encoded signals to 16-bit signed linear.
*
* Results:
* Converted signals are placed in tmp->f.data, tmp->f.datalen
* and tmp->f.timelen are calculated.
*
* Side effects:
* None.
*/
static struct ast_frame *
adpcmtolin_frameout (struct ast_translator_pvt *pvt)
{
struct adpcm_decoder_pvt *tmp = (struct adpcm_decoder_pvt *) pvt;
if (!tmp->tail)
return NULL;
tmp->f.frametype = AST_FRAME_VOICE;
tmp->f.subclass = AST_FORMAT_SLINEAR;
tmp->f.datalen = tmp->tail *2;
tmp->f.timelen = tmp->tail / 8;
tmp->f.mallocd = 0;
tmp->f.offset = AST_FRIENDLY_OFFSET;
tmp->f.src = __PRETTY_FUNCTION__;
tmp->f.data = tmp->outbuf;
tmp->tail = 0;
return &tmp->f;
}
/*
* LinToAdpcm_FrameIn
* Fill an input buffer with 16-bit signed linear PCM values.
*
* Results:
* None.
*
* Side effects:
* tmp->tail is number of signal values in the input buffer.
*/
static int
lintoadpcm_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
{
struct adpcm_encoder_pvt *tmp = (struct adpcm_encoder_pvt *) pvt;
if ((tmp->tail + f->datalen / 2) < (sizeof (tmp->inbuf) / 2))
{
memcpy (&tmp->inbuf[tmp->tail], f->data, f->datalen);
tmp->tail += f->datalen / 2;
}
else
{
ast_log (LOG_WARNING, "Out of buffer space\n");
return -1;
}
return 0;
}
/*
* LinToAdpcm_FrameOut
* Convert a buffer of raw 16-bit signed linear PCM to a buffer
* of 4-bit ADPCM packed two to a byte (Big Endian).
*
* Results:
* Foo
*
* Side effects:
* Leftover inbuf data gets packed, tail gets updated.
*/
static struct ast_frame *
lintoadpcm_frameout (struct ast_translator_pvt *pvt)
{
struct adpcm_encoder_pvt *tmp = (struct adpcm_encoder_pvt *) pvt;
unsigned char adpcm0, adpcm1;
int i_max, i;
if (tmp->tail < 2) return NULL;
i_max = (tmp->tail / 2) * 2;
tmp->outbuf[0] = tmp->ssindex & 0xff;
tmp->outbuf[1] = (tmp->signal >> 8) & 0xff;
tmp->outbuf[2] = (tmp->signal & 0xff);
for (i = 0; i < i_max; i+=2)
{
adpcm0 = adpcm(tmp->inbuf[i], &tmp->ssindex, &tmp->signal);
adpcm1 = adpcm(tmp->inbuf[i+1], &tmp->ssindex, &tmp->signal);
tmp->outbuf[i/2 + 3] = (adpcm0 << 4) | adpcm1;
};
tmp->f.frametype = AST_FRAME_VOICE;
tmp->f.subclass = AST_FORMAT_ADPCM;
tmp->f.timelen = i_max / 8;
tmp->f.mallocd = 0;
tmp->f.offset = AST_FRIENDLY_OFFSET;
tmp->f.src = __PRETTY_FUNCTION__;
tmp->f.data = tmp->outbuf;
tmp->f.datalen = i_max / 2 + 3;
/*
* If there is a signal left over (there should be no more than
* one) move it to the beginning of the input buffer.
*/
if (tmp->tail == i_max)
tmp->tail = 0;
else
{
tmp->inbuf[0] = tmp->inbuf[tmp->tail];
tmp->tail = 1;
}
return &tmp->f;
}
/*
* AdpcmToLin_Sample
*/
static struct ast_frame *
adpcmtolin_sample ()
{
static struct ast_frame f;
f.frametype = AST_FRAME_VOICE;
f.subclass = AST_FORMAT_ADPCM;
f.datalen = sizeof (adpcm_slin_ex);
f.timelen = sizeof(adpcm_slin_ex) / 4;
f.mallocd = 0;
f.offset = 0;
f.src = __PRETTY_FUNCTION__;
f.data = adpcm_slin_ex;
return &f;
}
/*
* LinToAdpcm_Sample
*/
static struct ast_frame *
lintoadpcm_sample ()
{
static struct ast_frame f;
f.frametype = AST_FRAME_VOICE;
f.subclass = AST_FORMAT_SLINEAR;
f.datalen = sizeof (slin_adpcm_ex);
/* Assume 8000 Hz */
f.timelen = sizeof (slin_adpcm_ex) / 16;
f.mallocd = 0;
f.offset = 0;
f.src = __PRETTY_FUNCTION__;
f.data = slin_adpcm_ex;
return &f;
}
/*
* Adpcm_Destroy
* Destroys a private workspace.
*
* Results:
* It's gone!
*
* Side effects:
* None.
*/
static void
adpcm_destroy (struct ast_translator_pvt *pvt)
{
free (pvt);
localusecnt--;
ast_update_use_count ();
}
/*
* The complete translator for ADPCMToLin.
*/
static struct ast_translator adpcmtolin = {
"adpcmtolin",
AST_FORMAT_ADPCM,
AST_FORMAT_SLINEAR,
adpcmtolin_new,
adpcmtolin_framein,
adpcmtolin_frameout,
adpcm_destroy,
/* NULL */
adpcmtolin_sample
};
/*
* The complete translator for LinToADPCM.
*/
static struct ast_translator lintoadpcm = {
"lintoadpcm",
AST_FORMAT_SLINEAR,
AST_FORMAT_ADPCM,
lintoadpcm_new,
lintoadpcm_framein,
lintoadpcm_frameout,
adpcm_destroy,
/* NULL */
lintoadpcm_sample
};
int
unload_module (void)
{
int res;
ast_pthread_mutex_lock (&localuser_lock);
res = ast_unregister_translator (&lintoadpcm);
if (!res)
res = ast_unregister_translator (&adpcmtolin);
if (localusecnt)
res = -1;
ast_pthread_mutex_unlock (&localuser_lock);
return res;
}
int
load_module (void)
{
int res;
res = ast_register_translator (&adpcmtolin);
if (!res)
res = ast_register_translator (&lintoadpcm);
else
ast_unregister_translator (&adpcmtolin);
return res;
}
/*
* Return a description of this module.
*/
char *
description (void)
{
return tdesc;
}
int
usecount (void)
{
int res;
STANDARD_USECOUNT (res);
return res;
}
char *
key ()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -23,7 +23,6 @@
#include <asterisk/translate.h>
#include <asterisk/module.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <pthread.h>
#include <fcntl.h>
#include <stdlib.h>
@@ -76,7 +75,7 @@ struct g723_encoder_pvt {
/* Space to build offset */
char offset[AST_FRIENDLY_OFFSET];
/* Buffer for our outgoing frame */
char outbuf[8000];
char outbuf[24];
/* Enough to store a full second */
short buf[8000];
int tail;
@@ -186,60 +185,27 @@ static struct ast_frame *g723tolin_frameout(struct ast_translator_pvt *pvt)
return &tmp->f;
}
static int g723_len(unsigned char buf)
{
switch(buf & TYPE_MASK) {
case TYPE_MASK:
case TYPE_SILENCE:
return 4;
break;
case TYPE_HIGH:
return 24;
break;
case TYPE_LOW:
return 20;
break;
default:
ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", buf & TYPE_MASK);
}
return -1;
}
static int g723tolin_framein(struct ast_translator_pvt *pvt, struct ast_frame *f)
{
struct g723_decoder_pvt *tmp = (struct g723_decoder_pvt *)pvt;
int len = 0;
int res;
#ifdef ANNEX_B
FLOAT tmpdata[Frame];
int x;
#endif
while(len < f->datalen) {
/* Assuming there's space left, decode into the current buffer at
the tail location */
res = g723_len(((unsigned char *)f->data + len)[0]);
if (res < 0) {
ast_log(LOG_WARNING, "Invalid data\n");
return -1;
}
if (res + len > f->datalen) {
ast_log(LOG_WARNING, "Measured length exceeds frame length\n");
return -1;
}
if (tmp->tail + Frame < sizeof(tmp->buf)/2) {
/* Assuming there's space left, decode into the current buffer at
the tail location */
if (tmp->tail + Frame < sizeof(tmp->buf)/2) {
#ifdef ANNEX_B
Decod(&tmp->dec, tmpdata, f->data + len, 0);
for (x=0;x<Frame;x++)
(tmp->buf + tmp->tail)[x] = (short)(tmpdata[x]);
Decod(&tmp->dec, tmpdata, f->data, 0);
for (x=0;x<Frame;x++)
(tmp->buf + tmp->tail)[x] = (short)(tmpdata[x]);
#else
Decod(&tmp->dec, tmp->buf + tmp->tail, f->data + len, 0);
Decod(&tmp->dec, tmp->buf + tmp->tail, f->data, 0);
#endif
tmp->tail+=Frame;
} else {
ast_log(LOG_WARNING, "Out of buffer space\n");
return -1;
}
len += res;
tmp->tail+=Frame;
} else {
ast_log(LOG_WARNING, "Out of buffer space\n");
return -1;
}
return 0;
}
@@ -268,39 +234,43 @@ static struct ast_frame *lintog723_frameout(struct ast_translator_pvt *pvt)
int x;
FLOAT tmpdata[Frame];
#endif
int cnt=0;
/* We can't work on anything less than a frame in size */
if (tmp->tail < Frame)
return NULL;
/* Encode a frame of data */
#ifdef ANNEX_B
for (x=0;x<Frame;x++)
tmpdata[x] = tmp->buf[x];
Coder(&tmp->cod, tmpdata, tmp->outbuf);
#else
Coder(&tmp->cod, tmp->buf, tmp->outbuf);
#endif
tmp->f.frametype = AST_FRAME_VOICE;
tmp->f.subclass = AST_FORMAT_G723_1;
/* Assume 8000 Hz */
tmp->f.timelen = 30;
tmp->f.mallocd = 0;
tmp->f.offset = AST_FRIENDLY_OFFSET;
tmp->f.src = __PRETTY_FUNCTION__;
tmp->f.timelen = 0;
tmp->f.mallocd = 0;
while(tmp->tail >= Frame) {
/* Encode a frame of data */
if (cnt + 24 >= sizeof(tmp->outbuf)) {
ast_log(LOG_WARNING, "Out of buffer space\n");
return NULL;
}
#ifdef ANNEX_B
for (x=0;x<Frame;x++)
tmpdata[x] = tmp->buf[x];
Coder(&tmp->cod, tmpdata, tmp->outbuf + cnt);
#else
Coder(&tmp->cod, tmp->buf, tmp->outbuf + cnt);
#endif
/* Assume 8000 Hz */
tmp->f.timelen += 30;
cnt += g723_len(tmp->outbuf[0]);
tmp->tail -= Frame;
/* Move the data at the end of the buffer to the front */
if (tmp->tail)
memmove(tmp->buf, tmp->buf + Frame, tmp->tail * 2);
}
tmp->f.datalen = cnt;
tmp->f.data = tmp->outbuf;
switch(tmp->outbuf[0] & TYPE_MASK) {
case TYPE_MASK:
case TYPE_SILENCE:
tmp->f.datalen = 4;
break;
case TYPE_HIGH:
tmp->f.datalen = 24;
break;
case TYPE_LOW:
tmp->f.datalen = 20;
break;
default:
ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", tmp->outbuf[0] & TYPE_MASK);
}
tmp->tail -= Frame;
/* Move the data at the end of the buffer to the front */
if (tmp->tail)
memmove(tmp->buf, tmp->buf + Frame, tmp->tail * 2);
#if 0
/* Save to a g723 sample output file... */
{
@@ -358,13 +328,13 @@ static struct ast_translator lintog723 =
int unload_module(void)
{
int res;
ast_pthread_mutex_lock(&localuser_lock);
pthread_mutex_lock(&localuser_lock);
res = ast_unregister_translator(&lintog723);
if (!res)
res = ast_unregister_translator(&g723tolin);
if (localusecnt)
res = -1;
ast_pthread_mutex_unlock(&localuser_lock);
pthread_mutex_unlock(&localuser_lock);
return res;
}
@@ -390,8 +360,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -22,7 +22,6 @@
#include <asterisk/translate.h>
#include <asterisk/module.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <pthread.h>
#include <fcntl.h>
#include <stdlib.h>
@@ -48,7 +47,7 @@ struct ast_translator_pvt {
/* Space to build offset */
char offset[AST_FRIENDLY_OFFSET];
/* Buffer for our outgoing frame */
short outbuf[8000];
gsm_frame outbuf;
/* Enough to store a full second */
short buf[8000];
int tail;
@@ -119,29 +118,34 @@ static struct ast_frame *gsmtolin_frameout(struct ast_translator_pvt *tmp)
/* Reset tail pointer */
tmp->tail = 0;
#if 0
/* Save a sample frame */
{ static int samplefr = 0;
if (samplefr == 80) {
int fd;
fd = open("gsm.example", O_WRONLY | O_CREAT, 0644);
write(fd, tmp->f.data, tmp->f.datalen);
close(fd);
}
samplefr++;
}
#endif
return &tmp->f;
}
static int gsmtolin_framein(struct ast_translator_pvt *tmp, struct ast_frame *f)
{
/* Assuming there's space left, decode into the current buffer at
the tail location. Read in as many frames as there are */
int x;
if (f->datalen % 33) {
ast_log(LOG_WARNING, "Huh? A GSM frame that isn't a multiple of 33 bytes long from %s (%d)?\n", f->src, f->datalen);
return -1;
}
for (x=0;x<f->datalen;x+=33) {
if (tmp->tail + 160 < sizeof(tmp->buf)/2) {
if (gsm_decode(tmp->gsm, f->data + x, tmp->buf + tmp->tail)) {
ast_log(LOG_WARNING, "Invalid GSM data\n");
return -1;
}
tmp->tail+=160;
} else {
ast_log(LOG_WARNING, "Out of buffer space\n");
the tail location */
if (tmp->tail + 160 < sizeof(tmp->buf)/2) {
if (gsm_decode(tmp->gsm, f->data, tmp->buf + tmp->tail)) {
ast_log(LOG_WARNING, "Invalid GSM data\n");
return -1;
}
tmp->tail+=160;
} else {
ast_log(LOG_WARNING, "Out of buffer space\n");
return -1;
}
return 0;
}
@@ -164,32 +168,34 @@ static int lintogsm_framein(struct ast_translator_pvt *tmp, struct ast_frame *f)
static struct ast_frame *lintogsm_frameout(struct ast_translator_pvt *tmp)
{
int x=0;
/* We can't work on anything less than a frame in size */
if (tmp->tail < 160)
return NULL;
/* Encode a frame of data */
gsm_encode(tmp->gsm, tmp->buf, tmp->outbuf);
tmp->f.frametype = AST_FRAME_VOICE;
tmp->f.subclass = AST_FORMAT_GSM;
tmp->f.datalen = 33;
/* Assume 8000 Hz -- 20 ms */
tmp->f.timelen = 20;
tmp->f.mallocd = 0;
tmp->f.offset = AST_FRIENDLY_OFFSET;
tmp->f.src = __PRETTY_FUNCTION__;
tmp->f.data = tmp->outbuf;
while(tmp->tail >= 160) {
if ((x+1) * 33 >= sizeof(tmp->outbuf)) {
ast_log(LOG_WARNING, "Out of buffer space\n");
return NULL;
tmp->tail -= 160;
/* Move the data at the end of the buffer to the front */
if (tmp->tail)
memmove(tmp->buf, tmp->buf + 160, tmp->tail * 2);
#if 0
/* Save the frames */
{
static int fd2 = -1;
if (fd2 == -1) {
fd2 = open("gsm.example", O_WRONLY | O_CREAT | O_TRUNC, 0644);
}
/* Encode a frame of data */
gsm_encode(tmp->gsm, tmp->buf, (gsm_byte *) tmp->outbuf + (x * 33));
/* Assume 8000 Hz -- 20 ms */
tmp->tail -= 160;
/* Move the data at the end of the buffer to the front */
if (tmp->tail)
memmove(tmp->buf, tmp->buf + 160, tmp->tail * 2);
x++;
}
tmp->f.datalen = x * 33;
tmp->f.timelen = x * 20;
write(fd2, tmp->f.data, tmp->f.datalen);
}
#endif
return &tmp->f;
}
@@ -222,13 +228,13 @@ static struct ast_translator lintogsm =
int unload_module(void)
{
int res;
ast_pthread_mutex_lock(&localuser_lock);
pthread_mutex_lock(&localuser_lock);
res = ast_unregister_translator(&lintogsm);
if (!res)
res = ast_unregister_translator(&gsmtolin);
if (localusecnt)
res = -1;
ast_pthread_mutex_unlock(&localuser_lock);
pthread_mutex_unlock(&localuser_lock);
return res;
}
@@ -254,8 +260,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -20,7 +20,6 @@
#include <asterisk/translate.h>
#include <asterisk/module.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <pthread.h>
#include <fcntl.h>
#include <stdlib.h>
@@ -56,7 +55,7 @@ struct ast_translator_pvt {
/* Space to build offset */
char offset[AST_FRIENDLY_OFFSET];
/* Buffer for our outgoing frame */
short outbuf[8000];
short outbuf[LPC10_SAMPLES_PER_FRAME];
/* Enough to store a full second */
short buf[8000];
int tail;
@@ -198,32 +197,26 @@ static int lpc10tolin_framein(struct ast_translator_pvt *tmp, struct ast_frame *
/* Assuming there's space left, decode into the current buffer at
the tail location */
int x;
int len=0;
float tmpbuf[LPC10_SAMPLES_PER_FRAME];
short *sd;
INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME];
while(len + LPC10_BYTES_IN_COMPRESSED_FRAME <= f->datalen) {
if (tmp->tail + LPC10_SAMPLES_PER_FRAME < sizeof(tmp->buf)/2) {
sd = tmp->buf + tmp->tail;
extract_bits(bits, f->data + len);
if (lpc10_decode(bits, tmpbuf, tmp->lpc10.dec)) {
ast_log(LOG_WARNING, "Invalid lpc10 data\n");
return -1;
}
for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++) {
/* Convert to a real between -1.0 and 1.0 */
sd[x] = 32768.0 * tmpbuf[x];
}
tmp->tail+=LPC10_SAMPLES_PER_FRAME;
} else {
ast_log(LOG_WARNING, "Out of buffer space\n");
if (tmp->tail + LPC10_SAMPLES_PER_FRAME < sizeof(tmp->buf)/2) {
sd = tmp->buf + tmp->tail;
extract_bits(bits, f->data);
if (lpc10_decode(bits, tmpbuf, tmp->lpc10.dec)) {
ast_log(LOG_WARNING, "Invalid lpc10 data\n");
return -1;
}
len += LPC10_BYTES_IN_COMPRESSED_FRAME;
for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++) {
/* Convert to a real between -1.0 and 1.0 */
sd[x] = 32768.0 * tmpbuf[x];
}
tmp->tail+=LPC10_SAMPLES_PER_FRAME;
} else {
ast_log(LOG_WARNING, "Out of buffer space\n");
return -1;
}
if (len != f->datalen)
printf("Decoded %d, expected %d\n", len, f->datalen);
return 0;
}
@@ -246,48 +239,35 @@ static int lintolpc10_framein(struct ast_translator_pvt *tmp, struct ast_frame *
static struct ast_frame *lintolpc10_frameout(struct ast_translator_pvt *tmp)
{
int x;
int consumed = 0;
float tmpbuf[LPC10_SAMPLES_PER_FRAME];
INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME];
/* We can't work on anything less than a frame in size */
if (tmp->tail < LPC10_SAMPLES_PER_FRAME)
return NULL;
/* Start with an empty frame */
tmp->f.timelen = 0;
tmp->f.datalen = 0;
/* Encode a frame of data */
for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++) {
tmpbuf[x] = (float)tmp->buf[x] / 32768.0;
}
lpc10_encode(tmpbuf, bits, tmp->lpc10.enc);
build_bits((unsigned char *)tmp->outbuf, bits);
tmp->f.frametype = AST_FRAME_VOICE;
tmp->f.subclass = AST_FORMAT_LPC10;
while(tmp->tail >= LPC10_SAMPLES_PER_FRAME) {
if (tmp->f.datalen + LPC10_BYTES_IN_COMPRESSED_FRAME > sizeof(tmp->outbuf)) {
ast_log(LOG_WARNING, "Out of buffer space\n");
return NULL;
}
/* Encode a frame of data */
for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++) {
tmpbuf[x] = (float)tmp->buf[x+consumed] / 32768.0;
}
lpc10_encode(tmpbuf, bits, tmp->lpc10.enc);
build_bits(((unsigned char *)tmp->outbuf) + tmp->f.datalen, bits);
tmp->f.datalen += LPC10_BYTES_IN_COMPRESSED_FRAME;
tmp->f.timelen += 22;
/* We alternate between 22 and 23 ms to simulate 22.5 ms */
tmp->f.timelen += tmp->longer;
/* Use one of the two left over bits to record if this is a 22 or 23 ms frame...
important for IAX use */
tmp->longer = 1 - tmp->longer;
#if 0 /* what the heck was this for? */
((char *)(tmp->f.data))[consumed - 1] |= tmp->longer;
#endif
tmp->tail -= LPC10_SAMPLES_PER_FRAME;
consumed += LPC10_SAMPLES_PER_FRAME;
}
tmp->f.datalen = LPC10_BYTES_IN_COMPRESSED_FRAME;
tmp->f.timelen = 22;
/* We alternate between 22 and 23 ms to simulate 22.5 ms */
tmp->f.timelen += tmp->longer;
/* Use one of the two left over bits to record if this is a 22 or 23 ms frame...
important for IAX use */
tmp->longer = 1 - tmp->longer;
tmp->f.mallocd = 0;
tmp->f.offset = AST_FRIENDLY_OFFSET;
tmp->f.src = __PRETTY_FUNCTION__;
tmp->f.data = tmp->outbuf;
((char *)(tmp->f.data))[LPC10_BYTES_IN_COMPRESSED_FRAME - 1] |= tmp->longer;
tmp->tail -= LPC10_SAMPLES_PER_FRAME;
/* Move the data at the end of the buffer to the front */
if (tmp->tail)
memmove(tmp->buf, tmp->buf + consumed, tmp->tail * 2);
memmove(tmp->buf, tmp->buf + LPC10_SAMPLES_PER_FRAME, tmp->tail * 2);
#if 0
/* Save a sample frame */
{ static int samplefr = 0;
@@ -334,13 +314,13 @@ static struct ast_translator lintolpc10 =
int unload_module(void)
{
int res;
ast_pthread_mutex_lock(&localuser_lock);
pthread_mutex_lock(&localuser_lock);
res = ast_unregister_translator(&lintolpc10);
if (!res)
res = ast_unregister_translator(&lpc10tolin);
if (localusecnt)
res = -1;
ast_pthread_mutex_unlock(&localuser_lock);
pthread_mutex_unlock(&localuser_lock);
return res;
}
@@ -366,8 +346,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -17,7 +17,6 @@
#include <asterisk/translate.h>
#include <asterisk/module.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
@@ -109,30 +108,40 @@ static struct ast_frame *mp3tolin_sample()
static struct ast_frame *mp3tolin_frameout(struct ast_translator_pvt *tmp)
{
int sent;
if (!tmp->tail)
return NULL;
sent = tmp->tail;
if (sent > MAX_OUT_FRAME/2)
sent = MAX_OUT_FRAME/2;
/* Signed linear is no particular frame size, so just send whatever
we have in the buffer in one lump sum */
tmp->f.frametype = AST_FRAME_VOICE;
tmp->f.subclass = AST_FORMAT_SLINEAR;
tmp->f.datalen = tmp->tail * 2;
tmp->f.datalen = sent * 2;
/* Assume 8000 Hz */
tmp->f.timelen = tmp->tail / 8;
tmp->f.timelen = sent / 8;
tmp->f.mallocd = 0;
tmp->f.offset = AST_FRIENDLY_OFFSET;
tmp->f.src = __PRETTY_FUNCTION__;
tmp->f.data = tmp->buf;
memcpy(tmp->outbuf, tmp->buf, tmp->tail * 2);
tmp->f.data = tmp->outbuf;
/* Reset tail pointer */
tmp->tail = 0;
tmp->tail -= sent;
if (tmp->tail)
memmove(tmp->buf, tmp->buf + sent, tmp->tail * 2);
#if 0
/* Save a sample frame */
{
static int fd = -1;
if (fd < 0)
fd = open("mp3out.raw", O_WRONLY | O_CREAT | O_TRUNC, 0644);
{ static int samplefr = 0;
if (samplefr == 80) {
int fd;
fd = open("mp3.example", O_WRONLY | O_CREAT, 0644);
write(fd, tmp->f.data, tmp->f.datalen);
close(fd);
}
samplefr++;
}
#endif
return &tmp->f;
}
@@ -286,11 +295,11 @@ static struct ast_translator mp3tolin =
int unload_module(void)
{
int res;
ast_pthread_mutex_lock(&localuser_lock);
pthread_mutex_lock(&localuser_lock);
res = ast_unregister_translator(&mp3tolin);
if (localusecnt)
res = -1;
ast_pthread_mutex_unlock(&localuser_lock);
pthread_mutex_unlock(&localuser_lock);
return res;
}
@@ -312,8 +321,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,378 +0,0 @@
/* codec_ulaw.c - translate between signed linear and ulaw
*
* Asterisk -- A telephony toolkit for Linux.
*
* Copyright (c) 2001 Linux Support Services, Inc. All rights reserved.
*
* Mark Spencer <markster@linux-support.net
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/logger.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/channel.h>
#include <asterisk/ulaw.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BUFFER_SIZE 8096 /* size for the translation buffers */
static pthread_mutex_t localuser_lock = PTHREAD_MUTEX_INITIALIZER;
static int localusecnt = 0;
static char *tdesc = "Mu-law Coder/Decoder";
/* Sample frame data */
#include "slin_ulaw_ex.h"
#include "ulaw_slin_ex.h"
/*
* Private workspace for translating signed linear signals to ulaw.
*/
struct ulaw_encoder_pvt
{
struct ast_frame f;
char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
unsigned char outbuf[BUFFER_SIZE]; /* Encoded ulaw, two nibbles to a word */
int tail;
};
/*
* Private workspace for translating ulaw signals to signed linear.
*/
struct ulaw_decoder_pvt
{
struct ast_frame f;
char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
short outbuf[BUFFER_SIZE]; /* Decoded signed linear values */
int tail;
};
/*
* ulawToLin_New
* Create a new instance of ulaw_decoder_pvt.
*
* Results:
* Returns a pointer to the new instance.
*
* Side effects:
* None.
*/
static struct ast_translator_pvt *
ulawtolin_new ()
{
struct ulaw_decoder_pvt *tmp;
tmp = malloc (sizeof (struct ulaw_decoder_pvt));
if (tmp)
{
memset(tmp, 0, sizeof(*tmp));
tmp->tail = 0;
localusecnt++;
ast_update_use_count ();
}
return (struct ast_translator_pvt *) tmp;
}
/*
* LinToulaw_New
* Create a new instance of ulaw_encoder_pvt.
*
* Results:
* Returns a pointer to the new instance.
*
* Side effects:
* None.
*/
static struct ast_translator_pvt *
lintoulaw_new ()
{
struct ulaw_encoder_pvt *tmp;
tmp = malloc (sizeof (struct ulaw_encoder_pvt));
if (tmp)
{
memset(tmp, 0, sizeof(*tmp));
localusecnt++;
ast_update_use_count ();
tmp->tail = 0;
}
return (struct ast_translator_pvt *) tmp;
}
/*
* ulawToLin_FrameIn
* Fill an input buffer with packed 4-bit ulaw values if there is room
* left.
*
* Results:
* Foo
*
* Side effects:
* tmp->tail is the number of packed values in the buffer.
*/
static int
ulawtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
{
struct ulaw_decoder_pvt *tmp = (struct ulaw_decoder_pvt *) pvt;
int x;
unsigned char *b;
if ((tmp->tail + f->datalen) * 2 > sizeof(tmp->outbuf)) {
ast_log(LOG_WARNING, "Out of buffer space\n");
return -1;
}
/* Reset ssindex and signal to frame's specified values */
b = f->data;
for (x=0;x<f->datalen;x++)
tmp->outbuf[tmp->tail + x] = ast_mulaw[b[x]];
tmp->tail += f->datalen;
return 0;
}
/*
* ulawToLin_FrameOut
* Convert 4-bit ulaw encoded signals to 16-bit signed linear.
*
* Results:
* Converted signals are placed in tmp->f.data, tmp->f.datalen
* and tmp->f.timelen are calculated.
*
* Side effects:
* None.
*/
static struct ast_frame *
ulawtolin_frameout (struct ast_translator_pvt *pvt)
{
struct ulaw_decoder_pvt *tmp = (struct ulaw_decoder_pvt *) pvt;
if (!tmp->tail)
return NULL;
tmp->f.frametype = AST_FRAME_VOICE;
tmp->f.subclass = AST_FORMAT_SLINEAR;
tmp->f.datalen = tmp->tail *2;
tmp->f.timelen = tmp->tail / 8;
tmp->f.mallocd = 0;
tmp->f.offset = AST_FRIENDLY_OFFSET;
tmp->f.src = __PRETTY_FUNCTION__;
tmp->f.data = tmp->outbuf;
tmp->tail = 0;
return &tmp->f;
}
/*
* LinToulaw_FrameIn
* Fill an input buffer with 16-bit signed linear PCM values.
*
* Results:
* None.
*
* Side effects:
* tmp->tail is number of signal values in the input buffer.
*/
static int
lintoulaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
{
struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
int x;
short *s;
if (tmp->tail + f->datalen/2 >= sizeof(tmp->outbuf))
{
ast_log (LOG_WARNING, "Out of buffer space\n");
return -1;
}
s = f->data;
for (x=0;x<f->datalen/2;x++)
tmp->outbuf[x+tmp->tail] = ast_lin2mu[s[x]+32768];
tmp->tail += f->datalen/2;
return 0;
}
/*
* LinToulaw_FrameOut
* Convert a buffer of raw 16-bit signed linear PCM to a buffer
* of 4-bit ulaw packed two to a byte (Big Endian).
*
* Results:
* Foo
*
* Side effects:
* Leftover inbuf data gets packed, tail gets updated.
*/
static struct ast_frame *
lintoulaw_frameout (struct ast_translator_pvt *pvt)
{
struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
if (tmp->tail) {
tmp->f.frametype = AST_FRAME_VOICE;
tmp->f.subclass = AST_FORMAT_ULAW;
tmp->f.timelen = tmp->tail / 8;
tmp->f.mallocd = 0;
tmp->f.offset = AST_FRIENDLY_OFFSET;
tmp->f.src = __PRETTY_FUNCTION__;
tmp->f.data = tmp->outbuf;
tmp->f.datalen = tmp->tail;
tmp->tail = 0;
return &tmp->f;
} else return NULL;
}
/*
* ulawToLin_Sample
*/
static struct ast_frame *
ulawtolin_sample ()
{
static struct ast_frame f;
f.frametype = AST_FRAME_VOICE;
f.subclass = AST_FORMAT_ULAW;
f.datalen = sizeof (ulaw_slin_ex);
f.timelen = sizeof(ulaw_slin_ex) / 8;
f.mallocd = 0;
f.offset = 0;
f.src = __PRETTY_FUNCTION__;
f.data = ulaw_slin_ex;
return &f;
}
/*
* LinToulaw_Sample
*/
static struct ast_frame *
lintoulaw_sample ()
{
static struct ast_frame f;
f.frametype = AST_FRAME_VOICE;
f.subclass = AST_FORMAT_SLINEAR;
f.datalen = sizeof (slin_ulaw_ex);
/* Assume 8000 Hz */
f.timelen = sizeof (slin_ulaw_ex) / 16;
f.mallocd = 0;
f.offset = 0;
f.src = __PRETTY_FUNCTION__;
f.data = slin_ulaw_ex;
return &f;
}
/*
* ulaw_Destroy
* Destroys a private workspace.
*
* Results:
* It's gone!
*
* Side effects:
* None.
*/
static void
ulaw_destroy (struct ast_translator_pvt *pvt)
{
free (pvt);
localusecnt--;
ast_update_use_count ();
}
/*
* The complete translator for ulawToLin.
*/
static struct ast_translator ulawtolin = {
"ulawtolin",
AST_FORMAT_ULAW,
AST_FORMAT_SLINEAR,
ulawtolin_new,
ulawtolin_framein,
ulawtolin_frameout,
ulaw_destroy,
/* NULL */
ulawtolin_sample
};
/*
* The complete translator for LinToulaw.
*/
static struct ast_translator lintoulaw = {
"lintoulaw",
AST_FORMAT_SLINEAR,
AST_FORMAT_ULAW,
lintoulaw_new,
lintoulaw_framein,
lintoulaw_frameout,
ulaw_destroy,
/* NULL */
lintoulaw_sample
};
int
unload_module (void)
{
int res;
ast_pthread_mutex_lock (&localuser_lock);
res = ast_unregister_translator (&lintoulaw);
if (!res)
res = ast_unregister_translator (&ulawtolin);
if (localusecnt)
res = -1;
ast_pthread_mutex_unlock (&localuser_lock);
return res;
}
int
load_module (void)
{
int res;
res = ast_register_translator (&ulawtolin);
if (!res)
res = ast_register_translator (&lintoulaw);
else
ast_unregister_translator (&ulawtolin);
return res;
}
/*
* Return a description of this module.
*/
char *
description (void)
{
return tdesc;
}
int
usecount (void)
{
int res;
STANDARD_USECOUNT (res);
return res;
}
char *
key ()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -7,11 +7,11 @@
SASR = -DSASR
######### Define SASR if >> is a signed arithmetic shift (-1 >> 1 == -1)
#MULHACK = -DUSE_FLOAT_MUL
MULHACK = -DUSE_FLOAT_MUL
######### Define this if your host multiplies floats faster than integers,
######### e.g. on a SPARCstation.
#FAST = -DFAST
FAST = -DFAST
######### Define together with USE_FLOAT_MUL to enable the GSM library's
######### approximation option for incorrect, but good-enough results.
@@ -30,17 +30,6 @@ WAV49 = -DWAV49
######### define this, and read about the GSM_OPT_WAV49 option in the
######### manual page on gsm_option(3).
K6OPT = -DK6OPT
#K6OPT =
######### Define to enable MMXTM optimizations for x86 architecture CPU's
######### which support MMX instructions. This should be newer pentiums,
######### ppro's, etc, as well as the AMD K6 and K7. The compile will
######### probably require gcc.
PG =
#PG = -g -pg
######### Profiling flags. If you don't know what that means, leave it blank.
# 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.
@@ -54,7 +43,7 @@ PG =
# CC = /usr/lang/acc
# CCFLAGS = -c -O
CC = gcc -ansi -pedantic -O6 -mpentium -fschedule-insns2 -fomit-frame-pointer
CC = gcc -ansi -pedantic
CCFLAGS += -c -DNeedFunctionPrototypes=1 -finline-functions -funroll-loops
LD = $(CC)
@@ -137,21 +126,20 @@ INC = $(ROOT)/inc
# Flags
DEBUG = -DNDEBUG
# DEBUG = -DNDEBUG
######### Remove -DNDEBUG to enable assertions.
CFLAGS = $(PG) $(CCFLAGS) $(SASR) $(DEBUG) $(MULHACK) $(FAST) \
$(LTP_CUT) $(WAV49) $(K6OPT) $(CCINC) -I$(INC)
CFLAGS = $(CCFLAGS) $(SASR) $(DEBUG) $(MULHACK) $(FAST) $(LTP_CUT) \
$(WAV49) $(CCINC) -I$(INC)
######### It's $(CC) $(CFLAGS)
LFLAGS = $(PG) $(LDFLAGS) $(LDINC)
LFLAGS = $(LDFLAGS) $(LDINC)
######### It's $(LD) $(LFLAGS)
# Targets
LIBGSM = $(LIB)/libgsm.a
LIBGSMSO= $(LIB)/libgsm.so
TOAST = $(BIN)/toast
UNTOAST = $(BIN)/untoast
@@ -175,7 +163,6 @@ GSM_SOURCES = $(SRC)/add.c \
$(SRC)/code.c \
$(SRC)/debug.c \
$(SRC)/decode.c \
$(SRC)/k6opt.s \
$(SRC)/long_term.c \
$(SRC)/lpc.c \
$(SRC)/preprocess.c \
@@ -220,7 +207,6 @@ GSM_OBJECTS = $(SRC)/add.o \
$(SRC)/code.o \
$(SRC)/debug.o \
$(SRC)/decode.o \
$(SRC)/k6opt.o \
$(SRC)/long_term.o \
$(SRC)/lpc.o \
$(SRC)/preprocess.o \
@@ -293,7 +279,7 @@ TOAST_INSTALL_TARGETS = \
# Target rules
all: $(LIBGSM) $(LIBGSMSO) $(TOAST) $(TCAT) $(UNTOAST)
all: $(LIBGSM) $(TOAST) $(TCAT) $(UNTOAST)
@-echo $(ROOT): Done.
tst: $(TST)/lin2cod $(TST)/cod2lin $(TOAST) $(TST)/test-result
@@ -313,11 +299,6 @@ install: toastinstall gsminstall
# The basic API: libgsm
$(LIBGSMSO): $(LIB) $(GSM_OBJECTS)
$(LD) -o $@.1.0.10 -shared -Xlinker -soname -Xlinker libgsm.so.1 $(GSM_OBJECTS) -lc
ln -fs libgsm.so.1.0.10 lib/libgsm.so.1
ln -fs libgsm.so.1.0.10 lib/libgsm.so
$(LIBGSM): $(LIB) $(GSM_OBJECTS)
-rm $(RMFLAGS) $(LIBGSM)
$(AR) $(ARFLAGS) $(LIBGSM) $(GSM_OBJECTS)
@@ -327,15 +308,15 @@ $(LIBGSM): $(LIB) $(GSM_OBJECTS)
# Toast, Untoast and Tcat -- the compress-like frontends to gsm.
$(TOAST): $(BIN) $(TOAST_OBJECTS) $(LIBGSM)
$(LD) $(LFLAGS) -o $(TOAST) $(TOAST_OBJECTS) $(LIBGSMSO) $(LDLIB)
$(LD) $(LFLAGS) -o $(TOAST) $(TOAST_OBJECTS) $(LIBGSM) $(LDLIB)
$(UNTOAST): $(BIN) $(TOAST)
-rm $(RMFLAGS) $(UNTOAST)
$(LN) toast $(UNTOAST)
$(LN) $(TOAST) $(UNTOAST)
$(TCAT): $(BIN) $(TOAST)
-rm $(RMFLAGS) $(TCAT)
$(LN) toast $(TCAT)
$(LN) $(TOAST) $(TCAT)
# The local bin and lib directories

View File

@@ -98,44 +98,6 @@ extern word gsm_asr P((word a, int n));
# define GSM_L_MULT(a, b) /* word a, word b */ \
(((longword)(a) * (longword)(b)) << 1)
#if defined(__GNUC__) && defined(__i386__)
static __inline__ int GSM_L_ADD(int a, int b)
{
__asm__ __volatile__(
"addl %2,%0; jno 0f; movl $0x7fffffff,%0; adcl $0,%0; 0:"
: "=r" (a)
: "0" (a), "ir" (b)
: "cc"
);
return(a);
}
static __inline__ short GSM_ADD(short a, short b)
{
__asm__ __volatile__(
"addw %2,%0; jno 0f; movw $0x7fff,%0; adcw $0,%0; 0:"
: "=r" (a)
: "0" (a), "ir" (b)
: "cc"
);
return(a);
}
static __inline__ short GSM_SUB(short a, short b)
{
__asm__ __volatile__(
"subw %2,%0; jno 0f; movw $0x7fff,%0; adcw $0,%0; 0:"
: "=r" (a)
: "0" (a), "ir" (b)
: "cc"
);
return(a);
}
#else
# define GSM_L_ADD(a, b) \
( (a) < 0 ? ( (b) >= 0 ? (a) + (b) \
: (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \
@@ -159,8 +121,6 @@ static __inline__ short GSM_SUB(short a, short b)
((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \
? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp)
#endif
# define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a))
/* Use these if necessary:

View File

@@ -1,84 +0,0 @@
/* k6opt.h vector functions optimized for MMX extensions to x86
*
* Copyright (C) 1999 by Stanley J. Brooks <stabro@megsinet.net>
*
* 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;
* not even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE.
*
* Chicago, 03.12.1999
* Stanley J. Brooks
*/
extern void Weighting_filter P2((e, x),
const word * e, /* signal [-5..0.39.44] IN */
word * x /* signal [0..39] OUT */
)
;
extern longword k6maxcc P3((wt,dp,Nc_out),
const word *wt,
const word *dp,
word * Nc_out /* OUT */
)
;
/*
* k6maxmin(p,n,out[])
* input p[n] is array of shorts (require n>0)
* returns (long) maximum absolute value..
* if out!=NULL, also returns out[0] the maximum and out[1] the minimum
*/
extern longword k6maxmin P3((p,n,out),
const word *p,
int n,
word *out /* out[0] is max, out[1] is min */
)
;
extern longword k6iprod P3((p,q,n),
const word *p,
const word *q,
int n
)
;
/*
* k6vsraw(p,n,bits)
* input p[n] is array of shorts (require n>0)
* shift/round each to the right by bits>=0 bits.
*/
extern void k6vsraw P3((p,n,bits),
const word *p,
int n,
int bits
)
;
/*
* k6vsllw(p,n,bits)
* input p[n] is array of shorts (require n>0)
* shift each to the left by bits>=0 bits.
*/
extern void k6vsllw P3((p,n,bits),
const word *p,
int n,
int bits
)
;
#if 1 /* there isn't any significant speed gain from mmx here: */
extern void Short_term_analysis_filteringx P4((u0,rp0,k_n,s),
register word * u0,
register word * rp0, /* [0..7] IN */
register int k_n, /* k_end - k_start */
register word * s /* [0..n-1] IN/OUT */
)
;
/*
#define Short_term_analysis_filtering Short_term_analysis_filteringx
*/
#endif

View File

@@ -1,755 +0,0 @@
/* k6opt.s vector functions optimized for MMX extensions to x86
*
* Copyright (C) 1999 by Stanley J. Brooks <stabro@megsinet.net>
*
* 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;
* not even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE.
*
* Chicago, 03.12.1999
* Stanley J. Brooks
*/
.file "k6opt.s"
.version "01.01"
/* gcc2_compiled.: */
.section .rodata
.align 4
.type coefs,@object
.size coefs,24
coefs:
.value -134
.value -374
.value 0
.value 2054
.value 5741
.value 8192
.value 5741
.value 2054
.value 0
.value -374
.value -134
.value 0
.text
.align 4
/* void Weighting_filter (const short *e, short *x) */
.globl Weighting_filter
.type Weighting_filter,@function
Weighting_filter:
pushl %ebp
movl %esp,%ebp
pushl %edi
pushl %esi
pushl %ebx
movl 12(%ebp),%edi
movl 8(%ebp),%ebx
addl $-10,%ebx
emms
movl $0x1000,%eax; movd %eax,%mm5 /* for rounding */
movq coefs,%mm1
movq coefs+8,%mm2
movq coefs+16,%mm3
xorl %esi,%esi
.p2align 2
.L21:
movq (%ebx,%esi,2),%mm0
pmaddwd %mm1,%mm0
movq 8(%ebx,%esi,2),%mm4
pmaddwd %mm2,%mm4
paddd %mm4,%mm0
movq 16(%ebx,%esi,2),%mm4
pmaddwd %mm3,%mm4
paddd %mm4,%mm0
movq %mm0,%mm4
punpckhdq %mm0,%mm4 /* mm4 has high int32 of mm0 dup'd */
paddd %mm4,%mm0;
paddd %mm5,%mm0 /* add for roundoff */
psrad $13,%mm0
packssdw %mm0,%mm0
movd %mm0,%eax /* ax has result */
movw %ax,(%edi,%esi,2)
incl %esi
cmpl $39,%esi
jle .L21
emms
popl %ebx
popl %esi
popl %edi
leave
ret
.Lfe1:
.size Weighting_filter,.Lfe1-Weighting_filter
.macro ccstep n
.if \n
movq \n(%edi),%mm1
movq \n(%esi),%mm2
.else
movq (%edi),%mm1
movq (%esi),%mm2
.endif
pmaddwd %mm2,%mm1
paddd %mm1,%mm0
.endm
.align 4
/* long k6maxcc(const short *wt, const short *dp, short *Nc_out) */
.globl k6maxcc
.type k6maxcc,@function
k6maxcc:
pushl %ebp
movl %esp,%ebp
pushl %edi
pushl %esi
pushl %ebx
emms
movl 8(%ebp),%edi
movl 12(%ebp),%esi
movl $0,%edx /* will be maximum inner-product */
movl $40,%ebx
movl %ebx,%ecx /* will be index of max inner-product */
subl $80,%esi
.p2align 2
.L41:
movq (%edi),%mm0
movq (%esi),%mm2
pmaddwd %mm2,%mm0
ccstep 8
ccstep 16
ccstep 24
ccstep 32
ccstep 40
ccstep 48
ccstep 56
ccstep 64
ccstep 72
movq %mm0,%mm1
punpckhdq %mm0,%mm1 /* mm1 has high int32 of mm0 dup'd */
paddd %mm1,%mm0;
movd %mm0,%eax /* eax has result */
cmpl %edx,%eax
jle .L40
movl %eax,%edx
movl %ebx,%ecx
.p2align 2
.L40:
subl $2,%esi
incl %ebx
cmpl $120,%ebx
jle .L41
movl 16(%ebp),%eax
movw %cx,(%eax)
movl %edx,%eax
emms
popl %ebx
popl %esi
popl %edi
leave
ret
.Lfe2:
.size k6maxcc,.Lfe2-k6maxcc
.align 4
/* long k6iprod (const short *p, const short *q, int n) */
.globl k6iprod
.type k6iprod,@function
k6iprod:
pushl %ebp
movl %esp,%ebp
pushl %edi
pushl %esi
emms
pxor %mm0,%mm0
movl 8(%ebp),%esi
movl 12(%ebp),%edi
movl 16(%ebp),%eax
leal -32(%esi,%eax,2),%edx /* edx = top - 32 */
cmpl %edx,%esi; ja .L202
.p2align 2
.L201:
ccstep 0
ccstep 8
ccstep 16
ccstep 24
addl $32,%esi
addl $32,%edi
cmpl %edx,%esi; jbe .L201
.p2align 2
.L202:
addl $24,%edx /* now edx = top-8 */
cmpl %edx,%esi; ja .L205
.p2align 2
.L203:
ccstep 0
addl $8,%esi
addl $8,%edi
cmpl %edx,%esi; jbe .L203
.p2align 2
.L205:
addl $4,%edx /* now edx = top-4 */
cmpl %edx,%esi; ja .L207
movd (%edi),%mm1
movd (%esi),%mm2
pmaddwd %mm2,%mm1
paddd %mm1,%mm0
addl $4,%esi
addl $4,%edi
.p2align 2
.L207:
addl $2,%edx /* now edx = top-2 */
cmpl %edx,%esi; ja .L209
movswl (%edi),%eax
movd %eax,%mm1
movswl (%esi),%eax
movd %eax,%mm2
pmaddwd %mm2,%mm1
paddd %mm1,%mm0
.p2align 2
.L209:
movq %mm0,%mm1
punpckhdq %mm0,%mm1 /* mm1 has high int32 of mm0 dup'd */
paddd %mm1,%mm0;
movd %mm0,%eax /* eax has result */
emms
popl %esi
popl %edi
leave
ret
.Lfe3:
.size k6iprod,.Lfe3-k6iprod
.align 4
/* void k6vsraw P3((short *p, int n, int bits) */
.globl k6vsraw
.type k6vsraw,@function
k6vsraw:
pushl %ebp
movl %esp,%ebp
pushl %esi
movl 8(%ebp),%esi
movl 16(%ebp),%ecx
andl %ecx,%ecx; jle .L399
movl 12(%ebp),%eax
leal -16(%esi,%eax,2),%edx /* edx = top - 16 */
emms
movd %ecx,%mm3
movq ones,%mm2
psllw %mm3,%mm2; psrlw $1,%mm2
cmpl %edx,%esi; ja .L306
.p2align 2
.L302: /* 8 words per iteration */
movq (%esi),%mm0
movq 8(%esi),%mm1
paddsw %mm2,%mm0
psraw %mm3,%mm0;
paddsw %mm2,%mm1
psraw %mm3,%mm1;
movq %mm0,(%esi)
movq %mm1,8(%esi)
addl $16,%esi
cmpl %edx,%esi
jbe .L302
.p2align 2
.L306:
addl $12,%edx /* now edx = top-4 */
cmpl %edx,%esi; ja .L310
.p2align 2
.L308: /* do up to 6 words, two at a time */
movd (%esi),%mm0
paddsw %mm2,%mm0
psraw %mm3,%mm0;
movd %mm0,(%esi)
addl $4,%esi
cmpl %edx,%esi
jbe .L308
.p2align 2
.L310:
addl $2,%edx /* now edx = top-2 */
cmpl %edx,%esi; ja .L315
movzwl (%esi),%eax
movd %eax,%mm0
paddsw %mm2,%mm0
psraw %mm3,%mm0;
movd %mm0,%eax
movw %ax,(%esi)
.p2align 2
.L315:
emms
.L399:
popl %esi
leave
ret
.Lfe4:
.size k6vsraw,.Lfe4-k6vsraw
.align 4
/* void k6vsllw P3((short *p, int n, int bits) */
.globl k6vsllw
.type k6vsllw,@function
k6vsllw:
pushl %ebp
movl %esp,%ebp
pushl %esi
movl 8(%ebp),%esi
movl 16(%ebp),%ecx
andl %ecx,%ecx; jle .L499
movl 12(%ebp),%eax
leal -16(%esi,%eax,2),%edx /* edx = top - 16 */
emms
movd %ecx,%mm3
cmpl %edx,%esi; ja .L406
.p2align 2
.L402: /* 8 words per iteration */
movq (%esi),%mm0
movq 8(%esi),%mm1
psllw %mm3,%mm0;
psllw %mm3,%mm1;
movq %mm0,(%esi)
movq %mm1,8(%esi)
addl $16,%esi
cmpl %edx,%esi
jbe .L402
.p2align 2
.L406:
addl $12,%edx /* now edx = top-4 */
cmpl %edx,%esi; ja .L410
.p2align 2
.L408: /* do up to 6 words, two at a time */
movd (%esi),%mm0
psllw %mm3,%mm0;
movd %mm0,(%esi)
addl $4,%esi
cmpl %edx,%esi
jbe .L408
.p2align 2
.L410:
addl $2,%edx /* now edx = top-2 */
cmpl %edx,%esi; ja .L415
movzwl (%esi),%eax
movd %eax,%mm0
psllw %mm3,%mm0;
movd %mm0,%eax
movw %ax,(%esi)
.p2align 2
.L415:
emms
.L499:
popl %esi
leave
ret
.Lfe5:
.size k6vsllw,.Lfe5-k6vsllw
.section .rodata
.align 4
.type extremes,@object
.size extremes,8
extremes:
.long 0x80008000
.long 0x7fff7fff
.type ones,@object
.size ones,8
ones:
.long 0x00010001
.long 0x00010001
.text
.align 4
/* long k6maxmin (const short *p, int n, short *out) */
.globl k6maxmin
.type k6maxmin,@function
k6maxmin:
pushl %ebp
movl %esp,%ebp
pushl %esi
emms
movl 8(%ebp),%esi
movl 12(%ebp),%eax
leal -8(%esi,%eax,2),%edx
cmpl %edx,%esi
jbe .L52
movd extremes,%mm0
movd extremes+4,%mm1
jmp .L58
.p2align 2
.L52:
movq (%esi),%mm0 /* mm0 will be max's */
movq %mm0,%mm1 /* mm1 will be min's */
addl $8,%esi
cmpl %edx,%esi
ja .L56
.p2align 2
.L54:
movq (%esi),%mm2
movq %mm2,%mm3
pcmpgtw %mm0,%mm3 /* mm3 is bitmask for words where mm2 > mm0 */
movq %mm3,%mm4
pand %mm2,%mm3 /* mm3 is mm2 masked to new max's */
pandn %mm0,%mm4 /* mm4 is mm0 masked to its max's */
por %mm3,%mm4
movq %mm4,%mm0 /* now mm0 is updated max's */
movq %mm1,%mm3
pcmpgtw %mm2,%mm3 /* mm3 is bitmask for words where mm2 < mm1 */
pand %mm3,%mm2 /* mm2 is mm2 masked to new min's */
pandn %mm1,%mm3 /* mm3 is mm1 masked to its min's */
por %mm3,%mm2
movq %mm2,%mm1 /* now mm1 is updated min's */
addl $8,%esi
cmpl %edx,%esi
jbe .L54
.p2align 2
.L56: /* merge down the 4-word max/mins to lower 2 words */
movq %mm0,%mm2
psrlq $32,%mm2
movq %mm2,%mm3
pcmpgtw %mm0,%mm3 /* mm3 is bitmask for words where mm2 > mm0 */
pand %mm3,%mm2 /* mm2 is mm2 masked to new max's */
pandn %mm0,%mm3 /* mm3 is mm0 masked to its max's */
por %mm3,%mm2
movq %mm2,%mm0 /* now mm0 is updated max's */
movq %mm1,%mm2
psrlq $32,%mm2
movq %mm1,%mm3
pcmpgtw %mm2,%mm3 /* mm3 is bitmask for words where mm2 < mm1 */
pand %mm3,%mm2 /* mm2 is mm2 masked to new min's */
pandn %mm1,%mm3 /* mm3 is mm1 masked to its min's */
por %mm3,%mm2
movq %mm2,%mm1 /* now mm1 is updated min's */
.p2align 2
.L58:
addl $4,%edx /* now dx = top-4 */
cmpl %edx,%esi
ja .L62
/* here, there are >= 2 words of input remaining */
movd (%esi),%mm2
movq %mm2,%mm3
pcmpgtw %mm0,%mm3 /* mm3 is bitmask for words where mm2 > mm0 */
movq %mm3,%mm4
pand %mm2,%mm3 /* mm3 is mm2 masked to new max's */
pandn %mm0,%mm4 /* mm4 is mm0 masked to its max's */
por %mm3,%mm4
movq %mm4,%mm0 /* now mm0 is updated max's */
movq %mm1,%mm3
pcmpgtw %mm2,%mm3 /* mm3 is bitmask for words where mm2 < mm1 */
pand %mm3,%mm2 /* mm2 is mm2 masked to new min's */
pandn %mm1,%mm3 /* mm3 is mm1 masked to its min's */
por %mm3,%mm2
movq %mm2,%mm1 /* now mm1 is updated min's */
addl $4,%esi
.p2align 2
.L62:
/* merge down the 2-word max/mins to 1 word */
movq %mm0,%mm2
psrlq $16,%mm2
movq %mm2,%mm3
pcmpgtw %mm0,%mm3 /* mm3 is bitmask for words where mm2 > mm0 */
pand %mm3,%mm2 /* mm2 is mm2 masked to new max's */
pandn %mm0,%mm3 /* mm3 is mm0 masked to its max's */
por %mm3,%mm2
movd %mm2,%ecx /* cx is max so far */
movq %mm1,%mm2
psrlq $16,%mm2
movq %mm1,%mm3
pcmpgtw %mm2,%mm3 /* mm3 is bitmask for words where mm2 < mm1 */
pand %mm3,%mm2 /* mm2 is mm2 masked to new min's */
pandn %mm1,%mm3 /* mm3 is mm1 masked to its min's */
por %mm3,%mm2
movd %mm2,%eax /* ax is min so far */
addl $2,%edx /* now dx = top-2 */
cmpl %edx,%esi
ja .L65
/* here, there is one word of input left */
cmpw (%esi),%cx
jge .L64
movw (%esi),%cx
.p2align 2
.L64:
cmpw (%esi),%ax
jle .L65
movw (%esi),%ax
.p2align 2
.L65: /* (finally!) cx is the max, ax the min */
movswl %cx,%ecx
movswl %ax,%eax
movl 16(%ebp),%edx /* ptr to output max,min vals */
andl %edx,%edx; jz .L77
movw %cx,(%edx) /* max */
movw %ax,2(%edx) /* min */
.p2align 2
.L77:
/* now calculate max absolute val */
negl %eax
cmpl %ecx,%eax
jge .L81
movl %ecx,%eax
.p2align 2
.L81:
emms
popl %esi
leave
ret
.Lfe6:
.size k6maxmin,.Lfe6-k6maxmin
/* void Short_term_analysis_filtering (short *u0, const short *rp0, int kn, short *s) */
.equiv pm_u0,8
.equiv pm_rp0,12
.equiv pm_kn,16
.equiv pm_s,20
.equiv lv_u_top,-4
.equiv lv_s_top,-8
.equiv lv_rp,-40 /* local version of rp0 with each word twice */
.align 4
.globl Short_term_analysis_filteringx
.type Short_term_analysis_filteringx,@function
Short_term_analysis_filteringx:
pushl %ebp
movl %esp,%ebp
subl $40,%esp
pushl %edi
pushl %esi
movl pm_rp0(%ebp),%esi;
leal lv_rp(%ebp),%edi;
cld
lodsw; stosw; stosw
lodsw; stosw; stosw
lodsw; stosw; stosw
lodsw; stosw; stosw
lodsw; stosw; stosw
lodsw; stosw; stosw
lodsw; stosw; stosw
lodsw; stosw; stosw
emms
movl $0x4000,%eax;
movd %eax,%mm4;
punpckldq %mm4,%mm4 /* (0x00004000,0x00004000) for rounding dword product pairs */
movl pm_u0(%ebp),%eax
addl $16,%eax
movl %eax,lv_u_top(%ebp) /* UTOP */
movl pm_s(%ebp),%edx /* edx is local s ptr throughout below */
movl pm_kn(%ebp),%eax
leal (%edx,%eax,2),%eax
movl %eax,lv_s_top(%ebp)
cmpl %eax,%edx
jae .L179
.p2align 2
.L181:
leal lv_rp(%ebp),%esi /* RP */
movl pm_u0(%ebp),%edi /* U */
movw (%edx),%ax /* (0,DI) */
roll $16,%eax
movw (%edx),%ax /* (DI,DI) */
.p2align 2
.L185: /* RP is %esi */
movl %eax,%ecx
movw (%edi),%ax /* (DI,U) */
movd (%esi),%mm3 /* mm3 is (0,0,RP,RP) */
movw %cx,(%edi)
movd %eax,%mm2 /* mm2 is (0,0,DI,U) */
rorl $16,%eax
movd %eax,%mm1 /* mm1 is (0,0,U,DI) */
movq %mm1,%mm0
pmullw %mm3,%mm0
pmulhw %mm3,%mm1
punpcklwd %mm1,%mm0 /* mm0 is (RP*U,RP*DI) */
paddd %mm4,%mm0 /* mm4 is 0x00004000,0x00004000 */
psrad $15,%mm0 /* (RP*U,RP*DI) adjusted */
packssdw %mm0,%mm0 /* (*,*,RP*U,RP*DI) adjusted and saturated to word */
paddsw %mm2,%mm0 /* mm0 is (?,?, DI', U') */
movd %mm0,%eax /* (DI,U') */
addl $2,%edi
addl $4,%esi
cmpl lv_u_top(%ebp),%edi
jb .L185
rorl $16,%eax
movw %ax,(%edx) /* last DI goes to *s */
addl $2,%edx /* next s */
cmpl lv_s_top(%ebp),%edx
jb .L181
.p2align 2
.L179:
emms
popl %esi
popl %edi
leave
ret
.Lfe7:
.size Short_term_analysis_filteringx,.Lfe7-Short_term_analysis_filteringx
.end
/* 'as' macro's seem to be case-insensitive */
.macro STEP n
.if \n
movd \n(%esi),%mm3 /* mm3 is (0,0,RP,RP) */
.else
movd (%esi),%mm3 /* mm3 is (0,0,RP,RP) */
.endif
movq %mm5,%mm1;
movd %mm4,%ecx; movw %cx,%ax /* (DI,U) */
psllq $48,%mm1; psrlq $16,%mm4; por %mm1,%mm4
psllq $48,%mm0; psrlq $16,%mm5; por %mm0,%mm5
movd %eax,%mm2 /* mm2 is (0,0,DI,U) */
rorl $16,%eax
movd %eax,%mm1 /* mm1 is (0,0,U,DI) */
movq %mm1,%mm0
pmullw %mm3,%mm0
pmulhw %mm3,%mm1
punpcklwd %mm1,%mm0 /* mm0 is (RP*U,RP*DI) */
paddd %mm6,%mm0 /* mm6 is 0x00004000,0x00004000 */
psrad $15,%mm0 /* (RP*U,RP*DI) adjusted */
packssdw %mm0,%mm0 /* (*,*,RP*U,RP*DI) adjusted and saturated to word */
paddsw %mm2,%mm0 /* mm0 is (?,?, DI', U') */
movd %mm0,%eax /* (DI,U') */
.endm
/* void Short_term_analysis_filtering (short *u0, const short *rp0, int kn, short *s) */
.equiv pm_u0,8
.equiv pm_rp0,12
.equiv pm_kn,16
.equiv pm_s,20
.equiv lv_rp_top,-4
.equiv lv_s_top,-8
.equiv lv_rp,-40 /* local version of rp0 with each word twice */
.align 4
.globl Short_term_analysis_filteringx
.type Short_term_analysis_filteringx,@function
Short_term_analysis_filteringx:
pushl %ebp
movl %esp,%ebp
subl $56,%esp
pushl %edi
pushl %esi
pushl %ebx
movl pm_rp0(%ebp),%esi;
leal lv_rp(%ebp),%edi;
cld
lodsw; stosw; stosw
lodsw; stosw; stosw
lodsw; stosw; stosw
lodsw; stosw; stosw
lodsw; stosw; stosw
lodsw; stosw; stosw
lodsw; stosw; stosw
lodsw; stosw; stosw
movl %edi,lv_rp_top(%ebp)
emms
movl $0x4000,%eax;
movd %eax,%mm6;
punpckldq %mm6,%mm6 /* (0x00004000,0x00004000) for rounding dword product pairs */
movl pm_u0(%ebp),%ebx
movq (%ebx),%mm4; movq 8(%ebx),%mm5 /* the 8 u's */
movl pm_s(%ebp),%edx /* edx is local s ptr throughout below */
movl pm_kn(%ebp),%eax
leal (%edx,%eax,2),%eax
movl %eax,lv_s_top(%ebp)
cmpl %eax,%edx
jae .L179
.p2align 2
.L181:
leal lv_rp(%ebp),%esi /* RP */
movw (%edx),%ax /* (0,DI) */
roll $16,%eax
movw (%edx),%ax /* (DI,DI) */
movd %eax,%mm0
.p2align 2
.L185: /* RP is %esi */
step 0
step 4
step 8
step 12
/*
step 16
step 20
step 24
step 28
*/
addl $16,%esi
cmpl lv_rp_top(%ebp),%esi
jb .L185
rorl $16,%eax
movw %ax,(%edx) /* last DI goes to *s */
addl $2,%edx /* next s */
cmpl lv_s_top(%ebp),%edx
jb .L181
.L179:
movq %mm4,(%ebx); movq %mm5,8(%ebx) /* the 8 u's */
emms
popl %ebx
popl %esi
popl %edi
leave
ret
.Lfe7:
.size Short_term_analysis_filteringx,.Lfe7-Short_term_analysis_filteringx
.ident "GCC: (GNU) 2.95.2 19991109 (Debian GNU/Linux)"

View File

@@ -13,9 +13,7 @@
#include "gsm.h"
#include "proto.h"
#ifdef K6OPT
#include "k6opt.h"
#endif
/*
* 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION
*/
@@ -199,9 +197,6 @@ static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
/* Search for the maximum cross-correlation and coding of the LTP lag
*/
# ifdef K6OPT
L_max = k6maxcc(wt,dp,&Nc);
# else
L_max = 0;
Nc = 40; /* index for the maximum cross-correlation */
@@ -239,7 +234,7 @@ static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
L_max = L_result;
}
}
# endif
*Nc_out = Nc;
L_max <<= 1;

View File

@@ -14,10 +14,6 @@
#include "gsm.h"
#include "proto.h"
#ifdef K6OPT
#include "k6opt.h"
#endif
#undef P
/*
@@ -48,19 +44,12 @@ static void Autocorrelation P2((s, L_ACF),
/* Search for the maximum.
*/
#ifndef K6OPT
smax = 0;
for (k = 0; k <= 159; k++) {
temp = GSM_ABS( s[k] );
if (temp > smax) smax = temp;
}
#else
{
longword lmax;
lmax = k6maxmin(s,160,NULL);
smax = (lmax > MAX_WORD) ? MAX_WORD : lmax;
}
#endif
/* Computation of the scaling factor.
*/
if (smax == 0) scalauto = 0;
@@ -73,7 +62,6 @@ static void Autocorrelation P2((s, L_ACF),
*/
if (scalauto > 0) {
# ifndef K6OPT
# ifdef USE_FLOAT_MUL
# define SCALE(n) \
@@ -95,10 +83,6 @@ static void Autocorrelation P2((s, L_ACF),
SCALE(4)
}
# undef SCALE
# else /* K6OPT */
k6vsraw(s,160,scalauto);
# endif
}
# ifdef USE_FLOAT_MUL
else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k];
@@ -106,7 +90,6 @@ static void Autocorrelation P2((s, L_ACF),
/* Compute the L_ACF[..].
*/
#ifndef K6OPT
{
# ifdef USE_FLOAT_MUL
register float * sp = float_s;
@@ -153,24 +136,11 @@ static void Autocorrelation P2((s, L_ACF),
for (k = 9; k--; L_ACF[k] <<= 1) ;
}
#else
{
int k;
for (k=0; k<9; k++) {
L_ACF[k] = 2*k6iprod(s,s+k,160-k);
}
}
#endif
/* Rescaling of the array s[0..159]
*/
if (scalauto > 0) {
assert(scalauto <= 4);
#ifndef K6OPT
for (k = 160; k--; *s++ <<= scalauto) ;
# else /* K6OPT */
k6vsllw(s,160,scalauto);
# endif
}
}

View File

@@ -42,8 +42,11 @@ void Gsm_Preprocess P3((S, s, so),
word mp = S->mp;
word s1;
longword L_s2;
longword L_temp;
word msp, lsp;
word SO;
longword ltmp; /* for ADD */
@@ -55,8 +58,7 @@ void Gsm_Preprocess P3((S, s, so),
/* 4.2.1 Downscaling of the input signal
*/
/* SO = SASR( *s, 3 ) << 2;*/
SO = SASR( *s, 1 ) & ~3;
SO = SASR( *s, 3 ) << 2;
s++;
assert (SO >= -0x4000); /* downscaled by */
@@ -78,38 +80,21 @@ void Gsm_Preprocess P3((S, s, so),
assert(s1 != MIN_WORD);
/* SJB Remark: float might be faster than the mess that follows */
/* Compute the recursive part
*/
L_s2 = s1;
L_s2 <<= 15;
/* Execution of a 31 bv 16 bits multiplication
*/
{
word msp, lsp;
longword L_s2;
longword L_temp;
L_s2 = s1;
L_s2 <<= 15;
#ifndef __GNUC__
msp = SASR( L_z2, 15 );
lsp = L_z2 & 0x7fff; /* gsm_L_sub(L_z2,(msp<<15)); */
lsp = L_z2-((longword)msp<<15); /* gsm_L_sub(L_z2,(msp<<15)); */
L_s2 += GSM_MULT_R( lsp, 32735 );
L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/
L_z2 = GSM_L_ADD( L_temp, L_s2 );
/* above does L_z2 = L_z2 * 0x7fd5/0x8000 + L_s2 */
#else
L_z2 = ((long long)L_z2*32735 + 0x4000)>>15;
/* alternate (ansi) version of above line does slightly different rounding:
* L_temp = L_z2 >> 9;
* L_temp += L_temp >> 5;
* L_temp = (++L_temp) >> 1;
* L_z2 = L_z2 - L_temp;
*/
L_z2 = GSM_L_ADD(L_z2,L_s2);
#endif
/* Compute sof[k] with rounding
*/
L_temp = GSM_L_ADD( L_z2, 16384 );
@@ -120,7 +105,6 @@ void Gsm_Preprocess P3((S, s, so),
msp = GSM_MULT_R( mp, -28180 );
mp = SASR( L_temp, 15 );
*so++ = GSM_ADD( mp, msp );
}
}
S->z1 = z1;

View File

@@ -18,9 +18,7 @@
*/
/* 4.2.13 */
#ifdef K6OPT
#include "k6opt.h"
#else
static void Weighting_filter P2((e, x),
register word * e, /* signal [-5..0.39.44] IN */
word * x /* signal [0..39] OUT */
@@ -112,7 +110,6 @@ static void Weighting_filter P2((e, x),
: (L_result > MAX_WORD ? MAX_WORD : L_result ));
}
}
#endif /* K6OPT */
/* 4.2.14 */

View File

@@ -13,12 +13,7 @@
#include "gsm.h"
#include "proto.h"
#ifdef K6OPT
#include "k6opt.h"
#define Short_term_analysis_filtering Short_term_analysis_filteringx
#endif
/*
* SHORT TERM ANALYSIS FILTERING SECTION
*/
@@ -185,16 +180,9 @@ static void LARp_to_rp P1((LARp),
/* 4.2.10 */
#ifndef Short_term_analysis_filtering
/* SJB Remark:
* I tried 2 MMX versions of this function, neither is significantly
* faster than the C version which follows. MMX might be useful if
* one were processing 2 input streams in parallel.
*/
static void Short_term_analysis_filtering P4((u0,rp0,k_n,s),
register word * u0,
register word * rp0, /* [0..7] IN */
static void Short_term_analysis_filtering P4((S,rp,k_n,s),
struct gsm_state * S,
register word * rp, /* [0..7] IN */
register int k_n, /* k_end - k_start */
register word * s /* [0..n-1] IN/OUT */
)
@@ -206,45 +194,45 @@ static void Short_term_analysis_filtering P4((u0,rp0,k_n,s),
* coefficient), it is assumed that the computation begins with index
* k_start (for arrays d[..] and s[..]) and stops with index k_end
* (k_start and k_end are defined in 4.2.9.1). This procedure also
* needs to keep the array u0[0..7] in memory for each call.
* needs to keep the array u[0..7] in memory for each call.
*/
{
register word * u_top = u0 + 8;
register word * s_top = s + k_n;
register word * u = S->u;
register int i;
register word di, zzz, ui, sav, rpi;
register longword ltmp;
while (s < s_top) {
register word *u, *rp ;
register longword di, u_out;
di = u_out = *s;
for (rp=rp0, u=u0; u<u_top;) {
register longword ui, rpi;
ui = *u;
*u++ = u_out;
rpi = *rp++;
u_out = ui + (((rpi*di)+0x4000)>>15);
di = di + (((rpi*ui)+0x4000)>>15);
/* make the common case fastest: */
if ((u_out == (word)u_out) && (di == (word)di)) continue;
/* otherwise do slower fixup (saturation) */
if (u_out>MAX_WORD) u_out=MAX_WORD;
else if (u_out<MIN_WORD) u_out=MIN_WORD;
if (di>MAX_WORD) di=MAX_WORD;
else if (di<MIN_WORD) di=MIN_WORD;
for (; k_n--; s++) {
di = sav = *s;
for (i = 0; i < 8; i++) { /* YYY */
ui = u[i];
rpi = rp[i];
u[i] = sav;
zzz = GSM_MULT_R(rpi, di);
sav = GSM_ADD( ui, zzz);
zzz = GSM_MULT_R(rpi, ui);
di = GSM_ADD( di, zzz );
}
*s++ = di;
*s = di;
}
}
#endif
#if defined(USE_FLOAT_MUL) && defined(FAST)
static void Fast_Short_term_analysis_filtering P4((u,rp,k_n,s),
register word * u;
static void Fast_Short_term_analysis_filtering P4((S,rp,k_n,s),
struct gsm_state * S,
register word * rp, /* [0..7] IN */
register int k_n, /* k_end - k_start */
register word * s /* [0..n-1] IN/OUT */
)
{
register word * u = S->u;
register int i;
float uf[8],
@@ -274,15 +262,6 @@ static void Fast_Short_term_analysis_filtering P4((u,rp,k_n,s),
}
#endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */
/*
* SJB Remark: modified Short_term_synthesis_filtering() below
* for significant (abt 35%) speedup of decompression.
* (gcc-2.95, k6 cpu)
* Please don't change this without benchmarking decompression
* to see that you haven't harmed speed.
* This function burns most of CPU time for untoasting.
* Unfortunately, didn't see any good way to benefit from mmx.
*/
static void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),
struct gsm_state * S,
register word * rrp, /* [0..7] IN */
@@ -293,34 +272,32 @@ static void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),
{
register word * v = S->v;
register int i;
register longword sri;
register word sri, tmp1, tmp2;
register longword ltmp; /* for GSM_ADD & GSM_SUB */
while (k--) {
sri = *wt++;
for (i = 8; i--;) {
register longword tmp1, tmp2;
/* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) );
*/
tmp1 = rrp[i];
tmp2 = v[i];
tmp2 = ( tmp1 == MIN_WORD && tmp2 == MIN_WORD
? MAX_WORD
: 0x0FFFF & (( (longword)tmp1 * (longword)tmp2
+ 16384) >> 15)) ;
sri = GSM_SUB( sri, tmp2 );
tmp2 = (( tmp1 * tmp2 + 16384) >> 15) ;
/* saturation done below */
sri -= tmp2;
if (sri != (word)sri) {
sri = (sri<0)? MIN_WORD:MAX_WORD;
}
/* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) );
*/
tmp1 = ( tmp1 == MIN_WORD && sri == MIN_WORD
? MAX_WORD
: 0x0FFFF & (( (longword)tmp1 * (longword)sri
+ 16384) >> 15)) ;
tmp1 = (( tmp1 * sri + 16384) >> 15) ;
/* saturation done below */
tmp1 += v[i];
if (tmp1 != (word)tmp1) {
tmp1 = (tmp1<0)? MIN_WORD:MAX_WORD;
}
v[i+1] = tmp1;
v[i+1] = GSM_ADD( v[i], tmp1);
}
*sr++ = v[0] = sri;
}
@@ -378,7 +355,7 @@ void Gsm_Short_Term_Analysis_Filter P3((S,LARc,s),
word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ];
word LARp[8];
int i;
#undef FILTER
#if defined(FAST) && defined(USE_FLOAT_MUL)
# define FILTER (* (S->fast \
@@ -393,20 +370,19 @@ int i;
Coefficients_0_12( LARpp_j_1, LARpp_j, LARp );
LARp_to_rp( LARp );
FILTER( S->u, LARp, 13, s);
FILTER( S, LARp, 13, s);
Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
LARp_to_rp( LARp );
FILTER( S->u, LARp, 14, s + 13);
FILTER( S, LARp, 14, s + 13);
Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
LARp_to_rp( LARp );
FILTER( S->u, LARp, 13, s + 27);
FILTER( S, LARp, 13, s + 27);
Coefficients_40_159( LARpp_j, LARp);
LARp_to_rp( LARp );
FILTER( S->u, LARp, 120, s + 40);
FILTER( S, LARp, 120, s + 40);
}
void Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s),

View File

@@ -22,7 +22,7 @@ LIB_TARGET_DIR = .
#
WARNINGS = -Wall -Wno-comment -Wno-error
CFLAGS = -O6 -mpentium -I$(LIB_TARGET_DIR) $(WARNINGS)
CFLAGS = -O3 -I$(LIB_TARGET_DIR) $(WARNINGS)
LIB = $(LIB_TARGET_DIR)/liblpc10.a

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -79,8 +79,8 @@ static integer c__1 = 1;
/* ANALYS Version 55 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -246,8 +246,8 @@ static integer c__1 = 1;
real phi[100] /* was [10][10] */, psi[10];
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -277,8 +277,8 @@ static integer c__1 = 1;
/* Frame size, Prediction order, Pitch period */
/* Arguments to ANALYS */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -48,8 +48,8 @@ extern struct {
/* BSYNZ Version 54 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -144,8 +144,8 @@ extern struct {
real lpi0, hpi0;
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -175,8 +175,8 @@ extern struct {
/* Frame size, Prediction order, Pitch period */
/* Arguments */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -35,8 +35,8 @@ extern int chanrd_(integer *order, integer *ipitv, integer *irms, integer *irc,
/* CHANL Version 49 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int dcbias_(integer *len, real *speech, real *sigout);
/* DCBIAS Version 50 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -53,8 +53,8 @@ static integer c__2 = 2;
/* DECODE Version 54 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -188,8 +188,8 @@ static integer c__2 = 2;
integer ishift, errcnt, lsb;
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -219,8 +219,8 @@ static integer c__2 = 2;
/* Frame size, Prediction order, Pitch period */
/* Arguments */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -37,8 +37,8 @@ extern int deemp_(real *x, integer *n, struct lpc10_decoder_state *st);
/* DEEMP Version 48 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int difmag_(real *speech, integer *lpita, integer *tau, integer *ltau, in
/* DIFMAG Version 49 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -47,8 +47,8 @@ extern struct {
/* DYPTRK Version 52 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -136,8 +136,8 @@ extern struct {
/* Arguments */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -43,8 +43,8 @@ static integer c__2 = 2;
/* ENCODE Version 54 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -128,8 +128,8 @@ static integer c__2 = 2;
integer idel, nbit, i__, j, i2, i3, mrk;
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -151,8 +151,8 @@ static integer c__2 = 2;
/* Frame size, Prediction order, Pitch period */
/* Arguments */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int energy_(integer *len, real *speech, real *rms);
/* ENERGY Version 50 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int ham84_(integer *input, integer *output, integer *errcnt);
/* HAM84 Version 45G */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -39,8 +39,8 @@ extern int inithp100_(void);
/* HP100 Version 55 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int invert_(integer *order, real *phi, real *psi, real *rc);
/* INVERT Version 45G */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -91,8 +91,8 @@ extern int invert_(integer *order, real *phi, real *psi, real *rc);
/* Arguments */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int irc2pc_(real *rc, real *pc, integer *order, real *gprime, real *g2pas
/* IRC2PC Version 48 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -82,8 +82,8 @@ extern int irc2pc_(real *rc, real *pc, integer *order, real *gprime, real *g2pas
/* Arguments */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int ivfilt_(real *lpbuf, real *ivbuf, integer *len, integer *nsamp, real
/* IVFILT Version 48 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 00:20:06 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 00:20:06 markster
Version 0.1.4 from FTP
Revision 1.1 2000/01/05 00:20:06 markster
Add broken lpc10 code... It's not too far from working I don't think...

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -58,8 +58,8 @@ static integer c__10 = 10;
/* ***************************************************************** */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -113,8 +113,8 @@ static integer c__10 = 10;
real rms;
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -147,8 +147,8 @@ static integer c__10 = 10;
/* Frame size, Prediction order, Pitch period */
/* Arguments */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -50,8 +50,8 @@ static integer c__10 = 10;
/* ***************************************************************** */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -109,8 +109,8 @@ static integer c__10 = 10;
/* Arguments */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -45,8 +45,8 @@ struct {
/* ***************************************************************** */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -71,8 +71,8 @@ struct {
{
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -97,8 +97,8 @@ struct {
/* LPC Configuration parameters: */
/* Frame size, Prediction order, Pitch period */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int lpfilt_(real *inbuf, real *lpbuf, integer *len, integer *nsamp);
/* LPFILT Version 55 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern integer median_(integer *d1, integer *d2, integer *d3);
/* MEDIAN Version 45G */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int mload_(integer *order, integer *awins, integer *awinf, real *speech,
/* MLOAD Version 48 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -41,8 +41,8 @@ static real c_b2 = 1.f;
/* ONSET Version 49 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -143,8 +143,8 @@ static real c_b2 = 1.f;
/* Arguments */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -37,8 +37,8 @@ extern int pitsyn_(integer *order, integer *voice, integer *pitch, real *rms, re
/* PITSYN Version 53 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -143,8 +143,8 @@ extern int pitsyn_(integer *order, integer *voice, integer *pitch, real *rms, re
/* Arguments */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,11 +1,8 @@
/*
$Log$
Revision 1.7 2001/04/12 21:27:53 markster
Version 0.1.8 from FTP
Revision 1.3 2001/04/12 21:27:53 markh
app_record now supports wildcards of sort so your output file is not overwritten every time it's run. File.h got a documentation update on the ast_fileexists to include the return call. Watch out for the placea.c placev.c code, it's updates have not been tested yet. Just a few parenthesis to make it compile nicer on newer gcc versions with all the -W flags set.
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -32,12 +29,9 @@ extern int placea_(integer *ipitch, integer *voibuf, integer *obound, integer *a
/* PLACEA Version 48 */
/* $Log$
* Revision 1.7 2001/04/12 21:27:53 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.3 2001/04/12 21:27:53 markh
/* app_record now supports wildcards of sort so your output file is not overwritten every time it's run. File.h got a documentation update on the ast_fileexists to include the return call. Watch out for the placea.c placev.c code, it's updates have not been tested yet. Just a few parenthesis to make it compile nicer on newer gcc versions with all the -W flags set.
/*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
/*
@@ -146,18 +140,18 @@ extern int placea_(integer *ipitch, integer *voibuf, integer *obound, integer *a
/* is not altered from MAXWIN, since this would defeat the purpose */
/* of phase-synchronous placement. */
/* Check for case 1 and case 2 */
allv = voibuf[((*af - 2) << 1) + 2] == 1;
allv = allv && voibuf[((*af - 1) << 1) + 1] == 1;
allv = allv && voibuf[((*af - 1) << 1) + 2] == 1;
allv = voibuf[(*af - 2 << 1) + 2] == 1;
allv = allv && voibuf[(*af - 1 << 1) + 1] == 1;
allv = allv && voibuf[(*af - 1 << 1) + 2] == 1;
allv = allv && voibuf[(*af << 1) + 1] == 1;
allv = allv && voibuf[(*af << 1) + 2] == 1;
winv = voibuf[(*af << 1) + 1] == 1 || voibuf[(*af << 1) + 2] == 1;
if (allv || winv && *obound == 0) {
/* APHASE: Phase synchronous window placement. */
/* Get minimum lower index of the window. */
i__ = (lrange + *ipitch - 1 - awin[((*af - 1) << 1) + 1]) / *ipitch;
i__ = (lrange + *ipitch - 1 - awin[(*af - 1 << 1) + 1]) / *ipitch;
i__ *= *ipitch;
i__ += awin[((*af - 1) << 1) + 1];
i__ += awin[(*af - 1 << 1) + 1];
/* L = the actual length of this frame's analysis window. */
l = *maxwin;
/* Calculate the location where a perfectly centered window would star

View File

@@ -1,11 +1,8 @@
/*
$Log$
Revision 1.7 2001/04/12 21:27:53 markster
Version 0.1.8 from FTP
Revision 1.3 2001/04/12 21:27:53 markh
app_record now supports wildcards of sort so your output file is not overwritten every time it's run. File.h got a documentation update on the ast_fileexists to include the return call. Watch out for the placea.c placev.c code, it's updates have not been tested yet. Just a few parenthesis to make it compile nicer on newer gcc versions with all the -W flags set.
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -32,12 +29,9 @@ extern int placev_(integer *osbuf, integer *osptr, integer *oslen, integer *obou
/* PLACEV Version 48 */
/* $Log$
* Revision 1.7 2001/04/12 21:27:53 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.3 2001/04/12 21:27:53 markh
/* app_record now supports wildcards of sort so your output file is not overwritten every time it's run. File.h got a documentation update on the ast_fileexists to include the return call. Watch out for the placea.c placev.c code, it's updates have not been tested yet. Just a few parenthesis to make it compile nicer on newer gcc versions with all the -W flags set.
/*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
/*
@@ -187,7 +181,7 @@ t*/
/* Function Body */
/* Computing MAX */
i__1 = vwin[((*af - 1) << 1) + 2] + 1, i__2 = (*af - 2) * *lframe + 1;
i__1 = vwin[(*af - 1 << 1) + 2] + 1, i__2 = (*af - 2) * *lframe + 1;
lrange = max(i__1,i__2);
hrange = *af * *lframe;
/* Compute OSPTR1, so the following code only looks at relevant onsets. */
@@ -201,7 +195,7 @@ L90:
/* Check for case 1 first (fast case): */
if (osptr1 <= 1 || osbuf[osptr1 - 1] < lrange) {
/* Computing MAX */
i__1 = vwin[((*af - 1) << 1) + 2] + 1;
i__1 = vwin[(*af - 1 << 1) + 2] + 1;
vwin[(*af << 1) + 1] = max(i__1,*dvwinl);
vwin[(*af << 1) + 2] = vwin[(*af << 1) + 1] + *maxwin - 1;
*obound = 0;

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int preemp_(real *inbuf, real *pebuf, integer *nsamp, real *coef, real *z
/* PREEMP Version 55 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -44,8 +44,8 @@ static integer c__1 = 1;
/* PREPRO Version 48 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -37,8 +37,8 @@ extern integer random_(struct lpc10_decoder_state *st);
/* RANDOM Version 49 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -29,8 +29,8 @@ extern int rcchk_(integer *order, real *rc1f, real *rc2f);
/* RCCHK Version 45G */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:39 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:39 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:39 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -58,8 +58,8 @@ static real c_b2 = .7f;
/* SYNTHS Version 54 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -178,8 +178,8 @@ static real c_b2 = .7f;
real rci[160] /* was [10][16] */;
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -209,8 +209,8 @@ static real c_b2 = .7f;
/* Frame size, Prediction order, Pitch period */
/* Arguments */
/* $Log$
* Revision 1.7 2000/01/05 08:20:39 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:39 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:39 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:40 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:40 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:40 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -30,8 +30,8 @@ extern int tbdm_(real *speech, integer *lpita, integer *tau, integer *ltau, real
/* TBDM Version 49 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:40 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:40 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:40 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:40 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:40 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:40 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -48,8 +48,8 @@ extern struct {
/* VOICIN Version 52 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:40 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:40 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:40 markster
/* Some OSS fixes and a few lpc changes to make it actually work
@@ -290,8 +290,8 @@ s*/
/* Global Variables: */
/* Arguments */
/* $Log$
* Revision 1.7 2000/01/05 08:20:40 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:40 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:40 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -1,8 +1,8 @@
/*
$Log$
Revision 1.7 2000/01/05 08:20:40 markster
Version 0.1.8 from FTP
Revision 1.3 2000/01/05 08:20:40 markster
Version 0.1.4 from FTP
Revision 1.2 2000/01/05 08:20:40 markster
Some OSS fixes and a few lpc changes to make it actually work
@@ -33,8 +33,8 @@ static real c_b2 = 1.f;
/* VPARMS Version 50 */
/* $Log$
* Revision 1.7 2000/01/05 08:20:40 markster
* Version 0.1.8 from FTP
* Revision 1.3 2000/01/05 08:20:40 markster
* Version 0.1.4 from FTP
*
/* Revision 1.2 2000/01/05 08:20:40 markster
/* Some OSS fixes and a few lpc changes to make it actually work

View File

@@ -44,7 +44,7 @@ mod 11/15/95 for Layer I
#pragma warning(disable:4056)
#endif
#include <string.h>
/* Read Only */
static long steps[18] =

View File

@@ -98,7 +98,6 @@ IN_OUT structure returns:
#include <stdlib.h>
#include <stdio.h>
#include <float.h>
#include <string.h>
#include <math.h>
#include "L3.h"
#include "mhead.h" /* mpeg header structure */

View File

@@ -35,7 +35,6 @@ mods 1/8/97 warnings
=========================================================*/
#include <limits.h>
#include <string.h>
/* Read only */
static long steps[18] =

View File

@@ -1,25 +0,0 @@
/*
* slin_adpcm_ex.h --
*
* Signed 16-bit audio data, 10 milliseconds worth at 8 kHz.
*
* Source: g723.example
*
* Copyright (C) 2001, Linux Support Services, Inc.
*
* Distributed under the terms of the GNU General Public License
*
*/
static signed short slin_adpcm_ex[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};

View File

@@ -1,25 +0,0 @@
/*
* slin_ulaw_ex.h --
*
* Signed 16-bit audio data, 10 milliseconds worth at 8 kHz.
*
* Source: g723.example
*
* Copyright (C) 2001, Linux Support Services, Inc.
*
* Distributed under the terms of the GNU General Public License
*
*/
static signed short slin_ulaw_ex[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};

View File

@@ -1,25 +0,0 @@
/*
* ulaw_slin_ex.h --
*
* 4-bit ADPCM data, 20 milliseconds worth at 8 kHz.
*
* Source: g723.example
*
* Copyright (C) 2001, Linux Support Services, Inc.
*
* Distributed under the terms of the GNU General Public License
*
*/
static unsigned char ulaw_slin_ex[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

View File

@@ -1,9 +0,0 @@
{ { 1.8229206611e-04,-7.8997325866e-01,2.2401819940e+00,-4.6751353581e+00,5.5080745712e+00,-5.0571565772e+00,2.6215820004e+00,0.0000000000e+00,
}, { 9.8532175289e-02,-5.6297236492e-02,3.3146713415e-01,-9.2239200436e-01,1.4844365184e+00,-2.0183258642e+00,2.0074154497e+00,0.0000000000e+00,
}, }, { { 1.8229206610e-04,-7.8997325866e-01,7.7191410839e-01,-2.8075643964e+00,1.6948618347e+00,-3.0367273700e+00,9.0333559408e-01,0.0000000000e+00,
}, { 9.8531161839e-02,-5.6297236492e-02,1.1421579050e-01,-4.8122536483e-01,4.0121072432e-01,-7.4834487567e-01,6.9170822332e-01,0.0000000000e+00,
}, }, { { 1.8229206611e-04,-7.8997325866e-01,2.9003821430e+00,-6.1082779024e+00,7.7169345751e+00,-6.6075999680e+00,3.3941838836e+00,0.0000000000e+00,
}, { 9.8539686961e-02,-5.6297236492e-02,4.2915323820e-01,-1.2609358633e+00,2.2399213250e+00,-2.9928879142e+00,2.5990173742e+00,0.0000000000e+00,
}, }, { { 1.8229206610e-04,-7.8997325866e-01,-7.7191410839e-01,-2.8075643964e+00,-1.6948618347e+00,-3.0367273700e+00,-9.0333559408e-01,0.0000000000e+00,
}, { 9.8531161839e-02,-5.6297236492e-02,-1.1421579050e-01,-4.8122536483e-01,-4.0121072432e-01,-7.4834487567e-01,-6.9170822332e-01,0.0000000000e+00,
}, },

View File

@@ -1,4 +0,0 @@
{ 1.3868644653e-08,-6.3283665042e-01,4.0895057217e+00,-1.1020074592e+01,1.5850766191e+01,-1.2835109292e+01,5.5477477340e+00,0.0000000000e+00,
}, { 3.1262119724e-03,-7.8390522307e-03,8.5209627801e-02,-4.0804129163e-01,1.1157139955e+00,-1.8767603680e+00,1.8916395224e+00,0.0000000000e+00
},

View File

@@ -51,9 +51,6 @@ void ast_destroy(struct ast_config *ast)
struct ast_category *cat, *catn;
struct ast_variable *v, *vn;
if (!ast)
return;
cat = ast->root;
while(cat) {
v = cat->root;
@@ -123,21 +120,6 @@ char *ast_variable_retrieve(struct ast_config *config, char *category, char *val
return NULL;
}
int ast_category_exist(struct ast_config *config, char *category_name)
{
struct ast_category *category = NULL;
category = config->root;
while(category) {
if (!strcasecmp(category->name,category_name))
return 1;
category = category->next;
}
return 0;
}
struct ast_config *ast_load(char *configfile)
{
char fn[256];
@@ -148,7 +130,6 @@ struct ast_config *ast_load(char *configfile)
FILE *f;
char *c, *cur;
int lineno=0;
if (configfile[0] == '/') {
strncpy(fn, configfile, sizeof(fn));
} else {
@@ -183,23 +164,10 @@ struct ast_config *ast_load(char *configfile)
/* Actually parse the entry */
if (cur[0] == '[') {
/* A category header */
/* XXX Don't let them use the same category twice XXX */
c = strchr(cur, ']');
if (c) {
*c = 0;
/*
* Check category duplicity before structure
* allocation
*/
if (ast_category_exist(tmp,cur+1)) {
ast_destroy(tmp);
ast_log(LOG_WARNING,
"Found duplicit category [%s] in "
"file %s line %d\n",
cur+1,configfile,lineno);
fclose(f);
return NULL;
}
tmpc = malloc(sizeof(struct ast_category));
if (!tmpc) {
ast_destroy(tmp);
@@ -233,15 +201,11 @@ struct ast_config *ast_load(char *configfile)
if (c) {
*c = 0;
c++;
/* Ignore > in => */
if (*c== '>')
c++;
v = malloc(sizeof(struct ast_variable));
if (v) {
v->next = NULL;
v->name = strdup(strip(cur));
v->value = strdup(strip(c));
v->lineno = lineno;
if (last)
last->next = v;
else

Some files were not shown because too many files have changed in this diff Show More