Wed Feb 11 12:00:03 2009

Asterisk developer's documentation


app_mixmonitor.c File Reference

MixMonitor() - Record a call and mix the audio during the recording. More...

#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/audiohook.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/cli.h"
#include "asterisk/options.h"
#include "asterisk/app.h"
#include "asterisk/linkedlists.h"
#include "asterisk/utils.h"

Go to the source code of this file.

Data Structures

struct  mixmonitor

Defines

#define get_volfactor(x)   x ? ((x > 0) ? (1 << x) : ((1 << abs(x)) * -1)) : 0
#define SAMPLES_PER_FRAME   160

Enumerations

enum  {
  MUXFLAG_APPEND = (1 << 1), MUXFLAG_BRIDGED = (1 << 2), MUXFLAG_VOLUME = (1 << 3), MUXFLAG_READVOLUME = (1 << 4),
  MUXFLAG_WRITEVOLUME = (1 << 5)
}
enum  { OPT_ARG_READVOLUME = 0, OPT_ARG_WRITEVOLUME, OPT_ARG_VOLUME, OPT_ARG_ARRAY_SIZE }

Functions

static void __reg_module (void)
static void __unreg_module (void)
static char * complete_mixmonitor_cli (const char *line, const char *word, int pos, int state)
static void launch_monitor_thread (struct ast_channel *chan, const char *filename, unsigned int flags, int readvol, int writevol, const char *post_process)
static int load_module (void)
static int mixmonitor_cli (int fd, int argc, char **argv)
static int mixmonitor_exec (struct ast_channel *chan, void *data)
static void * mixmonitor_thread (void *obj)
static int startmon (struct ast_channel *chan, struct ast_audiohook *audiohook)
static int stop_mixmonitor_exec (struct ast_channel *chan, void *data)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Mixed Audio Monitoring 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 = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, }
static const char * app = "MixMonitor"
static const struct ast_module_infoast_module_info = &__mod_info
static struct ast_cli_entry cli_mixmonitor []
static const char * desc
module_symbols * me
enum { ... }  mixmonitor_args
enum { ... }  mixmonitor_flags
static struct ast_app_option mixmonitor_opts [128] = { [ 'a' ] = { .flag = MUXFLAG_APPEND }, [ 'b' ] = { .flag = MUXFLAG_BRIDGED }, [ 'v' ] = { .flag = MUXFLAG_READVOLUME , .arg_index = OPT_ARG_READVOLUME + 1 }, [ 'V' ] = { .flag = MUXFLAG_WRITEVOLUME , .arg_index = OPT_ARG_WRITEVOLUME + 1 }, [ 'W' ] = { .flag = MUXFLAG_VOLUME , .arg_index = OPT_ARG_VOLUME + 1 },}
static const char * mixmonitor_spy_type = "MixMonitor"
static const char * stop_app = "StopMixMonitor"
static const char * stop_desc
static const char * stop_synopsis = "Stop recording a call through MixMonitor"
static const char * synopsis = "Record a call and mix the audio during the recording"


Detailed Description

MixMonitor() - Record a call and mix the audio during the recording.

Author:
Mark Spencer <markster@digium.com>

Kevin P. Fleming <kpfleming@digium.com>

Note:
Based on app_muxmon.c provided by Anthony Minessale II <anthmct@yahoo.com>

Definition in file app_mixmonitor.c.


Define Documentation

#define get_volfactor (  )     x ? ((x > 0) ? (1 << x) : ((1 << abs(x)) * -1)) : 0

Definition at line 58 of file app_mixmonitor.c.

Referenced by mixmonitor_exec().

#define SAMPLES_PER_FRAME   160

Definition at line 143 of file app_mixmonitor.c.

Referenced by mixmonitor_thread().


Enumeration Type Documentation

anonymous enum

Enumerator:
MUXFLAG_APPEND 
MUXFLAG_BRIDGED 
MUXFLAG_VOLUME 
MUXFLAG_READVOLUME 
MUXFLAG_WRITEVOLUME 

