Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:49:00 2009

## Asterisk developer's documentation

# indications.c File Reference

Tone Management. More...

`#include <stdio.h>`
`#include <stdlib.h>`
`#include <string.h>`
`#include <math.h>`
`#include "asterisk.h"`
`#include "asterisk/indications.h"`
`#include "asterisk/frame.h"`
`#include "asterisk/options.h"`
`#include "asterisk/channel.h"`
`#include "asterisk/logger.h"`
`#include "asterisk/lock.h"`
`#include "asterisk/utils.h"`

Include dependency graph for indications.c:

Go to the source code of this file.

## Data Structures

struct | playtones_def
struct | playtones_item
struct | playtones_state

## Functions

struct tone_zone_sound * | ast_get_indication_tone (const struct tone_zone *zone, const char *indication)
struct tone_zone * | ast_get_indication_zone (const char *country)
| AST_MUTEX_DEFINE_EXPORTED (tzlock)
int | ast_playtones_start (struct ast_channel *chan, int vol, const char *playlst, int interruptible)
void | ast_playtones_stop (struct ast_channel *chan)
int | ast_register_indication (struct tone_zone *zone, const char *indication, const char *tonelist)
int | ast_register_indication_country (struct tone_zone *zone)
int | ast_set_indication_country (const char *country)
int | ast_unregister_indication (struct tone_zone *zone, const char *indication)
int | ast_unregister_indication_country (const char *country)
static void | free_zone (struct tone_zone *zone)
static void * | playtones_alloc (struct ast_channel *chan, void *params)
static int | playtones_generator (struct ast_channel *chan, void *data, int len, int samples)
static void | playtones_release (struct ast_channel *chan, void *params)

## Variables

static struct tone_zone * | current_tonezone
static int | midi_tohz [128]
static struct ast_generator | playtones
struct tone_zone * | tone_zones

## Detailed Description

Tone Management.

Author:
  Pauline Middelink <middelink@polyware.nl>

This set of function allow us to play a list of tones on a channel. Each element has two frequencies, which are mixed together and a duration. For silence both frequencies can be set to 0. The playtones can be given as a comma separated string.

Definition in file indications.c.

## Function Documentation

struct tone_zone_sound* ast_get_indication_tone | ( | const struct tone_zone * | zone,
|  | const char * | indication |
| ) |  |  | `[read]`

Definition at line 397 of file indications.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, tone_zone_sound::name, tone_zone_sound::next, tone_zone::tones, and tzlock.

Referenced by ast_app_dtget(), ast_indicate(), dialtone_indicate(), handle_playtones(), and play_dialtone().

    00398 {
    00399    struct tone_zone_sound *ts;
    00400
    00401    /* we need some tonezone, pick the first */
    00402    if (zone == NULL && current_tonezone)
    00403       zone = current_tonezone;   /* default country? */
    00404    if (zone == NULL && tone_zones)
    00405       zone = tone_zones;      /* any country? */
    00406    if (zone == NULL)
    00407       return 0;   /* not a single country insight */
    00408
    00409    if (ast_mutex_lock(&tzlock)) {
    00410       ast_log(LOG_WARNING, "Unable to lock tone_zones list\n");
    00411       return 0;
    00412    }
    00413    for (ts=zone->tones; ts; ts=ts->next) {
    00414       if (strcasecmp(indication,ts->name)==0) {
    00415          /* found indication! */
    00416          ast_mutex_unlock(&tzlock);
    00417          return ts;
    00418       }
    00419    }
    00420    /* nothing found, sorry */
    00421    ast_mutex_unlock(&tzlock);
    00422    return 0;
    00423 }

struct tone_zone* ast_get_indication_zone | ( | const char * | country | ) | `[read]`

Definition at line 359 of file indications.c.

References tone_zone::alias, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), tone_zone::country, LOG_NOTICE, LOG_WARNING, tone_zone::next, and tzlock.

