Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:34 2007

Asterisk developer's documentation :: Codename Pineapple


indications.c File Reference


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.

#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "asterisk/lock.h"
#include "asterisk/linkedlists.h"
#include "asterisk/indications.h"
#include "asterisk/frame.h"
#include "asterisk/options.h"
#include "asterisk/channel.h"
#include "asterisk/logger.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

ind_tone_zone_soundast_get_indication_tone (const struct ind_tone_zone *zone, const char *indication)
 locate a tone_zone_sound, given the tone_zone. if tone_zone == NULL, use the default tone_zone
ind_tone_zoneast_get_indication_zone (const char *country)
 locate tone_zone, given the country. if country == NULL, use the default country
int ast_playtones_start (struct ast_channel *chan, int vol, const char *playlst, int interruptible)
 Start a tone-list going.
void ast_playtones_stop (struct ast_channel *chan)
 Stop the tones from playing.
int ast_register_indication (struct ind_tone_zone *zone, const char *indication, const char *tonelist)
 add a new indication to a tone_zone. tone_zone must exist. if the indication already exists, it will be replaced.
int ast_register_indication_country (struct ind_tone_zone *zone)
 add a new country, if country exists, it will be replaced.
static AST_RWLIST_HEAD_STATIC (tone_zones, ind_tone_zone)
int ast_set_indication_country (const char *country)
 set the default tone country
int ast_unregister_indication (struct ind_tone_zone *zone, const char *indication)
 remove an existing tone_zone's indication. tone_zone must exist
int ast_unregister_indication_country (const char *country)
 remove an existing country and all its indications, country must exist
ind_tone_zoneast_walk_indications (const struct ind_tone_zone *cur)
 support for walking through a list of indications
static void free_zone (struct ind_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 ind_tone_zonecurrent_tonezone
static int midi_tohz [128]
static struct ast_generator playtones


Function Documentation

struct ind_tone_zone_sound* ast_get_indication_tone const struct ind_tone_zone zone,
const char *  indication
 

locate a tone_zone_sound, given the tone_zone. if tone_zone == NULL, use the default tone_zone

Definition at line 423 of file indications.c.

References AST_LIST_FIRST, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, current_tonezone, ind_tone_zone_sound::name, ind_tone_zone_sound::next, and ind_tone_zone::tones.

Referenced by ast_app_dtget(), ast_indicate_data(), dialtone_indicate(), and handle_playtones().

00424 {
00425    struct ind_tone_zone_sound *ts = NULL;
00426 
00427    AST_RWLIST_RDLOCK(&tone_zones);
00428 
00429    /* If no zone is already specified we need to try to pick one */
00430    if (!zone) {
00431       if (current_tonezone) {
00432          zone = current_tonezone;
00433       } else if (!(zone = AST_LIST_FIRST(&tone_zones))) {
00434          /* No zone has been found ;( */
00435          AST_RWLIST_UNLOCK(&tone_zones);
00436          return NULL;
00437       }
00438    }
00439 
00440    /* Look through list of tones in the zone searching for the right one */
00441    for (ts = zone->tones; ts; ts = ts->next) {
00442       if (!strcasecmp(ts->name, indication))
00443          break;
00444    }
00445 
00446    AST_RWLIST_UNLOCK(&tone_zones);
00447 
00448    return ts;
00449 }

struct ind_tone_zone* ast_get_indication_zone const char *  country  ) 
 

locate tone_zone, given the country. if country == NULL, use the default country

Definition at line 385 of file indications.c.

References ind_tone_zone::alias, AST_LIST_FIRST, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ind_tone_zone::country, current_tonezone, and LOG_NOTICE.

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

