Asterisk - The Open Source Telephony Project  18.5.0
Macros | Enumerations | Functions | Variables
app_record.c File Reference

Trivial application to record a sound file. More...

#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/app.h"
#include "asterisk/channel.h"
#include "asterisk/dsp.h"
#include "asterisk/format_cache.h"
#include "asterisk/paths.h"
Include dependency graph for app_record.c:

Go to the source code of this file.

Macros

#define OPERATOR_KEY   '0'
 

Enumerations

enum  {
  OPTION_APPEND = (1 << 0), OPTION_NOANSWER = (1 << 1), OPTION_QUIET = (1 << 2), OPTION_SKIP = (1 << 3),
  OPTION_STAR_TERMINATE = (1 << 4), OPTION_IGNORE_TERMINATE = (1 << 5), OPTION_KEEP = (1 << 6), OPTION_ANY_TERMINATE = (1 << 7),
  OPTION_OPERATOR_EXIT = (1 << 8), OPTION_NO_TRUNCATE = (1 << 9)
}
 
enum  dtmf_response { RESPONSE_NO_MATCH = 0, RESPONSE_OPERATOR, RESPONSE_DTMF }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int create_destination_directory (const char *path)
 
static int load_module (void)
 
static enum dtmf_response record_dtmf_response (struct ast_channel *chan, struct ast_flags *flags, int dtmf_integer, int terminator)
 
static int record_exec (struct ast_channel *chan, const char *data)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Trivial Record Application" , .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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static char * app = "Record"
 
