x86-64 compile fixes and cleanups
[asterisk/asterisk.git] / indications.c
index 180b948..25b98a0 100755 (executable)
@@ -31,6 +31,7 @@ struct playtones_item {
        int freq1;
        int freq2;
        int duration;
+       int modulate;
 };
 
 struct playtones_def {
@@ -103,7 +104,15 @@ static int playtones_generator(struct ast_channel *chan, void *data, int len, in
 
        pi = &ps->items[ps->npos];
        for (x=0;x<len/2;x++) {
-               ps->data[x] = ps->vol * (
+               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))
                        );
@@ -114,6 +123,8 @@ static int playtones_generator(struct ast_channel *chan, void *data, int len, in
        ps->f.samples = samples;
        ps->f.offset = AST_FRIENDLY_OFFSET;
        ps->f.data = ps->data;
+       ps->f.delivery.tv_sec = 0;
+       ps->f.delivery.tv_usec = 0;
        ast_write(chan, &ps->f);
 
        ps->pos += x;
@@ -157,7 +168,7 @@ int ast_playtones_start(struct ast_channel *chan, int vol, const char *playlst,
                separator = ",";
        s = strsep(&stringp,separator);
         while(s && *s) {
-               int freq1, freq2, time;
+               int freq1, freq2, time, modulate=0;
 
                if (s[0]=='!')
                        s++;
@@ -168,6 +179,13 @@ int ast_playtones_start(struct ast_channel *chan, int vol, const char *playlst,
                } else if (sscanf(s, "%d+%d", &freq1, &freq2) == 2) {
                        /* f1+f2 format */
                        time = 0;
+               } else if (sscanf(s, "%d*%d/%d", &freq1, &freq2, &time) == 3) {
+                       /* f1*f2/time format */
+                       modulate = 1;
+               } else if (sscanf(s, "%d*%d", &freq1, &freq2) == 2) {
+                       /* f1*f2 format */
+                       time = 0;
+                       modulate = 1;
                } else if (sscanf(s, "%d/%d", &freq1, &time) == 2) {
                        /* f1/time format */
                        freq2 = 0;
@@ -186,6 +204,7 @@ int ast_playtones_start(struct ast_channel *chan, int vol, const char *playlst,
                d.items[d.nitems].freq1    = freq1;
                d.items[d.nitems].freq2    = freq2;
                d.items[d.nitems].duration = time;
+               d.items[d.nitems].modulate = modulate;
                d.nitems++;
 
                s = strsep(&stringp,separator);
@@ -210,7 +229,7 @@ static struct tone_zone *current_tonezone;
 
 /* Protect the tone_zones list (highly unlikely that two things would change
  * it at the same time, but still! */
-ast_mutex_t tzlock = AST_MUTEX_INITIALIZER;
+AST_MUTEX_DEFINE_EXPORTED(tzlock);
 
 /* Set global indication country */
 int ast_set_indication_country(const char *country)
@@ -218,7 +237,8 @@ int ast_set_indication_country(const char *country)
        if (country) {
                struct tone_zone *z = ast_get_indication_zone(country);
                if (z) {
-                       ast_verbose(VERBOSE_PREFIX_3 "Setting default indication country to '%s'\n",country);
+                       if (option_verbose > 2)
+                               ast_verbose(VERBOSE_PREFIX_3 "Setting default indication country to '%s'\n",country);
                        current_tonezone = z;
                        return 0;
                }
@@ -303,6 +323,8 @@ static inline void free_zone(struct tone_zone* zone)
                free(zone->tones);
                zone->tones = tmp;
        }
+       if (zone->ringcadance)
+               free((void*)zone->ringcadance);
        free(zone);
 }
 
@@ -342,7 +364,8 @@ int ast_register_indication_country(struct tone_zone *zone)
                tone_zones = zone;
        ast_mutex_unlock(&tzlock);
 
-       ast_verbose(VERBOSE_PREFIX_3 "Registered indication country '%s'\n",zone->country);
+       if (option_verbose > 2)
+               ast_verbose(VERBOSE_PREFIX_3 "Registered indication country '%s'\n",zone->country);
        return 0;
 }
 
@@ -373,8 +396,11 @@ int ast_unregister_indication_country(const char *country)
                                ast_log(LOG_NOTICE,"Removed default indication country '%s'\n",tz->country);
                                current_tonezone = NULL;
                        }
-                       ast_verbose(VERBOSE_PREFIX_3 "Unregistered indication country '%s'\n",tz->country);
+                       if (option_verbose > 2)
+                               ast_verbose(VERBOSE_PREFIX_3 "Unregistered indication country '%s'\n",tz->country);
                        free_zone(tz);
+                       if (tone_zones == tz)
+                               tone_zones = tmp;
                        tz = tmp;
                        res = 0;
                }