Referenced by ast_set_indication_country(), handle_add_indication(), and handle_remove_indication().

    00360 {
    00361    struct tone_zone *tz;
    00362    int alias_loop = 0;
    00363
    00364    /* we need some tonezone, pick the first */
    00365    if (country == NULL && current_tonezone)
    00366       return current_tonezone;   /* default country? */
    00367    if (country == NULL && tone_zones)
    00368       return tone_zones;      /* any country? */
    00369    if (country == NULL)
    00370       return 0;   /* not a single country insight */
    00371
    00372    if (ast_mutex_lock(&tzlock)) {
    00373       ast_log(LOG_WARNING, "Unable to lock tone_zones list\n");
    00374       return 0;
    00375    }
    00376    do {
    00377       for (tz=tone_zones; tz; tz=tz->next) {
    00378          if (strcasecmp(country,tz->country)==0) {
    00379             /* tone_zone found */
    00380             if (tz->alias && tz->alias[0]) {
    00381                country = tz->alias;
    00382                break;
    00383             }
    00384             ast_mutex_unlock(&tzlock);
    00385             return tz;
    00386          }
    00387       }
    00388    } while (++alias_loop<20 && tz);
    00389    ast_mutex_unlock(&tzlock);
    00390    if (alias_loop==20)
    00391       ast_log(LOG_NOTICE,"Alias loop for '%s' forcefull broken\n",country);
    00392    /* nothing found, sorry */
    00393    return 0;
    00394 }

AST_MUTEX_DEFINE_EXPORTED | ( | tzlock |  | ) |

int ast_playtones_start | ( | struct ast_channel * | chan,
|  | int | vol,
|  | const char * | playlst,
|  | int | interruptible |
| ) |  |  |

Definition at line 213 of file indications.c.

References ast_activate_generator(), ast_log(), ast_strdupa, playtones_item::duration, playtones_item::fac1, playtones_item::fac2, free, playtones_item::init_v2_1, playtones_item::init_v2_2, playtones_item::init_v3_1, playtones_item::init_v3_2, playtones_def::interruptible, playtones_def::items, LOG_WARNING, playtones_item::modulate, ast_channel::name, playtones_def::nitems, realloc, playtones_def::reppos, s, strsep(), and playtones_def::vol.

