[asterisk-commits] rizzo: trunk r47822 - /trunk/channels/chan_oss.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Sat Nov 18 01:19:42 MST 2006


Author: rizzo
Date: Sat Nov 18 02:19:41 2006
New Revision: 47822

URL: http://svn.digium.com/view/asterisk?view=rev&rev=47822
Log:
prevent the sound thread from consuming all the available CPU
doing busy-wait on the output audio device.
As it is set now, it tries to push a frame every 10ms,
which is still too frequent but avoids deep restructuring
of the code (which i should do, though).

Note, this is only for ring tones, regular audio coming
from the network is still delivered as soon as it is
available.

Eventually this could well end up in the 1.4 branch, but
since i am probably the only user of chan_oss there isn't
much urgency to do that.


Modified:
    trunk/channels/chan_oss.c

Modified: trunk/channels/chan_oss.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_oss.c?view=diff&rev=47822&r1=47821&r2=47822
==============================================================================
--- trunk/channels/chan_oss.c (original)
+++ trunk/channels/chan_oss.c Sat Nov 18 02:19:41 2006
@@ -530,7 +530,7 @@
 		return 0;
 	}
 	o->w_errors = 0;
-	return write(o->sounddev, ((void *) data), FRAME_SIZE * 2);
+	return write(o->sounddev, (void *)data, FRAME_SIZE * 2);
 }
 
 /*
@@ -559,10 +559,8 @@
 		l = s->samplen - l_sampsent;	/* # of available samples */
 		if (l > 0) {
 			start = l_sampsent % s->datalen;	/* source offset */
-			if (l > FRAME_SIZE - ofs)	/* don't overflow the frame */
-				l = FRAME_SIZE - ofs;
-			if (l > s->datalen - start)	/* don't overflow the source */
-				l = s->datalen - start;
+			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);
@@ -572,8 +570,7 @@
 
 			l += s->silencelen;
 			if (l > 0) {
-				if (l > FRAME_SIZE - ofs)
-					l = FRAME_SIZE - ofs;
+				l = MIN(l, FRAME_SIZE - ofs);
 				bcopy(silence, myframe + ofs, l * 2);
 				l_sampsent += l;
 			} else {			/* silence is over, restart sound if loop */
@@ -605,6 +602,7 @@
 	for (;;) {
 		fd_set rfds, wfds;
 		int maxfd, res;
+		struct timeval *to = NULL, t;
 
 		FD_ZERO(&rfds);
 		FD_ZERO(&wfds);
@@ -620,13 +618,19 @@
 				maxfd = MAX(o->sounddev, maxfd);
 			}
 			if (o->cursound > -1) {
-				FD_SET(o->sounddev, &wfds);
-				maxfd = MAX(o->sounddev, maxfd);
+				/*
+				 * 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, NULL);
-		if (res < 1) {
+		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;
@@ -650,7 +654,7 @@
 		if (o->sounddev > -1) {
 			if (FD_ISSET(o->sounddev, &rfds))	/* read and ignore errors */
 				read(o->sounddev, ign, sizeof(ign));
-			if (FD_ISSET(o->sounddev, &wfds))
+			if (to != NULL)			/* maybe it is possible to write */
 				send_sound(o);
 		}
 	}



More information about the asterisk-commits mailing list