summaryrefslogtreecommitdiff
path: root/channels/chan_oss.c
diff options
context:
space:
mode:
authorLuigi Rizzo <rizzo@icir.org>2006-11-18 08:19:41 +0000
committerLuigi Rizzo <rizzo@icir.org>2006-11-18 08:19:41 +0000
commit34ec231da7d9524963c9586d295c6f303195b04c (patch)
tree6a4beb5d92416ec5eccc8e0e5a3cedf15e43068d /channels/chan_oss.c
parent6dcb17baafe8e64e97d40e671ec68c01659ff780 (diff)
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. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@47822 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_oss.c')
-rw-r--r--channels/chan_oss.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/channels/chan_oss.c b/channels/chan_oss.c
index 3e68628e7..cec9f565a 100644
--- a/channels/chan_oss.c
+++ b/channels/chan_oss.c
@@ -530,7 +530,7 @@ static int soundcard_writeframe(struct chan_oss_pvt *o, short *data)
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 @@ static void send_sound(struct chan_oss_pvt *o)
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 @@ static void send_sound(struct chan_oss_pvt *o)
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 @@ static void *sound_thread(void *arg)
for (;;) {
fd_set rfds, wfds;
int maxfd, res;
+ struct timeval *to = NULL, t;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
@@ -620,13 +618,19 @@ static void *sound_thread(void *arg)
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 @@ static void *sound_thread(void *arg)
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);
}
}