From 90cfc9e3bc780d9b1dcce497a1b4cb504e15e62f Mon Sep 17 00:00:00 2001 From: Mark Spencer <markster@digium.com> Date: Sun, 16 Oct 2005 03:07:15 +0000 Subject: [PATCH] Make indications work more efficiently and without heavy floating point (bug #5360) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@6796 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- indications.c | 67 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 18 deletions(-) diff --git a/indications.c b/indications.c index 5f00a31798..6b2095216f 100755 --- a/indications.c +++ b/indications.c @@ -61,10 +61,14 @@ static int midi_tohz[128] = { }; struct playtones_item { - int freq1; - int freq2; - int duration; + int fac1; + int init_v2_1; + int init_v3_1; + int fac2; + int init_v2_2; + int init_v3_2; int modulate; + int duration; }; struct playtones_def { @@ -77,10 +81,17 @@ struct playtones_def { struct playtones_state { int vol; + int v1_1; + int v2_1; + int v3_1; + int v1_2; + int v2_2; + int v3_2; int reppos; int nitems; struct playtones_item *items; int npos; + int oldnpos; int pos; int origwfmt; struct ast_frame f; @@ -115,6 +126,7 @@ static void * playtones_alloc(struct ast_channel *chan, void *params) ps->reppos = pd->reppos; ps->nitems = pd->nitems; ps->items = pd->items; + ps->oldnpos = -1; } /* Let interrupts interrupt :) */ if (pd->interruptible) @@ -140,20 +152,34 @@ static int playtones_generator(struct ast_channel *chan, void *data, int len, in memset(&ps->f, 0, sizeof(ps->f)); pi = &ps->items[ps->npos]; + if (ps->oldnpos != ps->npos) { + /* Load new parameters */ + ps->v1_1 = 0; + ps->v2_1 = pi->init_v2_1; + ps->v3_1 = pi->init_v3_1; + ps->v1_2 = 0; + ps->v2_2 = pi->init_v2_2; + ps->v3_2 = pi->init_v3_2; + ps->oldnpos = ps->npos; + } for (x=0;x<len/2;x++) { - if (pi->modulate) - /* Modulate 1st tone with 2nd, to 90% modulation depth */ - ps->data[x] = ps->vol * 2 * ( - sin((pi->freq1 * 2.0 * M_PI / 8000.0) * (ps->pos + x)) * - (0.9 * fabs(sin((pi->freq2 * 2.0 * M_PI / 8000.0) * (ps->pos + x))) + 0.1) - ); - else - /* Add 2 tones together */ - ps->data[x] = ps->vol * ( - sin((pi->freq1 * 2.0 * M_PI / 8000.0) * (ps->pos + x)) + - sin((pi->freq2 * 2.0 * M_PI / 8000.0) * (ps->pos + x)) - ); + ps->v1_1 = ps->v2_1; + ps->v2_1 = ps->v3_1; + ps->v3_1 = (pi->fac1 * ps->v2_1 >> 15) - ps->v1_1; + + ps->v1_2 = ps->v2_2; + ps->v2_2 = ps->v3_2; + ps->v3_2 = (pi->fac2 * ps->v2_2 >> 15) - ps->v1_2; + if (pi->modulate) { + int p; + p = ps->v3_2 - 32768; + if (p < 0) p = -p; + p = ((p * 9) / 10) + 1; + ps->data[x] = (ps->v3_1 * p) >> 15; + } else + ps->data[x] = ps->v3_1 + ps->v3_2; } + ps->f.frametype = AST_FRAME_VOICE; ps->f.subclass = AST_FORMAT_SLINEAR; ps->f.datalen = len; @@ -192,7 +218,7 @@ int ast_playtones_start(struct ast_channel *chan, int vol, const char *playlst, if (!data) return -1; if (vol < 1) - d.vol = 8192; + d.vol = 7219; /* Default to -8db */ d.interruptible = interruptible; @@ -278,8 +304,13 @@ int ast_playtones_start(struct ast_channel *chan, int vol, const char *playlst, ast_log(LOG_WARNING, "Realloc failed!\n"); return -1; } - d.items[d.nitems].freq1 = freq1; - d.items[d.nitems].freq2 = freq2; + d.items[d.nitems].fac1 = 2.0 * cos(2.0 * M_PI * (freq1 / 8000.0)) * 32768.0; + d.items[d.nitems].init_v2_1 = sin(-4.0 * M_PI * (freq1 / 8000.0)) * d.vol; + d.items[d.nitems].init_v3_1 = sin(-2.0 * M_PI * (freq1 / 8000.0)) * d.vol; + + d.items[d.nitems].fac2 = 2.0 * cos(2.0 * M_PI * (freq2 / 8000.0)) * 32768.0; + d.items[d.nitems].init_v2_2 = sin(-4.0 * M_PI * (freq2 / 8000.0)) * d.vol; + d.items[d.nitems].init_v3_2 = sin(-2.0 * M_PI * (freq2 / 8000.0)) * d.vol; d.items[d.nitems].duration = time; d.items[d.nitems].modulate = modulate; d.nitems++; -- GitLab