Referenced by ast_app_dtget(), ast_indicate(), dialtone_indicate(), do_senddigit(), handle_playtones(), play_dialtone(), and send_digit_to_chan().

    00214 {
    00215    char *s, *data = ast_strdupa(playlst); /* cute */
    00216    struct playtones_def d = { vol, -1, 0, 1, NULL};
    00217    char *stringp=NULL;
    00218    char *separator;
    00219    if (!data)
    00220       return -1;
    00221    if (vol < 1)
    00222       d.vol = 7219; /* Default to -8db */
    00223
    00224    d.interruptible = interruptible;
    00225
    00226    stringp=data;
    00227    /* the stringp/data is not null here */
    00228    /* check if the data is separated with '|' or with ',' by default */
    00229    if (strchr(stringp,'|'))
    00230       separator = "|";
    00231    else
    00232       separator = ",";
    00233    s = strsep(&stringp,separator);
    00234    while (s && *s) {
    00235       int freq1, freq2, time, modulate=0, midinote=0;
    00236
    00237       if (s[0]=='!')
    00238          s++;
    00239       else if (d.reppos == -1)
    00240          d.reppos = d.nitems;
    00241       if (sscanf(s, "%30d+%30d/%30d", &freq1, &freq2, &time) == 3) {
    00242          /* f1+f2/time format */
    00243       } else if (sscanf(s, "%30d+%30d", &freq1, &freq2) == 2) {
    00244          /* f1+f2 format */
    00245          time = 0;
    00246       } else if (sscanf(s, "%30d*%30d/%30d", &freq1, &freq2, &time) == 3) {
    00247          /* f1*f2/time format */
    00248          modulate = 1;
    00249       } else if (sscanf(s, "%30d*%30d", &freq1, &freq2) == 2) {
    00250          /* f1*f2 format */
    00251          time = 0;
    00252          modulate = 1;
    00253       } else if (sscanf(s, "%30d/%30d", &freq1, &time) == 2) {
    00254          /* f1/time format */
    00255          freq2 = 0;
    00256       } else if (sscanf(s, "%30d", &freq1) == 1) {
    00257          /* f1 format */
    00258          freq2 = 0;
    00259          time = 0;
    00260       } else if (sscanf(s, "M%30d+M%30d/%30d", &freq1, &freq2, &time) == 3) {
    00261          /* Mf1+Mf2/time format */
    00262          midinote = 1;
    00263       } else if (sscanf(s, "M%30d+M%30d", &freq1, &freq2) == 2) {
    00264          /* Mf1+Mf2 format */
    00265          time = 0;
    00266          midinote = 1;
    00267       } else if (sscanf(s, "M%30d*M%30d/%30d", &freq1, &freq2, &time) == 3) {
    00268          /* Mf1*Mf2/time format */
    00269          modulate = 1;
    00270          midinote = 1;
    00271       } else if (sscanf(s, "M%30d*M%30d", &freq1, &freq2) == 2) {
    00272          /* Mf1*Mf2 format */
    00273          time = 0;
    00274          modulate = 1;
    00275          midinote = 1;
    00276       } else if (sscanf(s, "M%30d/%30d", &freq1, &time) == 2) {
    00277          /* Mf1/time format */
    00278          freq2 = -1;
    00279          midinote = 1;
    00280       } else if (sscanf(s, "M%30d", &freq1) == 1) {
    00281          /* Mf1 format */
    00282          freq2 = -1;
    00283          time = 0;
    00284          midinote = 1;
    00285       } else {
    00286          ast_log(LOG_WARNING,"%s: tone component '%s' of '%s' is no good\n",chan->name,s,playlst);
    00287          return -1;
    00288       }
    00289
    00290       if (midinote) {
    00291          /* midi notes must be between 0 and 127 */
    00292          if ((freq1 >= 0) && (freq1 <= 127))
    00293             freq1 = midi_tohz[freq1];
    00294          else
    00295             freq1 = 0;
    00296
    00297          if ((freq2 >= 0) && (freq2 <= 127))
    00298             freq2 = midi_tohz[freq2];
    00299          else
    00300             freq2 = 0;
    00301       }
    00302
    00303       d.items = realloc(d.items,(d.nitems+1)*sizeof(struct playtones_item));
    00304       if (d.items == NULL) {
    00305          ast_log(LOG_WARNING, "Realloc failed!\n");
    00306          return -1;
    00307       }
    00308       d.items[d.nitems].fac1 = 2.0 * cos(2.0 * M_PI * (freq1 / 8000.0)) * 32768.0;
    00309       d.items[d.nitems].init_v2_1 = sin(-4.0 * M_PI * (freq1 / 8000.0)) * d.vol;
    00310       d.items[d.nitems].init_v3_1 = sin(-2.0 * M_PI * (freq1 / 8000.0)) * d.vol;
    00311
    00312       d.items[d.nitems].fac2 = 2.0 * cos(2.0 * M_PI * (freq2 / 8000.0)) * 32768.0;
    00313       d.items[d.nitems].init_v2_2 = sin(-4.0 * M_PI * (freq2 / 8000.0)) * d.vol;
    00314       d.items[d.nitems].init_v3_2 = sin(-2.0 * M_PI * (freq2 / 8000.0)) * d.vol;
    00315       d.items[d.nitems].duration = time;
    00316       d.items[d.nitems].modulate = modulate;
    00317       d.nitems++;
    00318
    00319       s = strsep(&stringp,separator);
    00320    }
    00321
    00322    if (ast_activate_generator(chan, &playtones, &d)) {
    00323       free(d.items);
    00324       return -1;
    00325    }
    00326    return 0;
    00327 }

