Fri Jun 19 12:10:38 2009

Asterisk developer's documentation


indications.c File Reference

Tone Management. More...

#include "asterisk.h"
#include <math.h>
#include "asterisk/lock.h"
#include "asterisk/linkedlists.h"
#include "asterisk/indications.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/utils.h"

Go to the source code of this file.

Data Structures

struct  playtones_def
struct  playtones_item
struct  playtones_state
struct  tone_zones

Functions

tone_zone_soundast_get_indication_tone (const struct tone_zone *zone, const char *indication)
 locate a tone_zone_sound, given the tone_zone. if tone_zone == NULL, use the default tone_zone
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 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 tone_zone *zone)
 add a new country, if country exists, it will be replaced.
int ast_set_indication_country (const char *country)
 set the default tone country
int ast_unregister_indication (struct 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
tone_zoneast_walk_indications (const struct tone_zone *cur)
 support for walking through a list of indications
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_zonecurrent_tonezone
static int midi_tohz [128]
static struct ast_generator playtones


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 
)

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

Definition at line 414 of file indications.c.

References AST_LIST_FIRST, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, current_tonezone, tone_zone_sound::name, tone_zone_sound::next, and tone_zone::tones.

Referenced by ast_app_dtget(), ast_indicate_data(), dialtone_indicate(), handle_playtones(), in_band_indication(), pbx_builtin_waitexten(), play_dialtone(), read_exec(), readexten_exec(), and skinny_transfer().

00415 {
00416    struct tone_zone_sound *ts = NULL;
00417 
00418    AST_RWLIST_RDLOCK(&tone_zones);
00419 
00420    /* If no zone is already specified we need to try to pick one */
00421    if (!zone) {
00422       if (current_tonezone) {
00423          zone = current_tonezone;
00424       } else if (!(zone = AST_LIST_FIRST(&tone_zones))) {
00425          /* No zone has been found ;( */
00426          AST_RWLIST_UNLOCK(&tone_zones);
00427          return NULL;
00428       }
00429    }
00430 
00431    /* Look through list of tones in the zone searching for the right one */
00432    for (ts = zone->tones; ts; ts = ts->next) {
00433       if (!strcasecmp(ts->name, indication))
00434          break;
00435    }
00436 
00437    AST_RWLIST_UNLOCK(&tone_zones);
00438 
00439    return ts;
00440 }

struct 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 379 of file indications.c.

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

Referenced by ast_set_indication_country(), build_device(), func_channel_write(), handle_cli_indication_add(), and handle_cli_indication_remove().

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

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

Start a tone-list going.

Definition at line 215 of file indications.c.

References ast_activate_generator(), ast_free, ast_log(), ast_realloc, ast_strdupa, chan, cos, playtones_item::duration, 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_def::interruptible, playtones_def::items, LOG_WARNING, playtones_item::modulate, ast_channel::name, 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(), do_dtmf_local(), handle_playtones(), in_band_indication(), pbx_builtin_waitexten(), play_dialtone(), playtone(), read_exec(), readexten_exec(), send_digit_to_chan(), and skinny_transfer().

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

void ast_playtones_stop ( struct ast_channel chan  ) 

Stop the tones from playing.

Stop the tones from playing

Definition at line 328 of file indications.c.

References ast_deactivate_generator(), and chan.

Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_end(), disa_exec(), handle_stopplaytones(), pbx_builtin_waitexten(), playtone(), read_exec(), readexten_exec(), stop_indicate(), and unistim_indicate().

00329 {
00330    ast_deactivate_generator(chan);
00331 }

