Wed Jan 27 20:02:40 2016

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 236 of file func_volume.c.

References ast_custom_function_register.

00237 {
00238    return ast_custom_function_register(&volume_function);
00239 }

static int unload_module ( void   )  [static]

Definition at line 231 of file func_volume.c.

References ast_custom_function_unregister().

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

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, LOG_WARNING, 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    if (!chan) {
00166       ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
00167       return -1;
00168    }
00169 
00170    AST_STANDARD_APP_ARGS(args, data);
00171 
00172    ast_channel_lock(chan);
00173    if (!(datastore = ast_channel_datastore_find(chan, &volume_datastore, NULL))) {
00174       ast_channel_unlock(chan);
00175       /* Allocate a new datastore to hold the reference to this volume and audiohook information */
00176       if (!(datastore = ast_datastore_alloc(&volume_datastore, NULL)))
00177          return 0;
00178       if (!(vi = ast_calloc(1, sizeof(*vi)))) {
00179          ast_datastore_free(datastore);
00180          return 0;
00181       }
00182       ast_audiohook_init(&vi->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "Volume");
00183       vi->audiohook.manipulate_callback = volume_callback;
00184       ast_set_flag(&vi->audiohook, AST_AUDIOHOOK_WANTS_DTMF);
00185       is_new = 1;
00186    } else {
00187       ast_channel_unlock(chan);
00188       vi = datastore->data;
00189    }
00190 
00191    /* Adjust gain on volume information structure */
00192    if (ast_strlen_zero(args.direction)) {
00193       ast_log(LOG_ERROR, "Direction must be specified for VOLUME function\n");
00194       return -1;
00195    }
00196 
00197    if (!strcasecmp(args.direction, "tx")) { 
00198       vi->tx_gain = atoi(value); 
00199    } else if (!strcasecmp(args.direction, "rx")) {
00200       vi->rx_gain = atoi(value);
00201    } else {
00202       ast_log(LOG_ERROR, "Direction must be either RX or TX\n");
00203    }
00204 
00205    if (is_new) {
00206       datastore->data = vi;
00207       ast_channel_lock(chan);
00208       ast_channel_datastore_add(chan, datastore);
00209       ast_channel_unlock(chan);
00210       ast_audiohook_attach(chan, &vi->audiohook);
00211    }
00212 
00213    /* Add Option data to struct */
00214    
00215    if (!ast_strlen_zero(args.options)) {
00216       struct ast_flags flags = { 0 };
00217       ast_app_parse_options(volume_opts, &flags, NULL, args.options);
00218       vi->flags = flags.flags;
00219    } else { 
00220       vi->flags = 0; 
00221    }
00222 
00223    return 0;
00224 }


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 226 of file func_volume.c.


Generated on 27 Jan 2016 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1