void ast_playtones_stop | ( | struct ast_channel * | chan | ) |

Stop the tones from playing

Definition at line 329 of file indications.c.

References ast_deactivate_generator().

Referenced by ast_app_dtget(), ast_indicate(), disa_exec(), handle_stopplaytones(), and stop_indicate().

    00330 {
    00331    ast_deactivate_generator(chan);
    00332 }

int ast_register_indication | ( | struct tone_zone * | zone,
|  | const char * | indication,
|  | const char * | tonelist |
| ) |  |  |

Definition at line 528 of file indications.c.

References tone_zone::alias, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), tone_zone_sound::data, free, LOG_WARNING, malloc, tone_zone_sound::name, tone_zone_sound::next, strdup, tone_zone::tones, and tzlock.

Referenced by handle_add_indication().

    00529 {
    00530    struct tone_zone_sound *ts,*ps;
    00531
    00532    /* is it an alias? stop */
    00533    if (zone->alias[0])
    00534       return -1;
    00535
    00536    if (ast_mutex_lock(&tzlock)) {
    00537       ast_log(LOG_WARNING, "Unable to lock tone_zones list\n");
    00538       return -2;
    00539    }
    00540    for (ps=NULL,ts=zone->tones; ts; ps=ts,ts=ts->next) {
    00541       if (strcasecmp(indication,ts->name)==0) {
    00542          /* indication already there, replace */
    00543          free((void*)ts->name);
    00544          free((void*)ts->data);
    00545          break;
    00546       }
    00547    }
    00548    if (!ts) {
    00549       /* not there, we have to add */
    00550       ts = malloc(sizeof(struct tone_zone_sound));
    00551       if (!ts) {
    00552          ast_log(LOG_WARNING, "Out of memory\n");
    00553          ast_mutex_unlock(&tzlock);
    00554          return -2;
    00555       }
    00556       ts->next = NULL;
    00557    }
    00558    ts->name = strdup(indication);
    00559    ts->data = strdup(tonelist);
    00560    if (ts->name==NULL || ts->data==NULL) {
    00561       ast_log(LOG_WARNING, "Out of memory\n");
    00562       ast_mutex_unlock(&tzlock);
    00563       return -2;
    00564    }
    00565    if (ps)
    00566       ps->next = ts;
    00567    else
    00568       zone->tones = ts;
    00569    ast_mutex_unlock(&tzlock);
    00570    return 0;
    00571 }

int ast_register_indication_country | ( | struct tone_zone * | zone | ) |

Definition at line 443 of file indications.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), tone_zone::country, free_zone(), LOG_WARNING, tone_zone::next, option_verbose, tzlock, and VERBOSE_PREFIX_3.

Referenced by handle_add_indication(), and ind_load_module().

    00444 {
    00445    struct tone_zone *tz,*pz;
    00446
    00447    if (ast_mutex_lock(&tzlock)) {
    00448       ast_log(LOG_WARNING, "Unable to lock tone_zones list\n");
    00449       return -1;
    00450    }
    00451    for (pz=NULL,tz=tone_zones; tz; pz=tz,tz=tz->next) {
    00452       if (strcasecmp(zone->country,tz->country)==0) {
    00453          /* tone_zone already there, replace */
    00454          zone->next = tz->next;
    00455          if (pz)
    00456             pz->next = zone;
    00457          else
    00458             tone_zones = zone;
    00459          /* if we are replacing the default zone, re-point it */
    00460          if (tz == current_tonezone)
    00461             current_tonezone = zone;
    00462          /* now free the previous zone */
    00463          free_zone(tz);
    00464          ast_mutex_unlock(&tzlock);
    00465          return 0;
    00466       }
    00467    }
    00468    /* country not there, add */
    00469    zone->next = NULL;
    00470    if (pz)
    00471       pz->next = zone;
    00472    else
    00473       tone_zones = zone;
    00474    ast_mutex_unlock(&tzlock);
    00475
    00476    if (option_verbose > 2)
    00477       ast_verbose(VERBOSE_PREFIX_3 "Registered indication country '%s'\n",zone->country);
    00478    return 0;
    00479 }