00386 {
00387    struct ind_tone_zone *tz = NULL;
00388    int alias_loop = 0;
00389 
00390    AST_RWLIST_RDLOCK(&tone_zones);
00391 
00392    if (!country) {
00393       if (current_tonezone)
00394          tz = current_tonezone;
00395       else
00396          tz = AST_LIST_FIRST(&tone_zones);
00397    } else {
00398       do {
00399          AST_RWLIST_TRAVERSE(&tone_zones, tz, list) {
00400             if (!strcasecmp(tz->country, country))
00401                break;
00402          }
00403          if (!tz)
00404             break;
00405          /* If this is an alias then we have to search yet again otherwise we have found the zonezone */
00406          if (tz->alias && tz->alias[0])
00407             country = tz->alias;
00408          else
00409             break;
00410       } while ((++alias_loop < 20) && tz);
00411    }
00412 
00413    AST_RWLIST_UNLOCK(&tone_zones);
00414 
00415    /* If we reached the maximum loops to find the proper country via alias, print out a notice */
00416    if (alias_loop == 20)
00417       ast_log(LOG_NOTICE, "Alias loop for '%s' is bonkers\n", country);
00418 
00419    return tz;
00420 }

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

Start a tone-list going.

Definition at line 220 of file indications.c.

References ast_activate_generator(), ast_log(), ast_realloc, 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, midi_tohz, playtones_item::modulate, playtones_def::nitems, playtones, playtones_def::reppos, s, strsep(), and playtones_def::vol.

Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_begin(), dialtone_indicate(), handle_playtones(), and send_digit_to_chan().

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

void ast_playtones_stop struct ast_channel chan  ) 
 

Stop the tones from playing.

Definition at line 333 of file indications.c.

References ast_deactivate_generator().

Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_end(), handle_stopplaytones(), and stop_indicate().

00334 {
00335    ast_deactivate_generator(chan);
00336 }

int ast_register_indication struct ind_tone_zone zone,
const char *  indication,
const char *  tonelist
 

add a new indication to a tone_zone. tone_zone must exist. if the indication already exists, it will be replaced.

Definition at line 534 of file indications.c.

References ind_tone_zone::alias, ast_malloc, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ind_tone_zone_sound::data, free, ind_tone_zone_sound::name, ind_tone_zone_sound::next, and ind_tone_zone::tones.

Referenced by handle_add_indication().

00535 {
00536    struct ind_tone_zone_sound *ts, *ps;
00537 
00538    /* is it an alias? stop */
00539    if (zone->alias[0])
00540       return -1;
00541 
00542    AST_RWLIST_WRLOCK(&tone_zones);
00543    for (ps=NULL,ts=zone->tones; ts; ps=ts,ts=ts->next) {
00544       if (strcasecmp(indication,ts->name)==0) {
00545          /* indication already there, replace */
00546          free((void*)ts->name);
00547          free((void*)ts->data);
00548          break;
00549       }
00550    }
00551    if (!ts) {
00552       /* not there, we have to add */
00553       if (!(ts = ast_malloc(sizeof(*ts)))) {
00554          AST_RWLIST_UNLOCK(&tone_zones);
00555          return -2;
00556       }
00557       ts->next = NULL;
00558    }
00559    if (!(ts->name = ast_strdup(indication)) || !(ts->data = ast_strdup(tonelist))) {
00560       AST_RWLIST_UNLOCK(&tone_zones);
00561       return -2;
00562    }
00563    if (ps)
00564       ps->next = ts;
00565    else
00566       zone->tones = ts;
00567    AST_RWLIST_UNLOCK(&tone_zones);
00568    return 0;
00569 }

int ast_register_indication_country struct ind_tone_zone zone  ) 
 

add a new country, if country exists, it will be replaced.

Definition at line 471 of file indications.c.

References AST_RWLIST_INSERT_TAIL, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verbose(), ind_tone_zone::country, current_tonezone, free_zone(), option_verbose, and VERBOSE_PREFIX_3.

Referenced by handle_add_indication(), and ind_load_module().

