Tue Aug 20 16:35:04 2013

Asterisk developer's documentation


func_volume.c File Reference

Technology independent volume control. More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
#include "asterisk/audiohook.h"
#include "asterisk/app.h"

Go to the source code of this file.

Data Structures

struct  volume_information

Enumerations

enum  volume_flags { VOLUMEFLAG_CHANGE = (1 << 1) }

Functions

 AST_APP_OPTIONS (volume_opts,{AST_APP_OPTION('p', VOLUMEFLAG_CHANGE),})
 AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Technology independent volume control")
static void destroy_callback (void *data)
static int load_module (void)
static int unload_module (void)
static int volume_callback (struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction)
static int volume_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)

Variables

static struct ast_datastore_info volume_datastore
 Static structure for datastore information.
static struct ast_custom_function volume_function

Detailed Description

Technology independent volume control.

Author:
Joshua Colp <jcolp@digium.com>

Definition in file func_volume.c.


Enumeration Type Documentation

Enumerator:
VOLUMEFLAG_CHANGE 

Definition at line 80 of file func_volume.c.

00080                   {
00081    VOLUMEFLAG_CHANGE = (1 << 1),
00082 };


Function Documentation

AST_APP_OPTIONS ( volume_opts   ) 
AST_MODULE_INFO_STANDARD ( ASTERISK_GPL_KEY  ,
"Technology independent volume control"   
)
static void destroy_callback ( void *  data  )  [static]

Definition at line 88 of file func_volume.c.

References ast_audiohook_destroy(), ast_audiohook_detach(), ast_audiohook_lock, ast_audiohook_unlock, ast_free, and volume_information::audiohook.

00089 {
00090    struct volume_information *vi = data;
00091 
00092    /* Destroy the audiohook, and destroy ourselves */
00093    ast_audiohook_lock(&vi->audiohook);
00094    ast_audiohook_detach(&vi->audiohook);
00095    ast_audiohook_unlock(&vi->audiohook);
00096    ast_audiohook_destroy(&vi->audiohook);
00097    ast_free(vi);
00098 
00099    return;
00100 }

static int load_module ( void   )  [static]

Definition at line 231 of file func_volume.c.

References ast_custom_function_register.

00232 {
00233    return ast_custom_function_register(&volume_function);
00234 }

static int unload_module ( void   )  [static]

Definition at line 226 of file func_volume.c.

References ast_custom_function_unregister().

00227 {
00228    return ast_custom_function_unregister(&volume_function);
00229 }

static int volume_callback ( struct ast_audiohook audiohook,
struct ast_channel chan,
struct ast_frame frame,
enum ast_audiohook_direction  direction 
) [static]

Definition at line 108 of file func_volume.c.

References AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_STATUS_DONE, ast_channel_datastore_find(), ast_frame_adjust_volume(), AST_FRAME_DTMF, AST_FRAME_VOICE, ast_test_flag, ast_datastore::data, ast_frame::frametype, ast_frame_subclass::integer, volume_information::rx_gain, ast_audiohook::status, ast_frame::subclass, volume_information::tx_gain, and VOLUMEFLAG_CHANGE.

Referenced by volume_write().

00109 {
00110    struct ast_datastore *datastore = NULL;
00111    struct volume_information *vi = NULL;
00112    int *gain = NULL;
00113 
00114    /* If the audiohook is stopping it means the channel is shutting down.... but we let the datastore destroy take care of it */
00115    if (audiohook->status == AST_AUDIOHOOK_STATUS_DONE)
00116       return 0;
00117 
00118    /* Grab datastore which contains our gain information */
00119    if (!(datastore = ast_channel_datastore_find(chan, &volume_datastore, NULL)))
00120       return 0;
00121 
00122    vi = datastore->data;
00123 
00124    /* If this is DTMF then allow them to increase/decrease the gains */
00125    if (ast_test_flag(vi, VOLUMEFLAG_CHANGE)) {
00126       if (frame->frametype == AST_FRAME_DTMF) {
00127          /* Only use DTMF coming from the source... not going to it */
00128          if (direction != AST_AUDIOHOOK_DIRECTION_READ)
00129             return 0; 
00130          if (frame->subclass.integer == '*') {
00131             vi->tx_gain += 1;
00132             vi->rx_gain += 1;
00133          } else if (frame->subclass.integer == '#') {
00134             vi->tx_gain -= 1;
00135             vi->rx_gain -= 1;
00136          }
00137       }
00138    }
00139 
00140    
00141    if (frame->frametype == AST_FRAME_VOICE) {
00142       /* Based on direction of frame grab the gain, and confirm it is applicable */
00143       if (!(gain = (direction == AST_AUDIOHOOK_DIRECTION_READ) ? &vi->rx_gain : &vi->tx_gain) || !*gain)
00144          return 0;
00145       /* Apply gain to frame... easy as pi */
00146       ast_frame_adjust_volume(frame, *gain);
00147    }
00148 
00149    return 0;
00150 }