int ast_set_indication_country | ( | const char * | country | ) |

Definition at line 344 of file indications.c.

References ast_get_indication_zone(), ast_verbose(), option_verbose, and VERBOSE_PREFIX_3.

Referenced by ind_load_module().

    00345 {
    00346    if (country) {
    00347       struct tone_zone *z = ast_get_indication_zone(country);
    00348       if (z) {
    00349          if (option_verbose > 2)
    00350             ast_verbose(VERBOSE_PREFIX_3 "Setting default indication country to '%s'\n",country);
    00351          current_tonezone = z;
    00352          return 0;
    00353       }
    00354    }
    00355    return 1; /* not found */
    00356 }

int ast_unregister_indication | ( | struct tone_zone * | zone,
|  | const char * | indication |
| ) |  |  |

Definition at line 574 of file indications.c.

References tone_zone::alias, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), tone_zone_sound::data, free, LOG_WARNING, tone_zone_sound::name, tone_zone_sound::next, tone_zone::tones, and tzlock.

Referenced by handle_remove_indication().

    00575 {
    00576    struct tone_zone_sound *ts,*ps = NULL, *tmp;
    00577    int res = -1;
    00578
    00579    /* is it an alias? stop */
    00580    if (zone->alias[0])
    00581       return -1;
    00582
    00583    if (ast_mutex_lock(&tzlock)) {
    00584       ast_log(LOG_WARNING, "Unable to lock tone_zones list\n");
    00585       return -1;
    00586    }
    00587    ts = zone->tones;
    00588    while (ts) {
    00589       if (strcasecmp(indication,ts->name)==0) {
    00590          /* indication found */
    00591          tmp = ts->next;
    00592          if (ps)
    00593             ps->next = tmp;
    00594          else
    00595             zone->tones = tmp;
    00596          free((void*)ts->name);
    00597          free((void*)ts->data);
    00598          free(ts);
    00599          ts = tmp;
    00600          res = 0;
    00601       }
    00602       else {
    00603          /* next zone please */
    00604          ps = ts;
    00605          ts = ts->next;
    00606       }
    00607    }
    00608    /* indication not found, goodbye */
    00609    ast_mutex_unlock(&tzlock);
    00610    return res;
    00611 }

int ast_unregister_indication_country | ( | const char * | country | ) |

Definition at line 483 of file indications.c.

References tone_zone::alias, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), tone_zone::country, free_zone(), LOG_NOTICE, LOG_WARNING, tone_zone::next, option_verbose, tzlock, and VERBOSE_PREFIX_3.

Referenced by handle_add_indication(), handle_remove_indication(), reload(), and unload_module().

    00484 {
    00485    struct tone_zone *tz, *pz = NULL, *tmp;
    00486    int res = -1;
    00487
    00488    if (ast_mutex_lock(&tzlock)) {
    00489       ast_log(LOG_WARNING, "Unable to lock tone_zones list\n");
    00490       return -1;
    00491    }
    00492    tz = tone_zones;
    00493    while (tz) {
    00494       if (country==NULL ||
    00495           (strcasecmp(country, tz->country)==0 ||
    00496            strcasecmp(country, tz->alias)==0)) {
    00497          /* tone_zone found, remove */
    00498          tmp = tz->next;
    00499          if (pz)
    00500             pz->next = tmp;
    00501          else
    00502             tone_zones = tmp;
    00503          /* if we are unregistering the default country, w'll notice */
    00504          if (tz == current_tonezone) {
    00505             ast_log(LOG_NOTICE,"Removed default indication country '%s'\n",tz->country);
    00506             current_tonezone = NULL;
    00507          }
    00508          if (option_verbose > 2)
    00509             ast_verbose(VERBOSE_PREFIX_3 "Unregistered indication country '%s'\n",tz->country);
    00510          free_zone(tz);
    00511          if (tone_zones == tz)
    00512             tone_zones = tmp;
    00513          tz = tmp;
    00514          res = 0;
    00515       }
    00516       else {
    00517          /* next zone please */
    00518          pz = tz;
    00519          tz = tz->next;
    00520       }
    00521    }
    00522    ast_mutex_unlock(&tzlock);
    00523    return res;
    00524 }