static const struct ast_app_option app_opts [128] = { [ 'a' ] = { .flag = OPTION_APPEND }, [ 'k' ] = { .flag = OPTION_KEEP }, [ 'n' ] = { .flag = OPTION_NOANSWER }, [ 'o' ] = { .flag = OPTION_OPERATOR_EXIT }, [ 'q' ] = { .flag = OPTION_QUIET }, [ 's' ] = { .flag = OPTION_SKIP }, [ 't' ] = { .flag = OPTION_STAR_TERMINATE }, [ 'u' ] = { .flag = OPTION_NO_TRUNCATE }, [ 'y' ] = { .flag = OPTION_ANY_TERMINATE }, [ 'x' ] = { .flag = OPTION_IGNORE_TERMINATE }, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 

Detailed Description

Trivial application to record a sound file.

Author
Matthew Fredrickson cresl.nosp@m.in@d.nosp@m.igium.nosp@m..com

Definition in file app_record.c.

Macro Definition Documentation

◆ OPERATOR_KEY

#define OPERATOR_KEY   '0'

Definition at line 123 of file app_record.c.

Referenced by record_dtmf_response().

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
OPTION_APPEND 
OPTION_NOANSWER 
OPTION_QUIET 
OPTION_SKIP 
OPTION_STAR_TERMINATE 
OPTION_IGNORE_TERMINATE 
OPTION_KEEP 
OPTION_ANY_TERMINATE 
OPTION_OPERATOR_EXIT 
OPTION_NO_TRUNCATE 

Definition at line 127 of file app_record.c.

127  {
128  OPTION_APPEND = (1 << 0),
129  OPTION_NOANSWER = (1 << 1),
130  OPTION_QUIET = (1 << 2),
131  OPTION_SKIP = (1 << 3),
132  OPTION_STAR_TERMINATE = (1 << 4),
133  OPTION_IGNORE_TERMINATE = (1 << 5),
134  OPTION_KEEP = (1 << 6),
135  OPTION_ANY_TERMINATE = (1 << 7),
136  OPTION_OPERATOR_EXIT = (1 << 8),
137  OPTION_NO_TRUNCATE = (1 << 9),
138 };

◆ dtmf_response

Enumerator
RESPONSE_NO_MATCH 
RESPONSE_OPERATOR 
RESPONSE_DTMF 

Definition at line 140 of file app_record.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 543 of file app_record.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 543 of file app_record.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 543 of file app_record.c.

◆ create_destination_directory()

static int create_destination_directory ( const char *  path)
static

Definition at line 187 of file app_record.c.

References ast_config_AST_DATA_DIR, ast_mkdir(), and PATH_MAX.

Referenced by record_exec().

188 {
189  int res;
190  char directory[PATH_MAX], *file_sep;
191 
192  if (!(file_sep = strrchr(path, '/'))) {
193  /* No directory to create */
194  return 0;
195  }
196 
197  /* Overwrite temporarily */
198  *file_sep = '\0';
199 
200  /* Absolute path? */
201  if (path[0] == '/') {
202  res = ast_mkdir(path, 0777);
203  *file_sep = '/';
204  return res;
205  }
206 
207  /* Relative path */
208  res = snprintf(directory, sizeof(directory), "%s/sounds/%s",
210 
211  *file_sep = '/';
212 
213  if (res >= sizeof(directory)) {
214  /* We truncated, so we fail */
215  return -1;
216  }
217 
218  return ast_mkdir(directory, 0777);
219 }
const char * ast_config_AST_DATA_DIR
Definition: options.c:158
#define PATH_MAX
Definition: asterisk.h:40
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: main/utils.c:2231

◆ load_module()

static int load_module ( void  )
static

Definition at line 538 of file app_record.c.

References app, ast_register_application_xml, and record_exec().

539 {
541 }
static int record_exec(struct ast_channel *chan, const char *data)
Definition: app_record.c:221
static char * app
Definition: app_record.c:125
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

◆ record_dtmf_response()

static enum dtmf_response record_dtmf_response ( struct ast_channel chan,
struct ast_flags flags,
int  dtmf_integer,
int  terminator 
)
static

Definition at line 171 of file app_record.c.

References ast_test_flag, OPERATOR_KEY, OPTION_ANY_TERMINATE, OPTION_OPERATOR_EXIT, RESPONSE_DTMF, RESPONSE_NO_MATCH, and RESPONSE_OPERATOR.

Referenced by record_exec().

173 {
174  if ((dtmf_integer == OPERATOR_KEY) &&
176  return RESPONSE_OPERATOR;
177  }
178 
179  if ((dtmf_integer == terminator) ||
181  return RESPONSE_DTMF;
182  }
183 
184  return RESPONSE_NO_MATCH;
185 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define OPERATOR_KEY
Definition: app_record.c:123

◆ record_exec()

static int record_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 221 of file app_record.c.

References ao2_bump, ao2_cleanup, app_opts, args, ast_answer(), AST_APP_ARG, ast_app_parse_options(), ast_channel_language(), ast_channel_name(), ast_channel_readformat(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_closestream(), AST_CONTROL_VIDUPDATE, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_dsp_free(), ast_dsp_get_threshold_from_settings(), ast_dsp_new(), ast_dsp_set_threshold(), ast_dsp_silence(), AST_FILE_MODE, ast_filedelete(), ast_fileexists(), ast_format_slin, AST_FRAME_DTMF, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_indicate(), ast_log, ast_opt_transmit_silence, ast_read(), ast_remaining_ms(), ast_set_read_format(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_stream_rewind(), ast_streamfile(), ast_strlen_zero, ast_test_flag, ast_truncstream(), ast_tvnow(), ast_waitfor(), ast_waitstream(), ast_writefile(), ast_writestream(), create_destination_directory(), ext, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, NULL, OPTION_APPEND, OPTION_IGNORE_TERMINATE, OPTION_KEEP, OPTION_NO_TRUNCATE, OPTION_NOANSWER, OPTION_QUIET, OPTION_SKIP, OPTION_STAR_TERMINATE, options, out, parse(), PATH_MAX, pbx_builtin_setvar_helper(), RAII_VAR, record_dtmf_response(), RESPONSE_DTMF, RESPONSE_NO_MATCH, RESPONSE_OPERATOR, ast_frame::subclass, THRESHOLD_SILENCE, tmp(), and ast_dsp::totalsilence.

Referenced by load_module().

222 {
223  int res = 0;
224  char *ext = NULL, *opts[0];
225  char *parse;
226  int i = 0;
227  char tmp[PATH_MAX];
228 
229  struct ast_filestream *s = NULL;
230  struct ast_frame *f = NULL;
231 
232  struct ast_dsp *sildet = NULL; /* silence detector dsp */
233  int totalsilence = 0;
234  int dspsilence = 0;
235  int silence = 0; /* amount of silence to allow */
236  int gotsilence = 0; /* did we timeout for silence? */
237  int truncate_silence = 1; /* truncate on complete silence recording */
238  int maxduration = 0; /* max duration of recording in milliseconds */
239  int gottimeout = 0; /* did we timeout for maxduration exceeded? */
240  int terminator = '#';
241  RAII_VAR(struct ast_format *, rfmt, NULL, ao2_cleanup);
242  int ioflags;
243  struct ast_silence_generator *silgen = NULL;
244  struct ast_flags flags = { 0, };
246  AST_APP_ARG(filename);
247  AST_APP_ARG(silence);
248  AST_APP_ARG(maxduration);
250  );
251  int ms;
252  struct timeval start;
253  const char *status_response = "ERROR";
254 
255  /* The next few lines of code parse out the filename and header from the input string */
256  if (ast_strlen_zero(data)) { /* no data implies no filename or anything is present */
257  ast_log(LOG_WARNING, "Record requires an argument (filename)\n");
258  pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
259  return -1;
260  }
261 
262  parse = ast_strdupa(data);
263  AST_STANDARD_APP_ARGS(args, parse);
264  if (args.argc == 4)
265  ast_app_parse_options(app_opts, &flags, opts, args.options);
266 
267  if (!ast_strlen_zero(args.filename)) {
268  ext = strrchr(args.filename, '.'); /* to support filename with a . in the filename, not format */
269  if (!ext)
270  ext = strchr(args.filename, ':');
271  if (ext) {
272  *ext = '\0';
273  ext++;
274  }
275  }
276  if (!ext) {
277  ast_log(LOG_WARNING, "No extension specified to filename!\n");
278  pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
279  return -1;
280  }
281  if (args.silence) {
282  if ((sscanf(args.silence, "%30d", &i) == 1) && (i > -1)) {
283  silence = i * 1000;
284  } else if (!ast_strlen_zero(args.silence)) {
285  ast_log(LOG_WARNING, "'%s' is not a valid silence duration\n", args.silence);
286  }
287  }
288 
289  if (ast_test_flag(&flags, OPTION_NO_TRUNCATE))
290  truncate_silence = 0;
291 
292  if (args.maxduration) {
293  if ((sscanf(args.maxduration, "%30d", &i) == 1) && (i > -1))
294  /* Convert duration to milliseconds */
295  maxduration = i * 1000;
296  else if (!ast_strlen_zero(args.maxduration))
297  ast_log(LOG_WARNING, "'%s' is not a valid maximum duration\n", args.maxduration);
298  }
299 
301  terminator = '*';
303  terminator = '\0';
304 
305  /*
306  If a '%d' is specified as part of the filename, we replace that token with
307  sequentially incrementing numbers until we find a unique filename.
308  */
309  if (strchr(args.filename, '%')) {
310  size_t src, dst, count = 0;
311  size_t src_len = strlen(args.filename);
312  size_t dst_len = sizeof(tmp) - 1;
313 
314  do {
315  for (src = 0, dst = 0; src < src_len && dst < dst_len; src++) {
316  if (!strncmp(&args.filename[src], "%d", 2)) {
317  int s = snprintf(&tmp[dst], PATH_MAX - dst, "%zu", count);
318  if (s >= PATH_MAX - dst) {
319  /* We truncated, so we need to bail */
320  ast_log(LOG_WARNING, "Failed to create unique filename from template: %s\n", args.filename);
321  pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
322  return -1;
323  }
324  dst += s;
325  src++;
326  } else {
327  tmp[dst] = args.filename[src];
328  tmp[++dst] = '\0';
329  }
330  }
331  count++;
332  } while (ast_fileexists(tmp, ext, ast_channel_language(chan)) > 0);
333  } else
334  ast_copy_string(tmp, args.filename, sizeof(tmp));
335 
336  pbx_builtin_setvar_helper(chan, "RECORDED_FILE", tmp);
337 
338  if (ast_channel_state(chan) != AST_STATE_UP) {
339  if (ast_test_flag(&flags, OPTION_SKIP)) {
340  /* At the user's option, skip if the line is not up */
341  pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "SKIP");
342  return 0;
343  } else if (!ast_test_flag(&flags, OPTION_NOANSWER)) {
344  /* Otherwise answer unless we're supposed to record while on-hook */
345  res = ast_answer(chan);
346  }
347  }
348 
349  if (res) {
350  ast_log(LOG_WARNING, "Could not answer channel '%s'\n", ast_channel_name(chan));
351  status_response = "ERROR";
352  goto out;
353  }
354 
355  if (!ast_test_flag(&flags, OPTION_QUIET)) {
356  /* Some code to play a nice little beep to signify the start of the record operation */
357  res = ast_streamfile(chan, "beep", ast_channel_language(chan));
358  if (!res) {
359  res = ast_waitstream(chan, "");
360  } else {
361  ast_log(LOG_WARNING, "ast_streamfile(beep) failed on %s\n", ast_channel_name(chan));
362  res = 0;
363  }
364  ast_stopstream(chan);
365  }
366 
367  /* The end of beep code. Now the recording starts */
368 
369  if (silence > 0) {
370  rfmt = ao2_bump(ast_channel_readformat(chan));
372  if (res < 0) {
373  ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
374  pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
375  return -1;
376  }
377  sildet = ast_dsp_new();
378  if (!sildet) {
379  ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
380  pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
381  return -1;
382  }
384  }
385 
386  if (create_destination_directory(tmp)) {
387  ast_log(LOG_WARNING, "Could not create directory for file %s\n", args.filename);
388  status_response = "ERROR";
389  goto out;
390  }
391 
392  ioflags = ast_test_flag(&flags, OPTION_APPEND) ? O_CREAT|O_APPEND|O_WRONLY : O_CREAT|O_TRUNC|O_WRONLY;
393  s = ast_writefile(tmp, ext, NULL, ioflags, 0, AST_FILE_MODE);
394 
395  if (!s) {
396  ast_log(LOG_WARNING, "Could not create file %s\n", args.filename);
397  status_response = "ERROR";
398  goto out;
399  }
400 
403 
404  /* Request a video update */
406 
407  if (maxduration <= 0)
408  maxduration = -1;
409 
410  start = ast_tvnow();
411  while ((ms = ast_remaining_ms(start, maxduration))) {
412  ms = ast_waitfor(chan, ms);
413  if (ms < 0) {
414  break;
415  }
416 
417  if (maxduration > 0 && ms == 0) {
418  break;
419  }
420 
421  f = ast_read(chan);
422  if (!f) {
423  res = -1;
424  break;
425  }
426  if (f->frametype == AST_FRAME_VOICE) {
427  res = ast_writestream(s, f);
428 
429  if (res) {
430  ast_log(LOG_WARNING, "Problem writing frame\n");
431  ast_frfree(f);
432  status_response = "ERROR";
433  break;
434  }
435 
436  if (silence > 0) {
437  dspsilence = 0;
438  ast_dsp_silence(sildet, f, &dspsilence);
439  if (dspsilence) {
440  totalsilence = dspsilence;
441  } else {
442  totalsilence = 0;
443  }
444  if (totalsilence > silence) {
445  /* Ended happily with silence */
446  ast_frfree(f);
447  gotsilence = 1;
448  status_response = "SILENCE";
449  break;
450  }
451  }
452  } else if (f->frametype == AST_FRAME_VIDEO) {
453  res = ast_writestream(s, f);
454 
455  if (res) {
456  ast_log(LOG_WARNING, "Problem writing frame\n");
457  status_response = "ERROR";
458  ast_frfree(f);
459  break;
460  }
461  } else if (f->frametype == AST_FRAME_DTMF) {
462  enum dtmf_response rc =
463  record_dtmf_response(chan, &flags, f->subclass.integer, terminator);
464  switch(rc) {
465  case RESPONSE_NO_MATCH:
466  break;
467  case RESPONSE_OPERATOR:
468  status_response = "OPERATOR";
469  ast_debug(1, "Got OPERATOR\n");
470  break;
471  case RESPONSE_DTMF:
472  status_response = "DTMF";
473  ast_debug(1, "Got DTMF\n");
474  break;
475  }
476  if (rc != RESPONSE_NO_MATCH) {
477  ast_frfree(f);
478  break;
479  }
480  }
481  ast_frfree(f);
482  }
483 
484  if (maxduration > 0 && !ms) {
485  gottimeout = 1;
486  status_response = "TIMEOUT";
487  }
488 
489  if (!f) {
490  ast_debug(1, "Got hangup\n");
491  res = -1;
492  status_response = "HANGUP";
493  if (!ast_test_flag(&flags, OPTION_KEEP)) {
494  ast_filedelete(args.filename, NULL);
495  }
496  }
497 
498  if (gotsilence && truncate_silence) {
499  ast_stream_rewind(s, silence - 1000);
500  ast_truncstream(s);
501  } else if (!gottimeout && f) {
502  /*
503  * Strip off the last 1/4 second of it, if we didn't end because of a timeout,
504  * or a hangup. This must mean we ended because of a DTMF tone and while this
505  * 1/4 second stripping is very old code the most likely explanation is that it
506  * relates to stripping a partial DTMF tone.
507  */
508  ast_stream_rewind(s, 250);
509  ast_truncstream(s);
510  }
511  ast_closestream(s);
512 
513  if (silgen)
515 
516 out:
517  if ((silence > 0) && rfmt) {
518  res = ast_set_read_format(chan, rfmt);
519  if (res) {
520  ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", ast_channel_name(chan));
521  }
522  }
523 
524  if (sildet) {
525  ast_dsp_free(sildet);
526  }
527 
528  pbx_builtin_setvar_helper(chan, "RECORD_STATUS", status_response);
529 
530  return res;
531 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
dtmf_response
Definition: app_record.c:140
#define ast_test_flag(p, flag)
Definition: utils.h:63
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1745
static int tmp()
Definition: bt_open.c:389
unsigned int flags
Definition: utils.h:200
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4302
ast_channel_state
ast_channel states
Definition: channelstate.h:35
Definition of a media format.
Definition: format.c:43
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_opt_transmit_silence
Definition: options.h:124
const char * args
#define NULL
Definition: resample.c:96
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1098
#define AST_FRAME_DTMF
const char * ext
Definition: http.c:147
#define AST_FILE_MODE
Definition: asterisk.h:32
struct ast_frame_subclass subclass
int totalsilence
Definition: dsp.c:409
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5849
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static const struct ast_app_option app_opts[128]
Definition: app_record.c:157
Definition: dsp.c:405
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:2906
void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
Set the minimum average magnitude threshold to determine talking by the DSP.
Definition: dsp.c:1775
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
Definition: channel.c:8266
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: main/utils.c:2033
int ast_stream_rewind(struct ast_filestream *fs, off_t ms)
Rewind stream ms.
Definition: file.c:1063
struct ast_filestream * ast_writefile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
Starts writing a file.
Definition: file.c:1361
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:8312
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition: file.c:1068
Structure used to handle boolean flags.
Definition: utils.h:199
int ast_truncstream(struct ast_filestream *fs)
Trunc stream at current location.
Definition: file.c:1043
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...
int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
Process the audio frame for silence.
Definition: dsp.c:1483
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
Definition: mod_format.h:101
FILE * out
Definition: utils/frame.c:33
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3171
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)
int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
Writes a frame to a stream.
Definition: file.c:209
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086
#define ast_frfree(fr)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
Data structure associated with a single frame of data.
const char * ast_channel_language(const struct ast_channel *chan)
enum ast_frame_type frametype
#define PATH_MAX
Definition: asterisk.h:40
static struct test_options options
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:1996
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
static int create_destination_directory(const char *path)
Definition: app_record.c:187
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187
static enum dtmf_response record_dtmf_response(struct ast_channel *chan, struct ast_flags *flags, int dtmf_integer, int terminator)
Definition: app_record.c:171
#define AST_APP_ARG(name)
Define an application argument.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 533 of file app_record.c.

References app, and ast_unregister_application().

534 {
536 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
static char * app
Definition: app_record.c:125

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Trivial Record Application" , .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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 543 of file app_record.c.

◆ app

char* app = "Record"
static

Definition at line 125 of file app_record.c.

Referenced by load_module(), and unload_module().

◆ app_opts

const struct ast_app_option app_opts[128] = { [ 'a' ] = { .flag = OPTION_APPEND }, [ 'k' ] = { .flag = OPTION_KEEP }, [ 'n' ] = { .flag = OPTION_NOANSWER }, [ 'o' ] = { .flag = OPTION_OPERATOR_EXIT }, [ 'q' ] = { .flag = OPTION_QUIET }, [ 's' ] = { .flag = OPTION_SKIP }, [ 't' ] = { .flag = OPTION_STAR_TERMINATE }, [ 'u' ] = { .flag = OPTION_NO_TRUNCATE }, [ 'y' ] = { .flag = OPTION_ANY_TERMINATE }, [ 'x' ] = { .flag = OPTION_IGNORE_TERMINATE }, }
static

Definition at line 157 of file app_record.c.

Referenced by record_exec().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 543 of file app_record.c.