Index: res/res_musiconhold.c =================================================================== --- res/res_musiconhold.c (revision 283524) +++ res/res_musiconhold.c (working copy) @@ -41,16 +41,11 @@ #include #include #include -#include #ifdef SOLARIS #include #endif -#ifdef HAVE_DAHDI -#include -#endif - #include "asterisk/lock.h" #include "asterisk/file.h" #include "asterisk/channel.h" @@ -68,6 +63,9 @@ #include "asterisk/manager.h" #include "asterisk/paths.h" #include "asterisk/astobj2.h" +#include "asterisk/timing.h" +#include "asterisk/time.h" +#include "asterisk/poll-compat.h" #define INITIAL_NUM_FILES 8 #define HANDLE_REF 1 @@ -198,10 +196,10 @@ pthread_t thread; /*! Source of audio */ int srcfd; - /*! FD for timing source */ - int pseudofd; + /*! Generic timer */ + struct ast_timer *timer; /*! Created on the fly, from RT engine */ - int realtime; + unsigned int realtime:1; unsigned int delete:1; AST_LIST_HEAD_NOLOCK(, mohdata) members; AST_LIST_ENTRY(mohclass) list; @@ -607,7 +605,6 @@ struct mohclass *class = data; struct mohdata *moh; - char buf[8192]; short sbuf[8192]; int res, res2; int len; @@ -626,12 +623,26 @@ pthread_testcancel(); } } - if (class->pseudofd > -1) { + if (class->timer) { + struct pollfd pfd = { .fd = ast_timer_fd(class->timer), }; + struct timeval tv = { .tv_usec = 40000 }; + #ifdef SOLARIS thr_yield(); #endif /* Pause some amount of time */ - res = read(class->pseudofd, buf, sizeof(buf)); +#ifdef HAVE_POLL2 + if (ast_poll2(&pfd, 1, &tv) > 0) { + ast_timer_ack(class->timer, 1); + } + res = 8 * (40000 - tv.tv_usec) / 1000; +#else + tv = ast_tvnow(); + if (ast_poll(&pfd, 1, 40) > 0) { + ast_timer_ack(class->timer, 1); + } + res = 8 * (40 - ast_tvdiff_ms(ast_tvnow(), tv)); +#endif pthread_testcancel(); } else { long delta; @@ -1129,10 +1140,6 @@ static int init_app_class(struct mohclass *class) { -#ifdef HAVE_DAHDI - int x; -#endif - if (!strcasecmp(class->mode, "custom")) { ast_set_flag(class, MOH_CUSTOM); } else if (!strcasecmp(class->mode, "mp3nb")) { @@ -1142,27 +1149,23 @@ } else if (!strcasecmp(class->mode, "quietmp3")) { ast_set_flag(class, MOH_QUIET); } - + class->srcfd = -1; - class->pseudofd = -1; -#ifdef HAVE_DAHDI - /* Open /dev/zap/pseudo for timing... Is - there a better, yet reliable way to do this? */ - class->pseudofd = open("/dev/dahdi/pseudo", O_RDONLY); - if (class->pseudofd < 0) { - ast_log(LOG_WARNING, "Unable to open pseudo channel for timing... Sound may be choppy.\n"); - } else { - x = 320; - ioctl(class->pseudofd, DAHDI_SET_BLOCKSIZE, &x); + if (!(class->timer = ast_timer_open())) { + ast_log(LOG_WARNING, "Unable to create timer: %s\n", strerror(errno)); } -#endif + if (class->timer && ast_timer_set_rate(class->timer, 25)) { + ast_log(LOG_WARNING, "Unable to set 40ms frame rate: %s\n", strerror(errno)); + ast_timer_close(class->timer); + class->timer = NULL; + } if (ast_pthread_create_background(&class->thread, NULL, monmp3thread, class)) { ast_log(LOG_WARNING, "Unable to create moh thread...\n"); - if (class->pseudofd > -1) { - close(class->pseudofd); - class->pseudofd = -1; + if (class->timer) { + ast_timer_close(class->timer); + class->timer = NULL; } return -1; } @@ -1192,7 +1195,7 @@ time(&moh->start); moh->start -= respawn_time; - + if (!strcasecmp(moh->mode, "files")) { if (init_files_class(moh)) { if (unref) { @@ -1222,7 +1225,7 @@ if (unref) { moh = mohclass_unref(moh, "Unreffing new moh class because we just added it to the container"); } - + return 0; } @@ -1390,7 +1393,7 @@ time(&mohclass->start); mohclass->start -= respawn_time; - + if (!strcasecmp(mohclass->mode, "files")) { if (!moh_scan_files(mohclass)) { mohclass = mohclass_unref(mohclass, "unreffing potential mohclass (moh_scan_files failed)"); @@ -1408,21 +1411,17 @@ ast_set_flag(mohclass, MOH_SINGLE | MOH_QUIET); else if (!strcasecmp(mohclass->mode, "quietmp3")) ast_set_flag(mohclass, MOH_QUIET); - + mohclass->srcfd = -1; -#ifdef HAVE_DAHDI - /* Open /dev/dahdi/pseudo for timing... Is - there a better, yet reliable way to do this? */ - mohclass->pseudofd = open("/dev/dahdi/pseudo", O_RDONLY); - if (mohclass->pseudofd < 0) { - ast_log(LOG_WARNING, "Unable to open pseudo channel for timing... Sound may be choppy.\n"); - } else { - int x = 320; - ioctl(mohclass->pseudofd, DAHDI_SET_BLOCKSIZE, &x); + if (!(mohclass->timer = ast_timer_open())) { + ast_log(LOG_WARNING, "Unable to create timer: %s\n", strerror(errno)); } -#else - mohclass->pseudofd = -1; -#endif + if (mohclass->timer && ast_timer_set_rate(mohclass->timer, 25)) { + ast_log(LOG_WARNING, "Unable to set 40ms frame rate: %s\n", strerror(errno)); + ast_timer_close(mohclass->timer); + mohclass->timer = NULL; + } + /* Let's check if this channel already had a moh class before */ if (state && state->class) { /* Class already exist for this channel */ @@ -1435,9 +1434,9 @@ } else { if (ast_pthread_create_background(&mohclass->thread, NULL, monmp3thread, mohclass)) { ast_log(LOG_WARNING, "Unable to create moh...\n"); - if (mohclass->pseudofd > -1) { - close(mohclass->pseudofd); - mohclass->pseudofd = -1; + if (mohclass->timer) { + ast_timer_close(mohclass->timer); + mohclass->timer = NULL; } mohclass = mohclass_unref(mohclass, "Unreffing potential mohclass (failed to create background thread)"); return -1; @@ -1618,7 +1617,7 @@ if (reload) { ao2_t_callback(mohclasses, OBJ_NODATA, moh_class_mark, NULL, "Mark deleted classes"); } - + ast_clear_flag(global_flags, AST_FLAGS_ALL); cat = ast_category_browse(cfg, NULL);