static void free_zone | ( | struct tone_zone * | zone | ) | `[inline, static]`

Definition at line 426 of file indications.c.

References tone_zone_sound::data, free, tone_zone_sound::name, tone_zone_sound::next, tone_zone::ringcadence, and tone_zone::tones.

Referenced by ast_register_indication_country(), ast_unregister_indication_country(), and load_config().

    00427 {
    00428    while (zone->tones) {
    00429       struct tone_zone_sound *tmp = zone->tones->next;
    00430       free((void*)zone->tones->name);
    00431       free((void*)zone->tones->data);
    00432       free(zone->tones);
    00433       zone->tones = tmp;
    00434    }
    00435    if (zone->ringcadence)
    00436       free((void*)zone->ringcadence);
    00437    free(zone);
    00438 }

static void* playtones_alloc | ( | struct ast_channel * | chan,
|  | void * | params |
| ) |  |  | `[static]`

Definition at line 113 of file indications.c.

References ast_clear_flag, AST_FLAG_WRITE_INT, AST_FORMAT_SLINEAR, ast_log(), ast_set_flag, ast_set_write_format(), playtones_def::interruptible, playtones_def::items, playtones_state::items, LOG_WARNING, malloc, ast_channel::name, playtones_def::nitems, playtones_state::nitems, playtones_state::oldnpos, playtones_state::origwfmt, playtones_release(), playtones_def::reppos, playtones_state::reppos, playtones_def::vol, playtones_state::vol, and ast_channel::writeformat.

    00114 {
    00115    struct playtones_def *pd = params;
    00116    struct playtones_state *ps = malloc(sizeof(struct playtones_state));
    00117    if (!ps)
    00118       return NULL;
    00119    memset(ps, 0, sizeof(struct playtones_state));
    00120    ps->origwfmt = chan->writeformat;
    00121    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
    00122       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
    00123       playtones_release(NULL, ps);
    00124       ps = NULL;
    00125    } else {
    00126       ps->vol = pd->vol;
    00127       ps->reppos = pd->reppos;
    00128       ps->nitems = pd->nitems;
    00129       ps->items = pd->items;
    00130       ps->oldnpos = -1;
    00131    }
    00132    /* Let interrupts interrupt :) */
    00133    if (pd->interruptible)
    00134       ast_set_flag(chan, AST_FLAG_WRITE_INT);
    00135    else
    00136       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
    00137    return ps;
    00138 }

static int playtones_generator | ( | struct ast_channel * | chan,
|  | void * | data,
|  | int | len,
|  | int | samples |
| ) |  |  | `[static]`

Definition at line 140 of file indications.c.

