aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_oss.c
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2008-01-03 19:56:29 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2008-01-03 19:56:29 +0000
commita7ebd360e357e8dd68b0a1d0e5e2f7a9913d88c2 (patch)
treed04b833784432fde7d7b531f3fa46f3a593998fa /channels/chan_oss.c
parent22177a5c6b4e9f4ced5659e9839c04c1a3063cb9 (diff)
eliminiate sound_thread() and other stuff from chan_oss since Asterisk indications can handle it
remove gentone and all the headers containing tones that are no longer needed git-svn-id: http://svn.digium.com/svn/asterisk/trunk@96270 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_oss.c')
-rw-r--r--channels/chan_oss.c249
1 files changed, 14 insertions, 235 deletions
diff --git a/channels/chan_oss.c b/channels/chan_oss.c
index cabb734b2..9bf749459 100644
--- a/channels/chan_oss.c
+++ b/channels/chan_oss.c
@@ -65,12 +65,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "console_video.h"
-/* ringtones we use */
-#include "busy.h"
-#include "ringtone.h"
-#include "ring10.h"
-#include "answer.h"
-
/*! Global jitterbuffer configuration - by default, jb is disabled */
static struct ast_jb_conf default_jbconf =
{
@@ -247,30 +241,6 @@ static char *config = "oss.conf"; /* default config file */
static int oss_debug;
/*!
- * Each sound is made of 'datalen' samples of sound, repeated as needed to
- * generate 'samplen' samples of data, then followed by 'silencelen' samples
- * of silence. The loop is repeated if 'repeat' is set.
- */
-struct sound {
- int ind;
- char *desc;
- short *data;
- int datalen;
- int samplen;
- int silencelen;
- int repeat;
-};
-
-static struct sound sounds[] = {
- { AST_CONTROL_RINGING, "RINGING", ringtone, sizeof(ringtone)/2, 16000, 32000, 1 },
- { AST_CONTROL_BUSY, "BUSY", busy, sizeof(busy)/2, 4000, 4000, 1 },
- { AST_CONTROL_CONGESTION, "CONGESTION", busy, sizeof(busy)/2, 2000, 2000, 1 },
- { AST_CONTROL_RING, "RING10", ring10, sizeof(ring10)/2, 16000, 32000, 1 },
- { AST_CONTROL_ANSWER, "ANSWER", answer, sizeof(answer)/2, 2200, 0, 0 },
- { -1, NULL, 0, 0, 0, 0 }, /* end marker */
-};
-
-/*!
* \brief descriptor for one of our channels.
*
* There is one used for 'default' values (from the [general] entry in
@@ -282,18 +252,6 @@ struct chan_oss_pvt {
struct chan_oss_pvt *next;
char *name;
- /*!
- * cursound indicates which in struct sound we play. -1 means nothing,
- * any other value is a valid sound, in which case sampsent indicates
- * the next sample to send in [0..samplen + silencelen]
- * nosound is set to disable the audio data from the channel
- * (so we can play the tones etc.).
- */
- int sndcmd[2]; /*!< Sound command pipe */
- int cursound; /*!< index of sound to send */
- int sampsent; /*!< # of sound samples sent */
- int nosound; /*!< set to block audio from the PBX */
-
int total_blocks; /*!< total blocks in the output device */
int sounddev;
enum { M_UNSET, M_FULL, M_READ, M_WRITE } duplex;
@@ -356,7 +314,6 @@ struct video_desc *get_video_desc(struct ast_channel *c)
return o ? o->env : NULL;
}
static struct chan_oss_pvt oss_default = {
- .cursound = -1,
.sounddev = -1,
.duplex = M_UNSET, /* XXX check this */
.autoanswer = 1,
@@ -511,135 +468,6 @@ static int soundcard_writeframe(struct chan_oss_pvt *o, short *data)
}
/*!
- * \brief Handler for 'sound writable' events from the sound thread.
- *
- * Builds a frame from the high level description of the sounds,
- * and passes it to the audio device.
- * The actual sound is made of 1 or more sequences of sound samples
- * (s->datalen, repeated to make s->samplen samples) followed by
- * s->silencelen samples of silence. The position in the sequence is stored
- * in o->sampsent, which goes between 0 .. s->samplen+s->silencelen.
- * In case we fail to write a frame, don't update o->sampsent.
- */
-static void send_sound(struct chan_oss_pvt *o)
-{
- short myframe[FRAME_SIZE];
- int ofs, l, start;
- int l_sampsent = o->sampsent;
- struct sound *s;
-
- if (o->cursound < 0) /* no sound to send */
- return;
-
- s = &sounds[o->cursound];
-
- for (ofs = 0; ofs < FRAME_SIZE; ofs += l) {
- l = s->samplen - l_sampsent; /* # of available samples */
- if (l > 0) {
- start = l_sampsent % s->datalen; /* source offset */
- l = MIN(l, FRAME_SIZE - ofs); /* don't overflow the frame */
- l = MIN(l, s->datalen - start); /* don't overflow the source */
- bcopy(s->data + start, myframe + ofs, l * 2);
- if (0)
- ast_log(LOG_WARNING, "send_sound sound %d/%d of %d into %d\n", l_sampsent, l, s->samplen, ofs);
- l_sampsent += l;
- } else { /* end of samples, maybe some silence */
- static const short silence[FRAME_SIZE] = { 0, };
-
- l += s->silencelen;
- if (l > 0) {
- l = MIN(l, FRAME_SIZE - ofs);
- bcopy(silence, myframe + ofs, l * 2);
- l_sampsent += l;
- } else { /* silence is over, restart sound if loop */
- if (s->repeat == 0) { /* last block */
- o->cursound = -1;
- o->nosound = 0; /* allow audio data */
- if (ofs < FRAME_SIZE) /* pad with silence */
- bcopy(silence, myframe + ofs, (FRAME_SIZE - ofs) * 2);
- }
- l_sampsent = 0;
- }
- }
- }
- l = soundcard_writeframe(o, myframe);
- if (l > 0)
- o->sampsent = l_sampsent; /* update status */
-}
-
-static void *sound_thread(void *arg)
-{
- char ign[4096];
- struct chan_oss_pvt *o = (struct chan_oss_pvt *) arg;
-
- /*
- * Just in case, kick the driver by trying to read from it.
- * Ignore errors - this read is almost guaranteed to fail.
- */
- read(o->sounddev, ign, sizeof(ign));
- for (;;) {
- fd_set rfds, wfds;
- int maxfd, res;
- struct timeval *to = NULL, t;
-
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- FD_SET(o->sndcmd[0], &rfds);
- maxfd = o->sndcmd[0]; /* pipe from the main process */
- if (o->cursound > -1 && o->sounddev < 0)
- setformat(o, O_RDWR); /* need the channel, try to reopen */
- else if (o->cursound == -1 && o->owner == NULL)
- setformat(o, O_CLOSE); /* can close */
- if (o->sounddev > -1) {
- if (!o->owner) { /* no one owns the audio, so we must drain it */
- FD_SET(o->sounddev, &rfds);
- maxfd = MAX(o->sounddev, maxfd);
- }
- if (o->cursound > -1) {
- /*
- * We would like to use select here, but the device
- * is always writable, so this would become busy wait.
- * So we rather set a timeout to 1/2 of the frame size.
- */
- t.tv_sec = 0;
- t.tv_usec = (1000000 * FRAME_SIZE) / (5 * DEFAULT_SAMPLE_RATE);
- to = &t;
- }
- }
- /* ast_select emulates linux behaviour in terms of timeout handling */
- res = ast_select(maxfd + 1, &rfds, &wfds, NULL, to);
- if (res < 0) {
- ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
- sleep(1);
- continue;
- }
- if (FD_ISSET(o->sndcmd[0], &rfds)) {
- /* read which sound to play from the pipe */
- int i, what = -1;
-
- read(o->sndcmd[0], &what, sizeof(what));
- for (i = 0; sounds[i].ind != -1; i++) {
- if (sounds[i].ind == what) {
- o->cursound = i;
- o->sampsent = 0;
- o->nosound = 1; /* block audio from pbx */
- break;
- }
- }
- if (sounds[i].ind == -1)
- ast_log(LOG_WARNING, "invalid sound index: %d\n", what);
- }
- if (o->sounddev > -1) {
- if (FD_ISSET(o->sounddev, &rfds)) /* read and ignore errors */
- read(o->sounddev, ign, sizeof(ign));
- if (to != NULL) /* maybe it is possible to write */
- send_sound(o);
- }
- }
- return NULL; /* Never reached */
-}
-
-/*!
* reset and close the device if opened,
* then open and initialize it in the desired mode,
* trigger reads and writes so we can start using it.
@@ -763,13 +591,6 @@ static int oss_text(struct ast_channel *c, const char *text)
return 0;
}
-/*! \brief Play ringtone 'x' on device 'o' */
-static void ring(struct chan_oss_pvt *o, int x)
-{
- write(o->sndcmd[1], &x, sizeof(x));
-}
-
-
/*!
* \brief handler for incoming calls. Either autoanswer, or start ringing
*/
@@ -794,7 +615,7 @@ static int oss_call(struct ast_channel *c, char *dest, int timeout)
f.frametype = AST_FRAME_CONTROL;
f.subclass = AST_CONTROL_RINGING;
ast_queue_frame(c, &f);
- ring(o, AST_CONTROL_RING);
+ ast_indicate(c, AST_CONTROL_RINGING);
} else if (o->autoanswer) {
ast_verbose(" << Auto-answered >> \n");
f.frametype = AST_FRAME_CONTROL;
@@ -805,7 +626,7 @@ static int oss_call(struct ast_channel *c, char *dest, int timeout)
f.frametype = AST_FRAME_CONTROL;
f.subclass = AST_CONTROL_RINGING;
ast_queue_frame(c, &f);
- ring(o, AST_CONTROL_RING);
+ ast_indicate(c, AST_CONTROL_RINGING);
}
return 0;
}
@@ -815,16 +636,8 @@ static int oss_call(struct ast_channel *c, char *dest, int timeout)
*/
static int oss_answer(struct ast_channel *c)
{
- struct chan_oss_pvt *o = c->tech_pvt;
-
ast_verbose(" << Console call has been answered >> \n");
-#if 0
- /* play an answer tone (XXX do we really need it ?) */
- ring(o, AST_CONTROL_ANSWER);
-#endif
ast_setstate(c, AST_STATE_UP);
- o->cursound = -1;
- o->nosound = 0;
return 0;
}
@@ -832,8 +645,6 @@ static int oss_hangup(struct ast_channel *c)
{
struct chan_oss_pvt *o = c->tech_pvt;
- o->cursound = -1;
- o->nosound = 0;
c->tech_pvt = NULL;
o->owner = NULL;
ast_verbose(" << Hangup on console >> \n");
@@ -844,9 +655,6 @@ static int oss_hangup(struct ast_channel *c)
/* Assume auto-hangup too */
o->hookstate = 0;
setformat(o, O_CLOSE);
- } else {
- /* Make congestion noise */
- ring(o, AST_CONTROL_CONGESTION);
}
}
return 0;
@@ -858,11 +666,6 @@ static int oss_write(struct ast_channel *c, struct ast_frame *f)
int src;
struct chan_oss_pvt *o = c->tech_pvt;
- /* Immediately return if no sound is enabled */
- if (o->nosound)
- return 0;
- /* Stop any currently playing sound */
- o->cursound = -1;
/*
* we could receive a block which is not a multiple of our
* FRAME_SIZE, so buffer it locally and write to the device
@@ -948,43 +751,33 @@ static int oss_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
static int oss_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
{
struct chan_oss_pvt *o = c->tech_pvt;
- int res = -1;
+ int res = 0;
switch (cond) {
case AST_CONTROL_BUSY:
case AST_CONTROL_CONGESTION:
case AST_CONTROL_RINGING:
- res = cond;
- break;
-
case -1:
- o->cursound = -1;
- o->nosound = 0; /* when cursound is -1 nosound must be 0 */
- return 0;
-
- case AST_CONTROL_VIDUPDATE:
res = -1;
break;
-
+ case AST_CONTROL_PROGRESS:
+ case AST_CONTROL_PROCEEDING:
+ case AST_CONTROL_VIDUPDATE:
+ break;
case AST_CONTROL_HOLD:
ast_verbose(" << Console Has Been Placed on Hold >> \n");
ast_moh_start(c, data, o->mohinterpret);
break;
-
case AST_CONTROL_UNHOLD:
ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
ast_moh_stop(c);
break;
-
default:
ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
return -1;
}
- if (res > -1)
- ring(o, res);
-
- return 0;
+ return res;
}
/*!
@@ -1149,8 +942,7 @@ static char *console_autoanswer(struct ast_cli_entry *e, int cmd, struct ast_cli
}
/*! \brief helper function for the answer key/cli command */
-char *console_do_answer(int fd);
-char *console_do_answer(int fd)
+static char *console_do_answer(int fd)
{
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
struct chan_oss_pvt *o = find_desc(oss_active);
@@ -1160,8 +952,6 @@ char *console_do_answer(int fd)
return CLI_FAILURE;
}
o->hookstate = 1;
- o->cursound = -1;
- o->nosound = 0;
ast_queue_frame(o->owner, &f);
return CLI_SUCCESS;
}
@@ -1242,8 +1032,6 @@ static char *console_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
if (a->argc != e->args)
return CLI_SHOWUSAGE;
- o->cursound = -1;
- o->nosound = 0;
if (!o->owner && !o->hookstate) { /* XXX maybe only one ? */
ast_cli(a->fd, "No call to hang up\n");
return CLI_FAILURE;
@@ -1271,8 +1059,6 @@ static char *console_flash(struct ast_cli_entry *e, int cmd, struct ast_cli_args
if (a->argc != e->args)
return CLI_SHOWUSAGE;
- o->cursound = -1;
- o->nosound = 0; /* when cursound is -1 nosound must be 0 */
if (!o->owner) { /* XXX maybe !o->hookstate too ? */
ast_cli(a->fd, "No call to flash\n");
return CLI_FAILURE;
@@ -1595,7 +1381,7 @@ static struct chan_oss_pvt *store_config(struct ast_config *cfg, char *ctg)
if (o == &oss_default) /* we are done with the default */
return NULL;
- openit:
+openit:
#ifdef TRYOPEN
if (setformat(o, O_RDWR) < 0) { /* open device */
ast_verb(1, "Device %s not detected\n", ctg);
@@ -1605,11 +1391,7 @@ static struct chan_oss_pvt *store_config(struct ast_config *cfg, char *ctg)
if (o->duplex != M_FULL)
ast_log(LOG_WARNING, "XXX I don't work right with non " "full-duplex sound cards XXX\n");
#endif /* TRYOPEN */
- if (pipe(o->sndcmd) != 0) {
- ast_log(LOG_ERROR, "Unable to create pipe\n");
- goto error;
- }
- ast_pthread_create_background(&o->sthread, NULL, sound_thread, o);
+
/* link into list of devices */
if (o != &oss_default) {
o->next = oss_default.next;
@@ -1617,10 +1399,12 @@ static struct chan_oss_pvt *store_config(struct ast_config *cfg, char *ctg)
}
return o;
- error:
+#ifdef TRYOPEN
+error:
if (o != &oss_default)
ast_free(o);
return NULL;
+#endif
}
static int load_module(void)
@@ -1673,15 +1457,10 @@ static int unload_module(void)
for (o = oss_default.next; o; o = o->next) {
close(o->sounddev);
- if (o->sndcmd[0] > 0) {
- close(o->sndcmd[0]);
- close(o->sndcmd[1]);
- }
if (o->owner)
ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
if (o->owner) /* XXX how ??? */
return -1;
- /* XXX what about the thread ? */
/* XXX what about the memory allocated ? */
}
return 0;