Index: Makefile
===================================================================
RCS file: /usr/cvsroot/asterisk/Makefile,v
retrieving revision 1.24
diff -u -r1.24 Makefile
--- Makefile	19 Aug 2003 16:42:30 -0000	1.24
+++ Makefile	25 Aug 2003 03:25:52 -0000
@@ -36,7 +36,7 @@
 ######### Uncomment 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.  
-#K6OPT  = -DK6OPT
+K6OPT  = -DK6OPT
 
 #Tell gcc to optimize the asterisk's code
 OPTIMIZE=-O6
@@ -256,6 +256,7 @@
 	install -m 755 asterisk $(ASTSBINDIR)/
 	install -m 755 astgenkey $(ASTSBINDIR)/
 	install -m 755 safe_asterisk $(ASTSBINDIR)/
+	install -m 755 sox_wrapper /usr/bin/
 	for x in $(SUBDIRS); do $(MAKE) -C $$x install || exit 1 ; done
 	install -d $(ASTHEADERDIR)
 	install include/asterisk/*.h $(ASTHEADERDIR)
Index: res/res_musiconhold.c
===================================================================
RCS file: /usr/cvsroot/asterisk/res/res_musiconhold.c,v
retrieving revision 1.7
diff -u -r1.7 res_musiconhold.c
--- res/res_musiconhold.c	16 Aug 2003 05:10:35 -0000	1.7
+++ res/res_musiconhold.c	25 Aug 2003 03:25:52 -0000
@@ -93,8 +93,7 @@
 
 static ast_mutex_t moh_lock = AST_MUTEX_INITIALIZER;
 
-#define MPG_123 "/usr/bin/mpg123"
-#define MAX_MP3S 256
+#define MUSIC_PLAYER "/usr/bin/sox_wrapper"
 
 static void child_handler(int sig)
 {
@@ -108,8 +107,7 @@
 {
 	int fds[2];
 	int files;
-	char fns[MAX_MP3S][80];
-	char *argv[MAX_MP3S + 50];
+	char *argv[51];
 	char xargs[256];
 	char *argptr;
 	int argc;
@@ -120,18 +118,11 @@
 		ast_log(LOG_WARNING, "%s is not a valid directory\n", class->dir);
 		return -1;
  	}
-	argv[0] = MPG_123;
-	argv[1] = "-q";
-	argv[2] = "-s";
-	argv[3] = "--mono";
-	argv[4] = "-r";
-	argv[5] = "8000";
-	argv[6] = "-b";
-	argv[7] = "2048";
-	argc = 8;
+	closedir(dir);
+	argv[0] = MUSIC_PLAYER;
+	argc = 1;
 	if (class->quiet) {
-		argv[argc++] = "-f";
-		argv[argc++] = "8192";
+		argv[argc++] = "-Q";
 	}
 
 	/* Look for extra arguments and add them to the list */
@@ -146,32 +137,20 @@
 		}
 	}
 
-	files = 0;
-	while((de = readdir(dir)) && (files < MAX_MP3S)) {
-		if ((strlen(de->d_name) > 3) && !strcasecmp(de->d_name + strlen(de->d_name) - 4, ".mp3")) {
-			strncpy(fns[files], de->d_name, sizeof(fns[files]));
-			argv[argc++] = fns[files];
-			files++;
-		}
-	}
+        argv[argc++] = class->dir;
 	argv[argc] = NULL;
-	closedir(dir);
 	if (pipe(fds)) {	
 		ast_log(LOG_WARNING, "Pipe failed\n");
 		return -1;
 	}
 #if 0
-	printf("%d files total, %d args total\n", files, argc);
+	printf("%d args total\n", argc);
 	{
 		int x;
 		for (x=0;argv[x];x++)
 			printf("arg%d: %s\n", x, argv[x]);
 	}
 #endif	
