[Asterisk-Dev] Fix for Music on Hold
Michael Manousos
manousos at inaccessnetworks.com
Mon Jul 21 02:51:12 MST 2003
This patch fixes the playback of music on hold for
machines that do not have any zaptel hardware.
Michael.
-------------- next part --------------
Index: res/res_musiconhold.c
===================================================================
RCS file: /usr/cvsroot/asterisk/res/res_musiconhold.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 res_musiconhold.c
--- res/res_musiconhold.c 18 Mar 2003 06:00:18 -0000 1.1.1.5
+++ res/res_musiconhold.c 21 Jul 2003 10:11:48 -0000
@@ -201,11 +201,24 @@
static void *monmp3thread(void *data)
{
+#define MOH_MS_INTERVAL 100
+
struct mohclass *class = data;
struct mohdata *moh;
char buf[8192];
short sbuf[8192];
int res, res2;
+ struct timeval tv;
+ struct timeval tv_tmp;
+ long error_sec, error_usec;
+ long delay;
+
+ tv_tmp.tv_sec = 0;
+ tv_tmp.tv_usec = 0;
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ error_sec = 0;
+ error_usec = 0;
signal(SIGCHLD, child_handler);
for(;/* ever */;) {
/* Spawn mp3 player if it's not there */
@@ -220,8 +233,39 @@
/* Pause some amount of time */
res = read(class->pseudofd, buf, sizeof(buf));
} else {
- /* otherwise just sleep (unreliable) */
- usleep(100000); /* Sleep 100 ms */
+ /* Reliable sleep */
+ if (gettimeofday(&tv_tmp, NULL) < 0) {
+ ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
+ return NULL;
+ }
+ if (((unsigned long)(tv.tv_sec) > 0)&&((unsigned long)(tv.tv_usec) > 0)) {
+ if ((unsigned long)(tv_tmp.tv_usec) < (unsigned long)(tv.tv_usec)) {
+ tv_tmp.tv_usec += 1000000;
+ tv_tmp.tv_sec -= 1;
+ }
+ error_sec = (unsigned long)(tv_tmp.tv_sec) - (unsigned long)(tv.tv_sec);
+ error_usec = (unsigned long)(tv_tmp.tv_usec) - (unsigned long)(tv.tv_usec);
+ } else {
+ error_sec = 0;
+ error_usec = 0;
+ }
+ if (error_sec * 1000 + error_usec / 1000 < MOH_MS_INTERVAL) {
+ tv.tv_sec = tv_tmp.tv_sec + (MOH_MS_INTERVAL/1000 - error_sec);
+ tv.tv_usec = tv_tmp.tv_usec + ((MOH_MS_INTERVAL % 1000) * 1000 - error_usec);
+ delay = (MOH_MS_INTERVAL/1000 - error_sec) * 1000 +
+ ((MOH_MS_INTERVAL % 1000) * 1000 - error_usec) / 1000;
+ } else {
+ ast_log(LOG_NOTICE, "Request to schedule in the past?!?!\n");
+ tv.tv_sec = tv_tmp.tv_sec;
+ tv.tv_usec = tv_tmp.tv_usec;
+ delay = 0;
+ }
+ if (tv.tv_usec > 1000000) {
+ tv.tv_sec++;
+ tv.tv_usec-= 1000000;
+ }
+ if (delay > 0)
+ usleep(delay * 1000);
res = 800; /* 800 samples */
}
if (!class->members)
@@ -400,7 +444,8 @@
ast_log(LOG_WARNING, "Only doing %d of %d requested bytes on %s\n", sizeof(buf), len, chan->name);
len = sizeof(buf);
}
- res = read(moh->pipe[0], buf + AST_FRIENDLY_OFFSET/2, len);
+ /* XXX SEGFAULT res = read(moh->pipe[0], buf + AST_FRIENDLY_OFFSET/2, len);*/
+ res = read(moh->pipe[0], buf, len);
#if 0
if (res != len) {
ast_log(LOG_WARNING, "Read only %d of %d bytes: %s\n", res, len, strerror(errno));
@@ -413,7 +458,8 @@
f.mallocd = 0;
f.datalen = res;
f.samples = res / 2;
- f.data = buf + AST_FRIENDLY_OFFSET / 2;
+ /* XXX SEGFAULT f.data = buf + AST_FRIENDLY_OFFSET / 2;*/
+ f.data = buf;
f.offset = AST_FRIENDLY_OFFSET;
if (ast_write(chan, &f)< 0) {
ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror(errno));
More information about the asterisk-dev
mailing list