References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_write(), ast_frame::data, playtones_state::data, ast_frame::datalen, ast_frame::delivery, playtones_item::duration, playtones_state::f, playtones_item::fac1, playtones_item::fac2, ast_frame::frametype, playtones_item::init_v2_1, playtones_item::init_v2_2, playtones_item::init_v3_1, playtones_item::init_v3_2, playtones_state::items, LOG_WARNING, playtones_item::modulate, playtones_state::nitems, playtones_state::npos, ast_frame::offset, playtones_state::oldnpos, playtones_state::pos, playtones_state::reppos, ast_frame::samples, ast_frame::subclass, playtones_state::v1_1, playtones_state::v1_2, playtones_state::v2_1, playtones_state::v2_2, playtones_state::v3_1, and playtones_state::v3_2.

    00141 {
    00142    struct playtones_state *ps = data;
    00143    struct playtones_item *pi;
    00144    int x;
    00145    /* we need to prepare a frame with 16 * timelen samples as we're
    00146     * generating SLIN audio
    00147     */
    00148    len = samples * 2;
    00149    if (len > sizeof(ps->data) / 2 - 1) {
    00150       ast_log(LOG_WARNING, "Can't generate that much data!\n");
    00151       return -1;
    00152    }
    00153    memset(&ps->f, 0, sizeof(ps->f));
    00154
    00155    pi = &ps->items[ps->npos];
    00156    if (ps->oldnpos != ps->npos) {
    00157       /* Load new parameters */
    00158       ps->v1_1 = 0;
    00159       ps->v2_1 = pi->init_v2_1;
    00160       ps->v3_1 = pi->init_v3_1;
    00161       ps->v1_2 = 0;
    00162       ps->v2_2 = pi->init_v2_2;
    00163       ps->v3_2 = pi->init_v3_2;
    00164       ps->oldnpos = ps->npos;
    00165    }
    00166    for (x=0;x<len/2;x++) {
    00167       ps->v1_1 = ps->v2_1;
    00168       ps->v2_1 = ps->v3_1;
    00169       ps->v3_1 = (pi->fac1 * ps->v2_1 >> 15) - ps->v1_1;
    00170
    00171       ps->v1_2 = ps->v2_2;
    00172       ps->v2_2 = ps->v3_2;
    00173       ps->v3_2 = (pi->fac2 * ps->v2_2 >> 15) - ps->v1_2;
    00174       if (pi->modulate) {
    00175          int p;
    00176          p = ps->v3_2 - 32768;
    00177          if (p < 0) p = -p;
    00178          p = ((p * 9) / 10) + 1;
    00179          ps->data[x] = (ps->v3_1 * p) >> 15;
    00180       } else
    00181          ps->data[x] = ps->v3_1 + ps->v3_2;
    00182    }
    00183
    00184    ps->f.frametype = AST_FRAME_VOICE;
    00185    ps->f.subclass = AST_FORMAT_SLINEAR;
    00186    ps->f.datalen = len;
    00187    ps->f.samples = samples;
    00188    ps->f.offset = AST_FRIENDLY_OFFSET;
    00189    ps->f.data = ps->data;
    00190    ps->f.delivery.tv_sec = 0;
    00191    ps->f.delivery.tv_usec = 0;
    00192    ast_write(chan, &ps->f);
    00193
    00194    ps->pos += x;
    00195    if (pi->duration && ps->pos >= pi->duration * 8) { /* item finished? */
    00196       ps->pos = 0;               /* start new item */
    00197       ps->npos++;
    00198       if (ps->npos >= ps->nitems) {       /* last item? */
    00199          if (ps->reppos == -1)         /* repeat set? */
    00200             return -1;
    00201          ps->npos = ps->reppos;        /* redo from top */
    00202       }
    00203    }
    00204    return 0;
    00205 }

static void playtones_release | ( | struct ast_channel * | chan,
|  | void * | params |
| ) |  |  | `[static]`

Definition at line 103 of file indications.c.

References ast_set_write_format(), free, playtones_state::items, and playtones_state::origwfmt.

Referenced by playtones_alloc().

    00104 {
    00105    struct playtones_state *ps = params;
    00106    if (chan) {
    00107       ast_set_write_format(chan, ps->origwfmt);
    00108    }
    00109    if (ps->items) free(ps->items);
    00110    free(ps);
    00111 }

## Variable Documentation

struct tone_zone* current_tonezone`[static]`

Definition at line 337 of file indications.c.

int midi_tohz[128]`[static]`

Definition at line 48 of file indications.c.

struct ast_generator playtones`[static]`

Initial value:

     {
       alloc: playtones_alloc,
       release: playtones_release,
       generate: playtones_generator,
    }

Definition at line 207 of file indications.c.

struct tone_zone* tone_zones

Definition at line 336 of file indications.c.

Referenced by handle_show_indications().