static int volume_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
) [static]

Definition at line 152 of file func_volume.c.

References args, AST_APP_ARG, ast_app_parse_options(), ast_audiohook_attach(), ast_audiohook_init(), AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_WANTS_DTMF, ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_datastore_alloc, ast_datastore_free(), AST_DECLARE_APP_ARGS, ast_log(), ast_set_flag, AST_STANDARD_APP_ARGS, ast_strlen_zero(), volume_information::audiohook, ast_datastore::data, ast_flags::flags, volume_information::flags, LOG_ERROR, ast_audiohook::manipulate_callback, volume_information::rx_gain, volume_information::tx_gain, and volume_callback().

00153 {
00154    struct ast_datastore *datastore = NULL;
00155    struct volume_information *vi = NULL;
00156    int is_new = 0;
00157 
00158    /* Separate options from argument */
00159    
00160    AST_DECLARE_APP_ARGS(args,
00161       AST_APP_ARG(direction);
00162       AST_APP_ARG(options);
00163    );
00164    
00165    AST_STANDARD_APP_ARGS(args, data);
00166 
00167    ast_channel_lock(chan);
00168    if (!(datastore = ast_channel_datastore_find(chan, &volume_datastore, NULL))) {
00169       ast_channel_unlock(chan);
00170       /* Allocate a new datastore to hold the reference to this volume and audiohook information */
00171       if (!(datastore = ast_datastore_alloc(&volume_datastore, NULL)))
00172          return 0;
00173       if (!(vi = ast_calloc(1, sizeof(*vi)))) {
00174          ast_datastore_free(datastore);
00175          return 0;
00176       }
00177       ast_audiohook_init(&vi->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "Volume");
00178       vi->audiohook.manipulate_callback = volume_callback;
00179       ast_set_flag(&vi->audiohook, AST_AUDIOHOOK_WANTS_DTMF);
00180       is_new = 1;
00181    } else {
00182       ast_channel_unlock(chan);
00183       vi = datastore->data;
00184    }
00185 
00186    /* Adjust gain on volume information structure */
00187    if (ast_strlen_zero(args.direction)) {
00188       ast_log(LOG_ERROR, "Direction must be specified for VOLUME function\n");
00189       return -1;
00190    }
00191 
00192    if (!strcasecmp(args.direction, "tx")) { 
00193       vi->tx_gain = atoi(value); 
00194    } else if (!strcasecmp(args.direction, "rx")) {
00195       vi->rx_gain = atoi(value);
00196    } else {
00197       ast_log(LOG_ERROR, "Direction must be either RX or TX\n");
00198    }
00199 
00200    if (is_new) {
00201       datastore->data = vi;
00202       ast_channel_lock(chan);
00203       ast_channel_datastore_add(chan, datastore);
00204       ast_channel_unlock(chan);
00205       ast_audiohook_attach(chan, &vi->audiohook);
00206    }
00207 
00208    /* Add Option data to struct */
00209    
00210    if (!ast_strlen_zero(args.options)) {
00211       struct ast_flags flags = { 0 };
00212       ast_app_parse_options(volume_opts, &flags, NULL, args.options);
00213       vi->flags = flags.flags;
00214    } else { 
00215       vi->flags = 0; 
00216    }
00217 
00218    return 0;
00219 }


Variable Documentation

Initial value:
 {
   .type = "volume",
   .destroy = destroy_callback
}

Static structure for datastore information.

Definition at line 103 of file func_volume.c.

Initial value:
 {
   .name = "VOLUME",
   .write = volume_write,
}

Definition at line 221 of file func_volume.c.


Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1