int ast_register_indication ( struct 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 523 of file indications.c.

References tone_zone::alias, ast_free, ast_malloc, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, tone_zone_sound::data, tone_zone_sound::name, tone_zone_sound::next, ps, and tone_zone::tones.

Referenced by handle_cli_indication_add().

00524 {
00525    struct tone_zone_sound *ts, *ps;
00526 
00527    /* is it an alias? stop */
00528    if (zone->alias[0])
00529       return -1;
00530 
00531    AST_RWLIST_WRLOCK(&tone_zones);
00532    for (ps=NULL,ts=zone->tones; ts; ps=ts,ts=ts->next) {
00533       if (!strcasecmp(indication,ts->name)) {
00534          /* indication already there, replace */
00535          ast_free((void*)ts->name);
00536          ast_free((void*)ts->data);
00537          break;
00538       }
00539    }
00540    if (!ts) {
00541       /* not there, we have to add */
00542       if (!(ts = ast_malloc(sizeof(*ts)))) {
00543          AST_RWLIST_UNLOCK(&tone_zones);
00544          return -2;
00545       }
00546       ts->next = NULL;
00547    }
00548    if (!(ts->name = ast_strdup(indication)) || !(ts->data = ast_strdup(tonelist))) {
00549       AST_RWLIST_UNLOCK(&tone_zones);
00550       return -2;
00551    }
00552    if (ps)
00553       ps->next = ts;
00554    else
00555       zone->tones = ts;
00556    AST_RWLIST_UNLOCK(&tone_zones);
00557    return 0;
00558 }

int ast_register_indication_country ( struct tone_zone zone  ) 

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

Definition at line 462 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_verb, tone_zone::country, current_tonezone, and free_zone().

Referenced by handle_cli_indication_add(), and ind_load_module().

00463 {
00464    struct tone_zone *tz = NULL;
00465 
00466    AST_RWLIST_WRLOCK(&tone_zones);
00467    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&tone_zones, tz, list) {
00468       /* If this is not the same zone, then just continue to the next entry */
00469       if (strcasecmp(zone->country, tz->country))
00470          continue;
00471       /* If this zone we are going to remove is the current default then make the new zone the default */
00472       if (tz == current_tonezone)
00473          current_tonezone = zone;
00474       /* Remove from the linked list */
00475       AST_RWLIST_REMOVE_CURRENT(list);
00476       /* Finally free the zone itself */
00477       free_zone(tz);
00478       break;
00479    }
00480    AST_RWLIST_TRAVERSE_SAFE_END;
00481 
00482    /* Add zone to the list */
00483    AST_RWLIST_INSERT_TAIL(&tone_zones, zone, list);
00484 
00485    /* It's all over. */
00486    AST_RWLIST_UNLOCK(&tone_zones);
00487 
00488    ast_verb(3, "Registered indication country '%s'\n", zone->country);
00489 
00490    return 0;
00491 }

int ast_set_indication_country ( const char *  country  ) 

set the default tone country

Definition at line 359 of file indications.c.