Definition at line 104 of file app_mixmonitor.c.

00104      {
00105    MUXFLAG_APPEND = (1 << 1),
00106    MUXFLAG_BRIDGED = (1 << 2),
00107    MUXFLAG_VOLUME = (1 << 3),
00108    MUXFLAG_READVOLUME = (1 << 4),
00109    MUXFLAG_WRITEVOLUME = (1 << 5),
00110 } mixmonitor_flags;

anonymous enum

Enumerator:
OPT_ARG_READVOLUME 
OPT_ARG_WRITEVOLUME 
OPT_ARG_VOLUME 
OPT_ARG_ARRAY_SIZE 

Definition at line 112 of file app_mixmonitor.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 446 of file app_mixmonitor.c.

static void __unreg_module ( void   )  [static]

Definition at line 446 of file app_mixmonitor.c.

static char* complete_mixmonitor_cli ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 408 of file app_mixmonitor.c.

References ast_complete_channels().

00409 {
00410    return ast_complete_channels(line, word, pos, state, 2);
00411 }

static void launch_monitor_thread ( struct ast_channel chan,
const char *  filename,
unsigned int  flags,
int  readvol,
int  writevol,
const char *  post_process 
) [static]

Definition at line 217 of file app_mixmonitor.c.

References ast_audiohook_destroy(), ast_audiohook_init(), AST_AUDIOHOOK_TRIGGER_SYNC, AST_AUDIOHOOK_TYPE_SPY, ast_log(), ast_pthread_create_background, ast_set_flag, ast_strdupa, ast_strlen_zero(), calloc, mixmonitor::chan, mixmonitor::flags, free, len(), LOG_WARNING, mixmonitor_thread(), mixmonitor::name, ast_channel::name, pbx_substitute_variables_helper(), startmon(), and thread.

Referenced by mixmonitor_exec().

00219 {
00220    pthread_attr_t attr;
00221    pthread_t thread;
00222    struct mixmonitor *mixmonitor;
00223    char postprocess2[1024] = "";
00224    size_t len;
00225 
00226    len = sizeof(*mixmonitor) + strlen(chan->name) + strlen(filename) + 2;
00227 
00228    /* If a post process system command is given attach it to the structure */
00229    if (!ast_strlen_zero(post_process)) {
00230       char *p1, *p2;
00231 
00232       p1 = ast_strdupa(post_process);
00233       for (p2 = p1; *p2 ; p2++) {
00234          if (*p2 == '^' && *(p2+1) == '{') {
00235             *p2 = '$';
00236          }
00237       }
00238 
00239       pbx_substitute_variables_helper(chan, p1, postprocess2, sizeof(postprocess2) - 1);
00240       if (!ast_strlen_zero(postprocess2))
00241          len += strlen(postprocess2) + 1;
00242    }
00243 
00244    /* Pre-allocate mixmonitor structure and spy */
00245    if (!(mixmonitor = calloc(1, len))) {
00246       return;
00247    }
00248 
00249    /* Copy over flags and channel name */
00250    mixmonitor->flags = flags;
00251    mixmonitor->chan = chan;
00252    mixmonitor->name = (char *) mixmonitor + sizeof(*mixmonitor);
00253    strcpy(mixmonitor->name, chan->name);
00254    if (!ast_strlen_zero(postprocess2)) {
00255       mixmonitor->post_process = mixmonitor->name + strlen(mixmonitor->name) + strlen(filename) + 2;
00256       strcpy(mixmonitor->post_process, postprocess2);
00257    }
00258 
00259    mixmonitor->filename = (char *) mixmonitor + sizeof(*mixmonitor) + strlen(chan->name) + 1;
00260    strcpy(mixmonitor->filename, filename);
00261 
00262    /* Setup the actual spy before creating our thread */
00263    if (ast_audiohook_init(&mixmonitor->audiohook, AST_AUDIOHOOK_TYPE_SPY, mixmonitor_spy_type)) {
00264       free(mixmonitor);
00265       return;
00266    }
00267    
00268    ast_set_flag(&mixmonitor->audiohook, AST_AUDIOHOOK_TRIGGER_SYNC);
00269    
00270    if (readvol)
00271       mixmonitor->audiohook.options.read_volume = readvol;
00272    if (writevol)
00273       mixmonitor->audiohook.options.write_volume = writevol;
00274 
00275    if (startmon(chan, &mixmonitor->audiohook)) {
00276       ast_log(LOG_WARNING, "Unable to add '%s' spy to channel '%s'\n",
00277          mixmonitor_spy_type, chan->name);
00278       /* Since we couldn't add ourselves - bail out! */
00279       ast_audiohook_destroy(&mixmonitor->audiohook);
00280       free(mixmonitor);
00281       return;
00282    }
00283 
00284    pthread_attr_init(&attr);
00285    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00286    ast_pthread_create_background(&thread, &attr, mixmonitor_thread, mixmonitor);
00287    pthread_attr_destroy(&attr);
00288 
00289 }