00472 {
00473    struct ind_tone_zone *tz = NULL;
00474 
00475    AST_RWLIST_WRLOCK(&tone_zones);
00476    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&tone_zones, tz, list) {
00477       /* If this is not the same zone, then just continue to the next entry */
00478       if (strcasecmp(zone->country, tz->country))
00479          continue;
00480       /* If this zone we are going to remove is the current default then make the new zone the default */
00481       if (tz == current_tonezone)
00482          current_tonezone = zone;
00483       /* Remove from the linked list */
00484       AST_RWLIST_REMOVE_CURRENT(&tone_zones, list);
00485       /* Finally free the zone itself */
00486       free_zone(tz);
00487       break;
00488    }
00489    AST_RWLIST_TRAVERSE_SAFE_END
00490 
00491    /* Add zone to the list */
00492    AST_RWLIST_INSERT_TAIL(&tone_zones, zone, list);
00493 
00494    /* It's all over. */
00495    AST_RWLIST_UNLOCK(&tone_zones);
00496 
00497    if (option_verbose > 2)
00498       ast_verbose(VERBOSE_PREFIX_3 "Registered indication country '%s'\n", zone->country);
00499 
00500    return 0;
00501 }

static AST_RWLIST_HEAD_STATIC tone_zones  ,
ind_tone_zone 
[static]
 

int ast_set_indication_country const char *  country  ) 
 

set the default tone country

Definition at line 364 of file indications.c.

References ast_get_indication_zone(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verbose(), current_tonezone, option_verbose, and VERBOSE_PREFIX_3.

Referenced by ind_load_module().

00365 {
00366    struct ind_tone_zone *zone = NULL;
00367 
00368    /* If no country is specified or we are unable to find the zone, then return not found */
00369    if (!country || !(zone = ast_get_indication_zone(country)))
00370       return 1;
00371    
00372    if (option_verbose > 2)
00373       ast_verbose(VERBOSE_PREFIX_3 "Setting default indication country to '%s'\n", country);
00374 
00375    /* Protect the current tonezone using the tone_zones lock as well */
00376    AST_RWLIST_WRLOCK(&tone_zones);
00377    current_tonezone = zone;
00378    AST_RWLIST_UNLOCK(&tone_zones);
00379 
00380    /* Zone was found */
00381    return 0;
00382 }

int ast_unregister_indication struct ind_tone_zone zone,
const char *  indication
 

remove an existing tone_zone's indication. tone_zone must exist

Definition at line 572 of file indications.c.

References ind_tone_zone::alias, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ind_tone_zone_sound::data, free, ind_tone_zone_sound::name, ind_tone_zone_sound::next, and ind_tone_zone::tones.

Referenced by handle_remove_indication().

00573 {
00574    struct ind_tone_zone_sound *ts,*ps = NULL, *tmp;
00575    int res = -1;
00576 
00577    /* is it an alias? stop */
00578    if (zone->alias[0])
00579       return -1;
00580 
00581    AST_RWLIST_WRLOCK(&tone_zones);
00582    ts = zone->tones;
00583    while (ts) {
00584       if (strcasecmp(indication,ts->name)==0) {
00585          /* indication found */
00586          tmp = ts->next;
00587          if (ps)
00588             ps->next = tmp;
00589          else
00590             zone->tones = tmp;
00591          free((void*)ts->name);
00592          free((void*)ts->data);
00593          free(ts);
00594          ts = tmp;
00595          res = 0;
00596       }
00597       else {
00598          /* next zone please */
00599          ps = ts;
00600          ts = ts->next;
00601       }
00602    }
00603    /* indication not found, goodbye */
00604    AST_RWLIST_UNLOCK(&tone_zones);
00605    return res;
00606 }

int ast_unregister_indication_country const char *  country  ) 
 

remove an existing country and all its indications, country must exist

Definition at line 505 of file indications.c.

References ind_tone_zone::alias, ast_log(), AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verbose(), ind_tone_zone::country, current_tonezone, free_zone(), LOG_NOTICE, option_verbose, and VERBOSE_PREFIX_3.

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