-	if (!files) {
-		ast_log(LOG_WARNING, "Found no files in '%s'\n", class->dir);
-		return -1;
-	}
 	class->pid = fork();
 	if (class->pid < 0) {
 		close(fds[0]);
@@ -189,7 +168,7 @@
 			close(x);
 		/* Child */
 		chdir(class->dir);
-		execv(MPG_123, argv);
+		execv(MUSIC_PLAYER, argv);
 		ast_log(LOG_WARNING, "Exec failed: %s\n", strerror(errno));
 		exit(1);
 	} else {
@@ -574,8 +553,6 @@
 static void ast_moh_destroy(void)
 {
 	struct mohclass *moh;
-	char buff[8192];
-	int bytes, tbytes=0, stime = 0;
 	if (option_verbose > 1)
 		ast_verbose(VERBOSE_PREFIX_2 "Destroying any remaining musiconhold processes\n");
 	ast_mutex_lock(&moh_lock);
@@ -583,12 +560,7 @@
 	while(moh) {
 		if (moh->pid) {
 			ast_log(LOG_DEBUG, "killing %d!\n", moh->pid);
-			stime = time(NULL);
-			kill(moh->pid, SIGABRT);
-			while ((bytes = read(moh->srcfd, buff, 8192)) && time(NULL) < stime + 5) {
-				tbytes = tbytes + bytes;
-			}
-			ast_log(LOG_DEBUG, "mpg123 pid %d and child died after %d bytes read\n", moh->pid, tbytes);
+			kill(moh->pid, SIGTERM);
 			close(moh->srcfd);
 			moh->pid = 0;
 			}
--- sox_wrapper       16 Aug 2003 05:10:35 -0000
+++ sox_wrapper       25 Aug 2003 03:25:52 -0000
@@ -0,0 +1,98 @@
+#!/usr/bin/perl
+use POSIX ":sys_wait_h";
+use strict;
+
+my ($playerpid, $data, %Kid_Status);
+my $ppid = getppid();
+my $rand = 0;
+my $num = 0;
+my @quiet = ();
+my $dir = $ARGV[$#ARGV];
+
+$SIG{INT} = sub {
+    kill 9, $playerpid;
+    exit 0;
+};
+
+$SIG{PIPE} = sub {
+    kill 9, $playerpid;
+    exit 0;
+};
+
+$SIG{HUP} = sub {
+    kill 9, $playerpid;
+    exec $0, @ARGV;
+};
+
+$SIG{TERM} = sub {
+    kill 9, $playerpid;
+    exit 0;
+};
+
+sub REAPER {
+    my $child;
+    unless (kill 0, $ppid) {
+        exit 0;
+    }
+    while (($child = waitpid(-1,WNOHANG)) > 0) {
+        $Kid_Status{$child} = $?;
+        if ($child == $playerpid) {
+            PlayFile();
+        }
+    }
+    $SIG{CHLD} = \&REAPER;  # still loathe sysV
+}
+$SIG{CHLD} = \&REAPER;
+
+
+die "directory $dir does not exist\n" unless (-d $dir);
+opendir(DIR, $dir);
+my @files = readdir(DIR);
+closedir(DIR);
+
+if ($ARGV[0] eq '-Z' || $ARGV[0] eq '-Q') {
+    if ($ARGV[0] eq '-Z') {
+        $rand = 1;
+        srand();
+    } else {
+        @quiet = ('-v', '0.5');
+    }
+    if ($ARGV[1] eq '-Z' || $ARGV[1] eq '-Q') {
+        if ($ARGV[1] eq '-Z') {
+            $rand = 1;
+            srand();
+        } else {
+            @quiet = ('-v', '0.5');
+        }
+    }
+}
+
+sub PlayFile {
+    my $filename;
+
+    if ($rand) {
+        $filename = $files[int(rand($#files))];
+    } else {
+        $num = 0 if ($num > $#files);
+        $filename = $files[$num++];
+    }
+    if ($filename =~ /\.(...)$/) {
+        $playerpid = fork();
+        if ($playerpid == 0) {
+            exec { "sox" } "sox", "$dir/$filename", '-c', '1', '-r', '8000', '-w', '-s', '-t', 'raw', '-';
+        } elsif ($playerpid) {
+            my $kid;
+            do {
+                $kid = waitpid($playerpid, &WNOHANG);
+                sleep 1;
+            } until $kid > 0;
+        } else {
+            die "Couldn't fork!";
+        }
+    } else {
+        PlayFile();
+    }
+}
+
+PlayFile();
+sleep;