static int load_module ( void   )  [static]

Definition at line 435 of file app_mixmonitor.c.

References ast_cli_register_multiple(), ast_register_application(), cli_mixmonitor, mixmonitor_exec(), and stop_mixmonitor_exec().

00436 {
00437    int res;
00438 
00439    ast_cli_register_multiple(cli_mixmonitor, sizeof(cli_mixmonitor) / sizeof(struct ast_cli_entry));
00440    res = ast_register_application(app, mixmonitor_exec, synopsis, desc);
00441    res |= ast_register_application(stop_app, stop_mixmonitor_exec, stop_synopsis, stop_desc);
00442 
00443    return res;
00444 }

static int mixmonitor_cli ( int  fd,
int  argc,
char **  argv 
) [static]

Definition at line 386 of file app_mixmonitor.c.

References ast_audiohook_detach_source(), ast_channel_unlock, ast_cli(), ast_get_channel_by_name_prefix_locked(), mixmonitor_exec(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00387 {
00388    struct ast_channel *chan;
00389 
00390    if (argc < 3)
00391       return RESULT_SHOWUSAGE;
00392 
00393    if (!(chan = ast_get_channel_by_name_prefix_locked(argv[2], strlen(argv[2])))) {
00394       ast_cli(fd, "No channel matching '%s' found.\n", argv[2]);
00395       return RESULT_SUCCESS;
00396    }
00397 
00398    if (!strcasecmp(argv[1], "start"))
00399       mixmonitor_exec(chan, argv[3]);
00400    else if (!strcasecmp(argv[1], "stop"))
00401       ast_audiohook_detach_source(chan, mixmonitor_spy_type);
00402 
00403    ast_channel_unlock(chan);
00404 
00405    return RESULT_SUCCESS;
00406 }

static int mixmonitor_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 291 of file app_mixmonitor.c.

References AST_APP_ARG, ast_app_parse_options(), ast_config_AST_MONITOR_DIR, AST_DECLARE_APP_ARGS, ast_log(), ast_module_user_add, ast_module_user_remove, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_flags::flags, get_volfactor, launch_monitor_thread(), LOG_NOTICE, LOG_WARNING, mixmonitor_opts, MUXFLAG_READVOLUME, MUXFLAG_VOLUME, MUXFLAG_WRITEVOLUME, OPT_ARG_ARRAY_SIZE, OPT_ARG_READVOLUME, OPT_ARG_VOLUME, OPT_ARG_WRITEVOLUME, parse(), and pbx_builtin_setvar_helper().

Referenced by load_module(), and mixmonitor_cli().

00292 {
00293    int x, readvol = 0, writevol = 0;
00294    struct ast_module_user *u;
00295    struct ast_flags flags = {0};
00296    char *parse;
00297    AST_DECLARE_APP_ARGS(args,
00298       AST_APP_ARG(filename);
00299       AST_APP_ARG(options);
00300       AST_APP_ARG(post_process);
00301    );
00302    
00303    if (ast_strlen_zero(data)) {
00304       ast_log(LOG_WARNING, "MixMonitor requires an argument (filename)\n");
00305       return -1;
00306    }
00307 
00308    u = ast_module_user_add(chan);
00309 
00310    parse = ast_strdupa(data);
00311 
00312    AST_STANDARD_APP_ARGS(args, parse);
00313    
00314    if (ast_strlen_zero(args.filename)) {
00315       ast_log(LOG_WARNING, "MixMonitor requires an argument (filename)\n");
00316       ast_module_user_remove(u);
00317       return -1;
00318    }
00319 
00320    if (args.options) {
00321       char *opts[OPT_ARG_ARRAY_SIZE] = { NULL, };
00322 
00323       ast_app_parse_options(mixmonitor_opts, &flags, opts, args.options);
00324 
00325       if (ast_test_flag(&flags, MUXFLAG_READVOLUME)) {
00326          if (ast_strlen_zero(opts[OPT_ARG_READVOLUME])) {
00327             ast_log(LOG_WARNING, "No volume level was provided for the heard volume ('v') option.\n");
00328          } else if ((sscanf(opts[OPT_ARG_READVOLUME], "%d", &x) != 1) || (x < -4) || (x > 4)) {
00329             ast_log(LOG_NOTICE, "Heard volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_READVOLUME]);
00330          } else {
00331             readvol = get_volfactor(x);
00332          }
00333       }
00334       
00335       if (ast_test_flag(&flags, MUXFLAG_WRITEVOLUME)) {
00336          if (ast_strlen_zero(opts[OPT_ARG_WRITEVOLUME])) {
00337             ast_log(LOG_WARNING, "No volume level was provided for the spoken volume ('V') option.\n");
00338          } else if ((sscanf(opts[OPT_ARG_WRITEVOLUME], "%d", &x) != 1) || (x < -4) || (x > 4)) {
00339             ast_log(LOG_NOTICE, "Spoken volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_WRITEVOLUME]);
00340          } else {
00341             writevol = get_volfactor(x);
00342          }
00343       }
00344       
00345       if (ast_test_flag(&flags, MUXFLAG_VOLUME)) {
00346          if (ast_strlen_zero(opts[OPT_ARG_VOLUME])) {
00347             ast_log(LOG_WARNING, "No volume level was provided for the combined volume ('W') option.\n");
00348          } else if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &x) != 1) || (x < -4) || (x > 4)) {
00349             ast_log(LOG_NOTICE, "Combined volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_VOLUME]);
00350          } else {
00351             readvol = writevol = get_volfactor(x);
00352          }
00353       }
00354    }
00355 
00356    /* if not provided an absolute path, use the system-configured monitoring directory */
00357    if (args.filename[0] != '/') {
00358       char *build;
00359 
00360       build = alloca(strlen(ast_config_AST_MONITOR_DIR) + strlen(args.filename) + 3);
00361       sprintf(build, "%s/%s", ast_config_AST_MONITOR_DIR, args.filename);
00362       args.filename = build;
00363    }
00364 
00365    pbx_builtin_setvar_helper(chan, "MIXMONITOR_FILENAME", args.filename);
00366    launch_monitor_thread(chan, args.filename, flags.flags, readvol, writevol, args.post_process);
00367 
00368    ast_module_user_remove(u);
00369 
00370    return 0;
00371 }

static void* mixmonitor_thread ( void *  obj  )  [static]

Definition at line 145 of file app_mixmonitor.c.

References ast_audiohook_destroy(), ast_audiohook_detach(), AST_AUDIOHOOK_DIRECTION_BOTH, ast_audiohook_lock, ast_audiohook_read_frame(), AST_AUDIOHOOK_STATUS_RUNNING, ast_audiohook_trigger_wait(), ast_audiohook_unlock, ast_bridged_channel(), ast_closestream(), AST_FORMAT_SLINEAR, ast_frame_free(), ast_log(), ast_safe_system(), ast_test_flag, ast_verbose(), ast_writefile(), ast_writestream(), mixmonitor::audiohook, mixmonitor::chan, ext, mixmonitor::filename, free, LOG_ERROR, MUXFLAG_APPEND, MUXFLAG_BRIDGED, mixmonitor::name, option_verbose, mixmonitor::post_process, SAMPLES_PER_FRAME, ast_audiohook::status, and VERBOSE_PREFIX_2.

Referenced by launch_monitor_thread().

00146 {
00147    struct mixmonitor *mixmonitor = obj;
00148    struct ast_filestream *fs = NULL;
00149    unsigned int oflags;
00150    char *ext;
00151    int errflag = 0;
00152 
00153    if (option_verbose > 1)
00154       ast_verbose(VERBOSE_PREFIX_2 "Begin MixMonitor Recording %s\n", mixmonitor->name);
00155    
00156    ast_audiohook_lock(&mixmonitor->audiohook);
00157 
00158    while (mixmonitor->audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING) {
00159       struct ast_frame *fr = NULL;
00160       
00161       ast_audiohook_trigger_wait(&mixmonitor->audiohook);
00162       
00163       if (mixmonitor->audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING)
00164          break;
00165       
00166       if (!(fr = ast_audiohook_read_frame(&mixmonitor->audiohook, SAMPLES_PER_FRAME, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR)))
00167          continue;
00168       
00169       if (!ast_test_flag(mixmonitor, MUXFLAG_BRIDGED) || ast_bridged_channel(mixmonitor->chan)) {
00170          /* Initialize the file if not already done so */
00171          if (!fs && !errflag) {
00172             oflags = O_CREAT | O_WRONLY;
00173             oflags |= ast_test_flag(mixmonitor, MUXFLAG_APPEND) ? O_APPEND : O_TRUNC;
00174             
00175             if ((ext = strrchr(mixmonitor->filename, '.')))
00176                *(ext++) = '\0';
00177             else
00178                ext = "raw";
00179             
00180             if (!(fs = ast_writefile(mixmonitor->filename, ext, NULL, oflags, 0, 0644))) {
00181                ast_log(LOG_ERROR, "Cannot open %s.%s\n", mixmonitor->filename, ext);
00182                errflag = 1;
00183             }
00184          }
00185 
00186          /* Write out the frame */
00187          if (fs)
00188             ast_writestream(fs, fr);
00189       }
00190 
00191       /* All done! free it. */
00192       ast_frame_free(fr, 0);
00193    }
00194 
00195    ast_audiohook_detach(&mixmonitor->audiohook);
00196    ast_audiohook_unlock(&mixmonitor->audiohook);
00197    ast_audiohook_destroy(&mixmonitor->audiohook);
00198    
00199    if (option_verbose > 1)
00200       ast_verbose(VERBOSE_PREFIX_2 "End MixMonitor Recording %s\n", mixmonitor->name);
00201 
00202    if (fs)
00203       ast_closestream(fs);
00204 
00205    if (mixmonitor->post_process) {
00206       if (option_verbose > 2)
00207          ast_verbose(VERBOSE_PREFIX_2 "Executing [%s]\n", mixmonitor->post_process);
00208       ast_safe_system(mixmonitor->post_process);
00209    }
00210 
00211    free(mixmonitor);
00212 
00213 
00214    return NULL;
00215 }

static int startmon ( struct ast_channel chan,
struct ast_audiohook audiohook 
) [static]

Definition at line 127 of file app_mixmonitor.c.

References ast_audiohook_attach(), ast_bridged_channel(), AST_FLAG_NBRIDGE, ast_softhangup(), AST_SOFTHANGUP_UNBRIDGE, and ast_test_flag.

Referenced by launch_monitor_thread().

00128 {
00129    struct ast_channel *peer;
00130    int res;
00131 
00132    if (!chan)
00133       return -1;
00134 
00135    res = ast_audiohook_attach(chan, audiohook);
00136 
00137    if (!res && ast_test_flag(chan, AST_FLAG_NBRIDGE) && (peer = ast_bridged_channel(chan)))
00138       ast_softhangup(peer, AST_SOFTHANGUP_UNBRIDGE);  
00139 
00140    return res;
00141 }

static int stop_mixmonitor_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 373 of file app_mixmonitor.c.

References ast_audiohook_detach_source(), ast_module_user_add, ast_module_user_remove, and ast_module_user::chan.

Referenced by load_module().

00374 {
00375    struct ast_module_user *u;
00376 
00377    u = ast_module_user_add(chan);
00378 
00379    ast_audiohook_detach_source(chan, mixmonitor_spy_type);
00380 
00381    ast_module_user_remove(u);
00382 
00383    return 0;
00384 }

static int unload_module ( void   )  [static]

Definition at line 422 of file app_mixmonitor.c.

References ast_cli_unregister_multiple(), ast_module_user_hangup_all, ast_unregister_application(), and cli_mixmonitor.

00423 {
00424    int res;
00425 
00426    ast_cli_unregister_multiple(cli_mixmonitor, sizeof(cli_mixmonitor) / sizeof(struct ast_cli_entry));
00427    res = ast_unregister_application(stop_app);
00428    res |= ast_unregister_application(app);
00429    
00430    ast_module_user_hangup_all();
00431 
00432    return res;
00433 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Mixed Audio Monitoring 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 = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, } [static]

Definition at line 446 of file app_mixmonitor.c.

const char* app = "MixMonitor" [static]

Definition at line 60 of file app_mixmonitor.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 446 of file app_mixmonitor.c.

struct ast_cli_entry cli_mixmonitor[] [static]

Definition at line 413 of file app_mixmonitor.c.

Referenced by load_module(), and unload_module().

const char* desc [static]

Definition at line 62 of file app_mixmonitor.c.

struct module_symbols* me

Definition at line 91 of file app_mixmonitor.c.

enum { ... } mixmonitor_args

enum { ... } mixmonitor_flags

struct ast_app_option mixmonitor_opts[128] = { [ 'a' ] = { .flag = MUXFLAG_APPEND }, [ 'b' ] = { .flag = MUXFLAG_BRIDGED }, [ 'v' ] = { .flag = MUXFLAG_READVOLUME , .arg_index = OPT_ARG_READVOLUME + 1 }, [ 'V' ] = { .flag = MUXFLAG_WRITEVOLUME , .arg_index = OPT_ARG_WRITEVOLUME + 1 }, [ 'W' ] = { .flag = MUXFLAG_VOLUME , .arg_index = OPT_ARG_VOLUME + 1 },} [static]

Definition at line 125 of file app_mixmonitor.c.

Referenced by mixmonitor_exec().

const char* mixmonitor_spy_type = "MixMonitor" [static]

Definition at line 93 of file app_mixmonitor.c.

const char* stop_app = "StopMixMonitor" [static]

Definition at line 83 of file app_mixmonitor.c.

const char* stop_desc [static]

Initial value:

 ""
"  StopMixMonitor()\n\n"
"Stops the audio recording that was started with a call to MixMonitor()\n"
"on the current channel.\n"
""

Definition at line 85 of file app_mixmonitor.c.

const char* stop_synopsis = "Stop recording a call through MixMonitor" [static]

Definition at line 84 of file app_mixmonitor.c.

const char* synopsis = "Record a call and mix the audio during the recording" [static]

Definition at line 61 of file app_mixmonitor.c.


Generated on Wed Feb 11 12:00:04 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7