References ast_get_indication_zone(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, and current_tonezone.

Referenced by ind_load_module().

00360 {
00361    struct tone_zone *zone = NULL;
00362 
00363    /* If no country is specified or we are unable to find the zone, then return not found */
00364    if (!country || !(zone = ast_get_indication_zone(country)))
00365       return 1;
00366    
00367    ast_verb(3, "Setting default indication country to '%s'\n", country);
00368 
00369    /* Protect the current tonezone using the tone_zones lock as well */
00370    AST_RWLIST_WRLOCK(&tone_zones);
00371    current_tonezone = zone;
00372    AST_RWLIST_UNLOCK(&tone_zones);
00373 
00374    /* Zone was found */
00375    return 0;
00376 }

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

remove an existing tone_zone's indication. tone_zone must exist

Definition at line 561 of file indications.c.

References tone_zone::alias, ast_free, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, tone_zone_sound::data, tone_zone_sound::name, tone_zone_sound::next, ps, and tone_zone::tones.

Referenced by handle_cli_indication_remove().

00562 {
00563    struct tone_zone_sound *ts,*ps = NULL, *tmp;
00564    int res = -1;
00565 
00566    /* is it an alias? stop */
00567    if (zone->alias[0])
00568       return -1;
00569 
00570    AST_RWLIST_WRLOCK(&tone_zones);
00571    ts = zone->tones;
00572    while (ts) {
00573       if (!strcasecmp(indication,ts->name)) {
00574          /* indication found */
00575          tmp = ts->next;
00576          if (ps)
00577             ps->next = tmp;
00578          else
00579             zone->tones = tmp;
00580          ast_free((void*)ts->name);
00581          ast_free((void*)ts->data);
00582          ast_free(ts);
00583          ts = tmp;
00584          res = 0;
00585       }
00586       else {
00587          /* next zone please */
00588          ps = ts;
00589          ts = ts->next;
00590       }
00591    }
00592    /* indication not found, goodbye */
00593    AST_RWLIST_UNLOCK(&tone_zones);
00594    return res;
00595 }

int ast_unregister_indication_country ( const char *  country  ) 

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

Definition at line 495 of file indications.c.

References 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_verb, tone_zone::country, current_tonezone, free_zone(), and LOG_NOTICE.

Referenced by handle_cli_indication_add(), handle_cli_indication_remove(), ind_load_module(), and unload_module().

00496 {
00497    struct tone_zone *tz = NULL;
00498    int res = -1;
00499 
00500    AST_RWLIST_WRLOCK(&tone_zones);
00501    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&tone_zones, tz, list) {
00502       if (country && (strcasecmp(country, tz->country) && strcasecmp(country, tz->alias)))
00503          continue;
00504       /* If this tonezone is the current default then unset it */
00505       if (tz == current_tonezone) {
00506          ast_log(LOG_NOTICE,"Removed default indication country '%s'\n", tz->country);
00507          current_tonezone = NULL;
00508       }
00509       /* Remove from the list */
00510       AST_RWLIST_REMOVE_CURRENT(list);
00511       ast_verb(3, "Unregistered indication country '%s'\n", tz->country);
00512       free_zone(tz);
00513       res = 0;
00514    }
00515    AST_RWLIST_TRAVERSE_SAFE_END;
00516    AST_RWLIST_UNLOCK(&tone_zones);
00517 
00518    return res;
00519 }

struct tone_zone* ast_walk_indications ( const struct tone_zone cur  ) 

support for walking through a list of indications

Definition at line 338 of file indications.c.

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

Referenced by handle_cli_indication_show().

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

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

Definition at line 443 of file indications.c.

References ast_free, tone_zone_sound::data, 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(), free_vm_zones(), ind_load_module(), and timezone_destroy_list().

00444 {
00445    while (zone->tones) {
00446       struct tone_zone_sound *tmp = zone->tones->next;
00447       ast_free((void *)zone->tones->name);
00448       ast_free((void *)zone->tones->data);
00449       ast_free(zone->tones);
00450       zone->tones = tmp;
00451    }
00452 
00453    if (zone->ringcadence)
00454       ast_free(zone->ringcadence);
00455 
00456    ast_free(zone);
00457 }

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

Definition at line 111 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(), chan, LOG_WARNING, ast_channel::name, pd, playtones_release(), ps, and ast_channel::writeformat.

00112 {
00113    struct playtones_def *pd = params;
00114    struct playtones_state *ps = NULL;
00115 
00116    if (!(ps = ast_calloc(1, sizeof(*ps))))
00117       return NULL;
00118 
00119    ps->origwfmt = chan->writeformat;
00120 
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 
00133    /* Let interrupts interrupt :) */
00134    if (pd->interruptible)
00135       ast_set_flag(chan, AST_FLAG_WRITE_INT);
00136    else
00137       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
00138 
00139    return ps;
00140 }

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

Definition at line 142 of file indications.c.

References ast_log(), 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, LOG_WARNING, playtones_item::modulate, and ps.

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

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

Definition at line 99 of file indications.c.

References ast_free, ast_set_write_format(), chan, and ps.

Referenced by playtones_alloc().

00100 {
00101    struct playtones_state *ps = params;
00102 
00103    if (chan)
00104       ast_set_write_format(chan, ps->origwfmt);
00105    if (ps->items)
00106       ast_free(ps->items);
00107 
00108    ast_free(ps);
00109 }


Variable Documentation

struct tone_zone* current_tonezone [static]

Definition at line 336 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 44 of file indications.c.

struct ast_generator playtones [static]

Initial value:

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

Definition at line 209 of file indications.c.

Referenced by ast_playtones_start().


Generated on Fri Jun 19 12:10:38 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7