#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_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 | |
tone_zone * | ast_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_zone * | ast_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_zone * | current_tonezone |
static int | midi_tohz [128] |
static struct ast_generator | playtones |
Definition in file indications.c.
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(), milliwatt_exec(), 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, "%30d+%30d/%30d", &freq1, &freq2, &duration) == 3) { 00243 /* f1+f2/time format */ 00244 } else if (sscanf(s, "%30d+%30d", &freq1, &freq2) == 2) { 00245 /* f1+f2 format */ 00246 duration = 0; 00247 } else if (sscanf(s, "%30d*%30d/%30d", &freq1, &freq2, &duration) == 3) { 00248 /* f1*f2/time format */ 00249 modulate = 1; 00250 } else if (sscanf(s, "%30d*%30d", &freq1, &freq2) == 2) { 00251 /* f1*f2 format */ 00252 duration = 0; 00253 modulate = 1; 00254 } else if (sscanf(s, "%30d/%30d", &freq1, &duration) == 2) { 00255 /* f1/time format */ 00256 freq2 = 0; 00257 } else if (sscanf(s, "%30d", &freq1) == 1) { 00258 /* f1 format */ 00259 freq2 = 0; 00260 duration = 0; 00261 } else if (sscanf(s, "M%30d+M%30d/%30d", &freq1, &freq2, &duration) == 3) { 00262 /* Mf1+Mf2/time format */ 00263 midinote = 1; 00264 } else if (sscanf(s, "M%30d+M%30d", &freq1, &freq2) == 2) { 00265 /* Mf1+Mf2 format */ 00266 duration = 0; 00267 midinote = 1; 00268 } else if (sscanf(s, "M%30d*M%30d/%30d", &freq1, &freq2, &duration) == 3) { 00269 /* Mf1*Mf2/time format */ 00270 modulate = 1; 00271 midinote = 1; 00272 } else if (sscanf(s, "M%30d*M%30d", &freq1, &freq2) == 2) { 00273 /* Mf1*Mf2 format */ 00274 duration = 0; 00275 modulate = 1; 00276 midinote = 1; 00277 } else if (sscanf(s, "M%30d/%30d", &freq1, &duration) == 2) { 00278 /* Mf1/time format */ 00279 freq2 = -1; 00280 midinote = 1; 00281 } else if (sscanf(s, "M%30d", &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 }
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 }
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().