00506 {
00507    struct ind_tone_zone *tz = NULL;
00508    int res = -1;
00509 
00510    AST_RWLIST_WRLOCK(&tone_zones);
00511    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&tone_zones, tz, list) {
00512       if (country && (strcasecmp(country, tz->country) && strcasecmp(country, tz->alias)))
00513          continue;
00514       /* If this tonezone is the current default then unset it */
00515       if (tz == current_tonezone) {
00516          ast_log(LOG_NOTICE,"Removed default indication country '%s'\n", tz->country);
00517          current_tonezone = NULL;
00518       }
00519       /* Remove from the list */
00520       AST_RWLIST_REMOVE_CURRENT(&tone_zones, list);
00521       if (option_verbose > 2)
00522          ast_verbose(VERBOSE_PREFIX_3 "Unregistered indication country '%s'\n", tz->country);
00523       free_zone(tz);
00524       res = 0;
00525    }
00526    AST_RWLIST_TRAVERSE_SAFE_END
00527    AST_RWLIST_UNLOCK(&tone_zones);
00528 
00529    return res;
00530 }

struct ind_tone_zone* ast_walk_indications const struct ind_tone_zone cur  ) 
 

support for walking through a list of indications

Definition at line 343 of file indications.c.

References AST_RWLIST_FIRST, AST_RWLIST_NEXT, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, and AST_RWLIST_UNLOCK.

Referenced by handle_show_indications().

00344 {
00345    struct ind_tone_zone *tz = NULL;
00346 
00347    AST_RWLIST_RDLOCK(&tone_zones);
00348    /* If cur is not NULL, then we have to iterate through - otherwise just return the first entry */
00349    if (cur) {
00350       AST_RWLIST_TRAVERSE(&tone_zones, tz, list) {
00351          if (tz == cur)
00352             break;
00353       }
00354       tz = AST_RWLIST_NEXT(tz, list);
00355    } else {
00356       tz = AST_RWLIST_FIRST(&tone_zones);
00357    }
00358    AST_RWLIST_UNLOCK(&tone_zones);
00359 
00360    return tz;
00361 }

static void free_zone struct ind_tone_zone zone  )  [inline, static]
 

Definition at line 452 of file indications.c.

References ind_tone_zone_sound::data, free, ind_tone_zone_sound::name, ind_tone_zone_sound::next, ind_tone_zone::ringcadence, and ind_tone_zone::tones.

Referenced by ast_register_indication_country(), and ast_unregister_indication_country().

00453 {
00454    while (zone->tones) {
00455       struct ind_tone_zone_sound *tmp = zone->tones->next;
00456       free((void*)zone->tones->name);
00457       free((void*)zone->tones->data);
00458       free(zone->tones);
00459       zone->tones = tmp;
00460    }
00461 
00462    if (zone->ringcadence)
00463       free(zone->ringcadence);
00464 
00465    free(zone);
00466 }

static void* playtones_alloc struct ast_channel chan,
void *  params
[static]
 

Definition at line 116 of file indications.c.

References ast_calloc, 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, LOG_WARNING, playtones_def::nitems, playtones_release(), playtones_def::reppos, playtones_def::vol, and ast_channel::writeformat.

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

static int playtones_generator struct ast_channel chan,
void *  data,
int  len,
int  samples
[static]
 

Definition at line 147 of file indications.c.

References ast_log(), playtones_state::data, playtones_state::f, playtones_item::fac1, playtones_item::fac2, 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::npos, playtones_state::oldnpos, 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.

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

static void playtones_release struct ast_channel chan,
void *  params
[static]
 

Definition at line 104 of file indications.c.

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

Referenced by playtones_alloc().

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


Variable Documentation

struct ind_tone_zone* current_tonezone [static]
 

Definition at line 341 of file indications.c.

Referenced by ast_get_indication_tone(), ast_get_indication_zone(), ast_register_indication_country(), ast_set_indication_country(), and ast_unregister_indication_country().

int midi_tohz[128] [static]
 

Definition at line 49 of file indications.c.

Referenced by ast_playtones_start().

struct ast_generator playtones [static]
 

Initial value:

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

Definition at line 214 of file indications.c.

Referenced by ast_playtones_start().


Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen