Wed Jan 8 2020 09:49:57

Asterisk developer's documentation


app_waitforsilence.c File Reference

Wait for Silence. More...

#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/dsp.h"
#include "asterisk/module.h"

Go to the source code of this file.

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int do_waiting (struct ast_channel *chan, int timereqd, time_t waitstart, int timeout, int wait_for_silence)
 
static int load_module (void)
 
static int unload_module (void)
 
static int waitfor_exec (struct ast_channel *chan, const char *data, int wait_for_silence)
 
static int waitfornoise_exec (struct ast_channel *chan, const char *data)
 
static int waitforsilence_exec (struct ast_channel *chan, const char *data)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Wait For Silence" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
 
static char * app_noise = "WaitForNoise"
 
static char * app_silence = "WaitForSilence"
 
static struct ast_module_infoast_module_info = &__mod_info
 

Detailed Description

Wait for Silence.

  • Waits for up to 'x' milliseconds of silence, 'y' times
  • WaitForSilence(500,2) will wait for 1/2 second of silence, twice
  • WaitForSilence(1000,1) will wait for 1 second of silence, once
  • WaitForSilence(300,3,10) will wait for 300ms of silence, 3 times, and return after 10sec
    Author
    David C. Troy dave@.nosp@m.popv.nosp@m.ox.co.nosp@m.m
    Wait For Noise The same as Wait For Silence but listenes noise on the chennel that is above
    the pre-configured silence threshold from dsp.conf
Author
Philipp Skadorov skado.nosp@m.rov@.nosp@m.yahoo.nosp@m..com

Definition in file app_waitforsilence.c.

Function Documentation

static void __reg_module ( void  )
static

Definition at line 276 of file app_waitforsilence.c.

static void __unreg_module ( void  )
static

Definition at line 276 of file app_waitforsilence.c.

static int do_waiting ( struct ast_channel chan,
int  timereqd,
time_t  waitstart,
int  timeout,
int  wait_for_silence 
)
static

Definition at line 129 of file app_waitforsilence.c.

References ast_debug, ast_dsp_free(), ast_dsp_get_threshold_from_settings(), ast_dsp_new(), ast_dsp_noise(), ast_dsp_set_threshold(), ast_dsp_silence(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_frfree, ast_getformatname(), ast_log(), ast_read(), ast_set_read_format(), ast_verb, ast_waitfor(), f, ast_frame::frametype, LOG_WARNING, ast_channel::name, pbx_builtin_setvar_helper(), ast_channel::readformat, and THRESHOLD_SILENCE.

Referenced by waitfor_exec().

129  {
130  struct ast_frame *f = NULL;
131  int dsptime = 0;
132  int rfmt = 0;
133  int res = 0;
134  struct ast_dsp *sildet; /* silence detector dsp */
135  time_t now;
136 
137  /*Either silence or noise calc depending on wait_for_silence flag*/
138  int (*ast_dsp_func)(struct ast_dsp*, struct ast_frame*, int*) =
139  wait_for_silence ? ast_dsp_silence : ast_dsp_noise;
140 
141  rfmt = chan->readformat; /* Set to linear mode */
142  if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)) < 0) {
143  ast_log(LOG_WARNING, "Unable to set channel to linear mode, giving up\n");
144  return -1;
145  }
146 
147  /* Create the silence detector */
148  if (!(sildet = ast_dsp_new())) {
149  ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
150  return -1;
151  }
153 
154  /* Await silence... */
155  for (;;) {
156  /* Start with no silence received */
157  dsptime = 0;
158 
159  res = ast_waitfor(chan, timereqd);
160 
161  /* Must have gotten a hangup; let's exit */
162  if (res < 0) {
163  pbx_builtin_setvar_helper(chan, "WAITSTATUS", "HANGUP");
164  break;
165  }
166 
167  /* We waited and got no frame; sounds like digital silence or a muted digital channel */
168  if (res == 0) {
169  dsptime = timereqd;
170  } else {
171  /* Looks like we did get a frame, so let's check it out */
172  if (!(f = ast_read(chan))) {
173  pbx_builtin_setvar_helper(chan, "WAITSTATUS", "HANGUP");
174  break;
175  }
176  if (f->frametype == AST_FRAME_VOICE) {
177  ast_dsp_func(sildet, f, &dsptime);
178  }
179  ast_frfree(f);
180  }
181 
182  ast_verb(6, "Got %dms %s < %dms required\n", dsptime, wait_for_silence ? "silence" : "noise", timereqd);
183 
184  if (dsptime >= timereqd) {
185  ast_verb(3, "Exiting with %dms %s >= %dms required\n", dsptime, wait_for_silence ? "silence" : "noise", timereqd);
186  /* Ended happily with silence */
187  res = 1;
188  pbx_builtin_setvar_helper(chan, "WAITSTATUS", wait_for_silence ? "SILENCE" : "NOISE");
189  ast_debug(1, "WAITSTATUS was set to %s\n", wait_for_silence ? "SILENCE" : "NOISE");
190  break;
191  }
192 
193  if (timeout && (difftime(time(&now), waitstart) >= timeout)) {
194  pbx_builtin_setvar_helper(chan, "WAITSTATUS", "TIMEOUT");
195  ast_debug(1, "WAITSTATUS was set to TIMEOUT\n");
196  res = 0;
197  break;
198  }
199  }
200 
201 
202  if (rfmt && ast_set_read_format(chan, rfmt)) {
203  ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(rfmt), chan->name);
204  }
205  ast_dsp_free(sildet);
206  return res;
207 }
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1650
#define LOG_WARNING
Definition: logger.h:144
struct ast_dsp * ast_dsp_new(void)
Definition: dsp.c:1607
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4383
#define ast_verb(level,...)
Definition: logger.h:243
int ast_set_read_format(struct ast_channel *chan, format_t format)
Sets read format on channel chan Set read format for channel to whichever component of &quot;format&quot; is be...
Definition: channel.c:5301
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
Definition: dsp.c:390
void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
Set threshold value for silence.
Definition: dsp.c:1655
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct ast_format f[]
Definition: format_g726.c:181
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
Return non-zero if this is silence. Updates &quot;totalsilence&quot; with the total number of seconds of silenc...
Definition: dsp.c:1355
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3539
format_t readformat
Definition: channel.h:853
Data structure associated with a single frame of data.
Definition: frame.h:142
enum ast_frame_type frametype
Definition: frame.h:144
#define ast_frfree(fr)
Definition: frame.h:583
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:1880
int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
Return non-zero if this is noise. Updates &quot;totalnoise&quot; with the total number of seconds of noise...
Definition: dsp.c:1373
static int load_module ( void  )
static

Definition at line 267 of file app_waitforsilence.c.

References ast_register_application_xml, waitfornoise_exec(), and waitforsilence_exec().

268 {
269  int res;
270 
273  return res;
274 }
static int waitforsilence_exec(struct ast_channel *chan, const char *data)
static char * app_silence
static char * app_noise
static int waitfornoise_exec(struct ast_channel *chan, const char *data)
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
static int unload_module ( void  )
static

Definition at line 258 of file app_waitforsilence.c.

References ast_unregister_application().

259 {
260  int res;
263 
264  return res;
265 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
static char * app_silence
static char * app_noise
static int waitfor_exec ( struct ast_channel chan,
const char *  data,
int  wait_for_silence 
)
static

Definition at line 209 of file app_waitforsilence.c.

References ast_channel::_state, ast_answer(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_log(), ast_opt_transmit_silence, AST_STATE_UP, ast_verb, do_waiting(), and LOG_WARNING.

Referenced by waitfornoise_exec(), and waitforsilence_exec().

210 {
211  int res = 1;
212  int timereqd = 1000;
213  int timeout = 0;
214  int iterations = 1, i;
215  time_t waitstart;
216  struct ast_silence_generator *silgen = NULL;
217 
218  if (chan->_state != AST_STATE_UP) {
219  res = ast_answer(chan); /* Answer the channel */
220  }
221 
222  if (!data || ( (sscanf(data, "%30d,%30d,%30d", &timereqd, &iterations, &timeout) != 3) &&
223  (sscanf(data, "%30d,%30d", &timereqd, &iterations) != 2) &&
224  (sscanf(data, "%30d", &timereqd) != 1) ) ) {
225  ast_log(LOG_WARNING, "Using default value of 1000ms, 1 iteration, no timeout\n");
226  }
227 
228  ast_verb(3, "Waiting %d time(s) for %d ms silence with %d timeout\n", iterations, timereqd, timeout);
229 
232  }
233  time(&waitstart);
234  res = 1;
235  for (i=0; (i<iterations) && (res == 1); i++) {
236  res = do_waiting(chan, timereqd, waitstart, timeout, wait_for_silence);
237  }
238  if (silgen) {
240  }
241 
242 
243  if (res > 0)
244  res = 0;
245  return res;
246 }
static int do_waiting(struct ast_channel *chan, int timereqd, time_t waitstart, int timeout, int wait_for_silence)
#define LOG_WARNING
Definition: logger.h:144
#define ast_opt_transmit_silence
Definition: options.h:120
#define ast_verb(level,...)
Definition: logger.h:243
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
Definition: channel.c:8309
enum ast_channel_state _state
Definition: channel.h:839
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
Stops a previously-started silence generator on the given channel.
Definition: channel.c:8355
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
static int waitfornoise_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 253 of file app_waitforsilence.c.

References waitfor_exec().

Referenced by load_module().

254 {
255  return waitfor_exec(chan, data, 0);
256 }
static int waitfor_exec(struct ast_channel *chan, const char *data, int wait_for_silence)
static int waitforsilence_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 248 of file app_waitforsilence.c.

References waitfor_exec().

Referenced by load_module().

249 {
250  return waitfor_exec(chan, data, 1);
251 }
static int waitfor_exec(struct ast_channel *chan, const char *data, int wait_for_silence)

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Wait For Silence" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static

Definition at line 276 of file app_waitforsilence.c.

char* app_noise = "WaitForNoise"
static

Definition at line 127 of file app_waitforsilence.c.

char* app_silence = "WaitForSilence"
static

Definition at line 126 of file app_waitforsilence.c.

Definition at line 276 of file app_waitforsilence.c.