Wed Apr 6 11:29:53 2011

Asterisk developer's documentation


audiohook.h File Reference

Audiohooks Architecture. More...

#include "asterisk/lock.h"
#include "asterisk/linkedlists.h"
#include "asterisk/frame_defs.h"
#include "asterisk/slinfactory.h"

Go to the source code of this file.

Data Structures

struct  ast_audiohook
struct  ast_audiohook_options

Defines

#define ast_audiohook_lock(ah)   ast_mutex_lock(&(ah)->lock)
 Lock an audiohook.
#define AST_AUDIOHOOK_SYNC_TOLERANCE   100
#define ast_audiohook_unlock(ah)   ast_mutex_unlock(&(ah)->lock)
 Unlock an audiohook.

Typedefs

typedef int(*) ast_audiohook_manipulate_callback (struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction)
 Callback function for manipulate audiohook type.

Enumerations

enum  ast_audiohook_direction { AST_AUDIOHOOK_DIRECTION_READ = 0, AST_AUDIOHOOK_DIRECTION_WRITE, AST_AUDIOHOOK_DIRECTION_BOTH }
enum  ast_audiohook_flags {
  AST_AUDIOHOOK_TRIGGER_MODE = (3 << 0), AST_AUDIOHOOK_TRIGGER_READ = (1 << 0), AST_AUDIOHOOK_TRIGGER_WRITE = (2 << 0), AST_AUDIOHOOK_WANTS_DTMF = (1 << 1),
  AST_AUDIOHOOK_TRIGGER_SYNC = (1 << 2), AST_AUDIOHOOK_SMALL_QUEUE = (1 << 3), AST_AUDIOHOOK_MUTE_READ = (1 << 4), AST_AUDIOHOOK_MUTE_WRITE = (1 << 5)
}
enum  ast_audiohook_status { AST_AUDIOHOOK_STATUS_NEW = 0, AST_AUDIOHOOK_STATUS_RUNNING, AST_AUDIOHOOK_STATUS_SHUTDOWN, AST_AUDIOHOOK_STATUS_DONE }
enum  ast_audiohook_type { AST_AUDIOHOOK_TYPE_SPY = 0, AST_AUDIOHOOK_TYPE_WHISPER, AST_AUDIOHOOK_TYPE_MANIPULATE }

Functions

int ast_audiohook_attach (struct ast_channel *chan, struct ast_audiohook *audiohook)
 Attach audiohook to channel.
int ast_audiohook_destroy (struct ast_audiohook *audiohook)
 Destroys an audiohook structure.
int ast_audiohook_detach (struct ast_audiohook *audiohook)
 Detach audiohook from channel.
int ast_audiohook_detach_list (struct ast_audiohook_list *audiohook_list)
 Detach audiohooks from list and destroy said list.
int ast_audiohook_detach_source (struct ast_channel *chan, const char *source)
 Detach specified source audiohook from channel.
int ast_audiohook_init (struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source)
 Initialize an audiohook structure.
void ast_audiohook_move_by_source (struct ast_channel *old_chan, struct ast_channel *new_chan, const char *source)
 Move an audiohook from one channel to a new one.
ast_frameast_audiohook_read_frame (struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, format_t format)
 Reads a frame in from the audiohook structure.
int ast_audiohook_remove (struct ast_channel *chan, struct ast_audiohook *audiohook)
 Remove an audiohook from a specified channel.
int ast_audiohook_set_mute (struct ast_channel *chan, const char *source, enum ast_audiohook_flags flag, int clear)
 Mute frames read from or written to a channel.
void ast_audiohook_trigger_wait (struct ast_audiohook *audiohook)
 Wait for audiohook trigger to be triggered.
void ast_audiohook_update_status (struct ast_audiohook *audiohook, enum ast_audiohook_status status)
 Update audiohook's status.
int ast_audiohook_volume_adjust (struct ast_channel *chan, enum ast_audiohook_direction direction, int volume)
 Adjust the volume on frames read from or written to a channel.
int ast_audiohook_volume_get (struct ast_channel *chan, enum ast_audiohook_direction direction)
 Retrieve the volume adjustment value on frames read from or written to a channel.
int ast_audiohook_volume_set (struct ast_channel *chan, enum ast_audiohook_direction direction, int volume)
 Adjust the volume on frames read from or written to a channel.
int ast_audiohook_write_frame (struct ast_audiohook *audiohook, enum ast_audiohook_direction direction, struct ast_frame *frame)
 Writes a frame into the audiohook structure.
ast_frameast_audiohook_write_list (struct ast_channel *chan, struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame)
 Pass a frame off to be handled by the audiohook core.
int ast_audiohook_write_list_empty (struct ast_audiohook_list *audiohook_list)
 determines if a audiohook_list is empty or not.
int ast_channel_audiohook_count_by_source (struct ast_channel *chan, const char *source, enum ast_audiohook_type type)
 Find out how many audiohooks from a certain source exist on a given channel, regardless of status.
int ast_channel_audiohook_count_by_source_running (struct ast_channel *chan, const char *source, enum ast_audiohook_type type)
 Find out how many spies of a certain type exist on a given channel, and are in state running.


Detailed Description

Audiohooks Architecture.

Definition in file audiohook.h.


Define Documentation

#define ast_audiohook_lock ( ah   )     ast_mutex_lock(&(ah)->lock)

Lock an audiohook.

Parameters:
ah Audiohook structure

Definition at line 260 of file audiohook.h.

Referenced by ast_audiohook_move_by_source(), ast_audiohook_update_status(), audio_audiohook_write_list(), channel_spy(), destroy_monitor_audiohook(), dtmf_audiohook_write_list(), mixmonitor_thread(), spy_generate(), and stop_mixmonitor_exec().

#define AST_AUDIOHOOK_SYNC_TOLERANCE   100

Definition at line 69 of file audiohook.h.

Referenced by ast_audiohook_write_frame().

#define ast_audiohook_unlock ( ah   )     ast_mutex_unlock(&(ah)->lock)

Unlock an audiohook.

Parameters:
ah Audiohook structure

Definition at line 265 of file audiohook.h.

Referenced by ast_audiohook_move_by_source(), ast_audiohook_update_status(), audio_audiohook_write_list(), channel_spy(), destroy_monitor_audiohook(), dtmf_audiohook_write_list(), mixmonitor_thread(), spy_generate(), and stop_mixmonitor_exec().


Typedef Documentation

typedef int(*) ast_audiohook_manipulate_callback(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction)

Callback function for manipulate audiohook type.

Parameters:
audiohook Audiohook structure
chan Channel
frame Frame of audio to manipulate
direction Direction frame came from
Returns:
Returns 0 on success, -1 on failure.
Note:
An audiohook does not have any reference to a private data structure for manipulate types. It is up to the manipulate callback to store this data via it's own method. An example would be datastores.

The input frame should never be freed or corrupted during a manipulate callback. If the callback has the potential to corrupt the frame's data during manipulation, local data should be used for the manipulation and only copied to the frame on success.

A failure return value indicates that the frame was not manipulated and that is being returned in its original state.

Definition at line 89 of file audiohook.h.


Enumeration Type Documentation

enum ast_audiohook_direction

Enumerator:
AST_AUDIOHOOK_DIRECTION_READ  Reading audio in
AST_AUDIOHOOK_DIRECTION_WRITE  Writing audio out
AST_AUDIOHOOK_DIRECTION_BOTH  Both reading audio in and writing audio out

Definition at line 49 of file audiohook.h.

00049                              {
00050    AST_AUDIOHOOK_DIRECTION_READ = 0, /*!< Reading audio in */
00051    AST_AUDIOHOOK_DIRECTION_WRITE,    /*!< Writing audio out */
00052    AST_AUDIOHOOK_DIRECTION_BOTH,     /*!< Both reading audio in and writing audio out */
00053 };

enum ast_audiohook_flags

Enumerator:
AST_AUDIOHOOK_TRIGGER_MODE  When audiohook should be triggered to do something
AST_AUDIOHOOK_TRIGGER_READ  Audiohook wants to be triggered when reading audio in
AST_AUDIOHOOK_TRIGGER_WRITE  Audiohook wants to be triggered when writing audio out
AST_AUDIOHOOK_WANTS_DTMF  Audiohook also wants to receive DTMF frames
AST_AUDIOHOOK_TRIGGER_SYNC  Audiohook wants to be triggered when both sides have combined audio available
AST_AUDIOHOOK_SMALL_QUEUE  Audiohooks with this flag set will not allow for a large amount of samples to build up on its slinfactories. We will flush the factories if they contain too many samples.
AST_AUDIOHOOK_MUTE_READ  audiohook should be mute frames read
AST_AUDIOHOOK_MUTE_WRITE  audiohook should be mute frames written

Definition at line 55 of file audiohook.h.

00055                          {
00056    AST_AUDIOHOOK_TRIGGER_MODE = (3 << 0),  /*!< When audiohook should be triggered to do something */
00057    AST_AUDIOHOOK_TRIGGER_READ = (1 << 0),  /*!< Audiohook wants to be triggered when reading audio in */
00058    AST_AUDIOHOOK_TRIGGER_WRITE = (2 << 0), /*!< Audiohook wants to be triggered when writing audio out */
00059    AST_AUDIOHOOK_WANTS_DTMF = (1 << 1),    /*!< Audiohook also wants to receive DTMF frames */
00060    AST_AUDIOHOOK_TRIGGER_SYNC = (1 << 2),  /*!< Audiohook wants to be triggered when both sides have combined audio available */
00061    /*! Audiohooks with this flag set will not allow for a large amount of samples to build up on its
00062     * slinfactories. We will flush the factories if they contain too many samples.
00063     */
00064    AST_AUDIOHOOK_SMALL_QUEUE = (1 << 3),
00065    AST_AUDIOHOOK_MUTE_READ = (1 << 4),     /*!< audiohook should be mute frames read */
00066    AST_AUDIOHOOK_MUTE_WRITE = (1 << 5),    /*!< audiohook should be mute frames written */
00067 };

enum ast_audiohook_status

Enumerator:
AST_AUDIOHOOK_STATUS_NEW  Audiohook was just created, not in use yet
AST_AUDIOHOOK_STATUS_RUNNING  Audiohook is running on a channel
AST_AUDIOHOOK_STATUS_SHUTDOWN  Audiohook is being shutdown
AST_AUDIOHOOK_STATUS_DONE  Audiohook has shutdown and is not running on a channel any longer

Definition at line 42 of file audiohook.h.

00042                           {
00043    AST_AUDIOHOOK_STATUS_NEW = 0,  /*!< Audiohook was just created, not in use yet */
00044    AST_AUDIOHOOK_STATUS_RUNNING,  /*!< Audiohook is running on a channel */
00045    AST_AUDIOHOOK_STATUS_SHUTDOWN, /*!< Audiohook is being shutdown */
00046    AST_AUDIOHOOK_STATUS_DONE,     /*!< Audiohook has shutdown and is not running on a channel any longer */
00047 };

enum ast_audiohook_type

Enumerator:
AST_AUDIOHOOK_TYPE_SPY  Audiohook wants to receive audio
AST_AUDIOHOOK_TYPE_WHISPER  Audiohook wants to provide audio to be mixed with existing audio
AST_AUDIOHOOK_TYPE_MANIPULATE  Audiohook wants to manipulate the audio

Definition at line 36 of file audiohook.h.

00036                         {
00037    AST_AUDIOHOOK_TYPE_SPY = 0,    /*!< Audiohook wants to receive audio */
00038    AST_AUDIOHOOK_TYPE_WHISPER,    /*!< Audiohook wants to provide audio to be mixed with existing audio */
00039    AST_AUDIOHOOK_TYPE_MANIPULATE, /*!< Audiohook wants to manipulate the audio */
00040 };


Function Documentation

int ast_audiohook_attach ( struct ast_channel chan,
struct ast_audiohook audiohook 
)

Attach audiohook to channel.

Parameters:
chan Channel
audiohook Audiohook structure
Returns:
Returns 0 on success, -1 on failure

Definition at line 342 of file audiohook.c.

References AST_AUDIOHOOK_STATUS_RUNNING, AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_audiohook_update_status(), ast_calloc, ast_channel_lock, ast_channel_unlock, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_TAIL, ast_channel::audiohooks, ast_audiohook_list::manipulate_list, ast_audiohook_list::spy_list, ast_audiohook::type, and ast_audiohook_list::whisper_list.

Referenced by ast_audiohook_move_by_source(), audiohook_volume_get(), enable_jack_hook(), mute_add_audiohook(), pitchshift_helper(), speex_write(), start_spying(), startmon(), and volume_write().

00343 {
00344    ast_channel_lock(chan);
00345 
00346    if (!chan->audiohooks) {
00347       /* Whoops... allocate a new structure */
00348       if (!(chan->audiohooks = ast_calloc(1, sizeof(*chan->audiohooks)))) {
00349          ast_channel_unlock(chan);
00350          return -1;
00351       }
00352       AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->spy_list);
00353       AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->whisper_list);
00354       AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->manipulate_list);
00355    }
00356 
00357    /* Drop into respective list */
00358    if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY)
00359       AST_LIST_INSERT_TAIL(&chan->audiohooks->spy_list, audiohook, list);
00360    else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER)
00361       AST_LIST_INSERT_TAIL(&chan->audiohooks->whisper_list, audiohook, list);
00362    else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE)
00363       AST_LIST_INSERT_TAIL(&chan->audiohooks->manipulate_list, audiohook, list);
00364 
00365    /* Change status over to running since it is now attached */
00366    ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_RUNNING);
00367 
00368    ast_channel_unlock(chan);
00369 
00370    return 0;
00371 }

int ast_audiohook_destroy ( struct ast_audiohook audiohook  ) 

Destroys an audiohook structure.

Parameters:
audiohook Audiohook structure
Returns:
Returns 0 on success, -1 on failure

Definition at line 91 of file audiohook.c.

References AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_cond_destroy, ast_mutex_destroy, ast_slinfactory_destroy(), ast_translator_free_path(), ast_audiohook::lock, ast_audiohook::read_factory, ast_audiohook::trans_pvt, ast_audiohook::trigger, ast_audiohook::type, and ast_audiohook::write_factory.

Referenced by audiohook_volume_destroy(), channel_spy(), destroy_callback(), destroy_jack_data(), destroy_monitor_audiohook(), and launch_monitor_thread().

00092 {
00093    /* Drop the factories used by this audiohook type */
00094    switch (audiohook->type) {
00095    case AST_AUDIOHOOK_TYPE_SPY:
00096       ast_slinfactory_destroy(&audiohook->read_factory);
00097    case AST_AUDIOHOOK_TYPE_WHISPER:
00098       ast_slinfactory_destroy(&audiohook->write_factory);
00099       break;
00100    default:
00101       break;
00102    }
00103 
00104    /* Destroy translation path if present */
00105    if (audiohook->trans_pvt)
00106       ast_translator_free_path(audiohook->trans_pvt);
00107 
00108    /* Lock and trigger be gone! */
00109    ast_cond_destroy(&audiohook->trigger);
00110    ast_mutex_destroy(&audiohook->lock);
00111 
00112    return 0;
00113 }

int ast_audiohook_detach ( struct ast_audiohook audiohook  ) 

Detach audiohook from channel.

Parameters:
audiohook Audiohook structure
Returns:
Returns 0 on success, -1 on failure

Definition at line 395 of file audiohook.c.

References AST_AUDIOHOOK_STATUS_DONE, AST_AUDIOHOOK_STATUS_NEW, AST_AUDIOHOOK_STATUS_SHUTDOWN, ast_audiohook_trigger_wait(), ast_audiohook_update_status(), and ast_audiohook::status.

Referenced by channel_spy(), destroy_monitor_audiohook(), disable_jack_hook(), and speex_write().

00396 {
00397    if (audiohook->status == AST_AUDIOHOOK_STATUS_NEW || audiohook->status == AST_AUDIOHOOK_STATUS_DONE)
00398       return 0;
00399 
00400    ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_SHUTDOWN);
00401 
00402    while (audiohook->status != AST_AUDIOHOOK_STATUS_DONE)
00403       ast_audiohook_trigger_wait(audiohook);
00404 
00405    return 0;
00406 }

int ast_audiohook_detach_list ( struct ast_audiohook_list audiohook_list  ) 

Detach audiohooks from list and destroy said list.

Parameters:
audiohook_list List of audiohooks
Returns:
Returns 0 on success, -1 on failure

Definition at line 412 of file audiohook.c.

References AST_AUDIOHOOK_STATUS_DONE, ast_audiohook_update_status(), ast_free, AST_LIST_REMOVE_HEAD, ast_translator_free_path(), ast_audiohook_list::in_translate, ast_audiohook::list, ast_audiohook_list::manipulate_list, ast_audiohook_list::out_translate, ast_audiohook_list::spy_list, ast_audiohook_translate::trans_pvt, and ast_audiohook_list::whisper_list.

Referenced by __ast_read(), ast_hangup(), and ast_write().

00413 {
00414    int i = 0;
00415    struct ast_audiohook *audiohook = NULL;
00416 
00417    /* Drop any spies */
00418    while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->spy_list, list))) {
00419       ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
00420    }
00421 
00422    /* Drop any whispering sources */
00423    while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->whisper_list, list))) {
00424       ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
00425    }
00426 
00427    /* Drop any manipulaters */
00428    while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->manipulate_list, list))) {
00429       ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
00430       audiohook->manipulate_callback(audiohook, NULL, NULL, 0);
00431    }
00432 
00433    /* Drop translation paths if present */
00434    for (i = 0; i < 2; i++) {
00435       if (audiohook_list->in_translate[i].trans_pvt)
00436          ast_translator_free_path(audiohook_list->in_translate[i].trans_pvt);
00437       if (audiohook_list->out_translate[i].trans_pvt)
00438          ast_translator_free_path(audiohook_list->out_translate[i].trans_pvt);
00439    }
00440    
00441    /* Free ourselves */
00442    ast_free(audiohook_list);
00443 
00444    return 0;
00445 }

int ast_audiohook_detach_source ( struct ast_channel chan,
const char *  source 
)

Detach specified source audiohook from channel.

Parameters:
chan Channel to detach from
source Name of source to detach
Returns:
Returns 0 on success, -1 on failure

Definition at line 503 of file audiohook.c.

References AST_AUDIOHOOK_STATUS_DONE, AST_AUDIOHOOK_STATUS_SHUTDOWN, ast_audiohook_update_status(), ast_channel_lock, ast_channel_unlock, ast_channel::audiohooks, find_audiohook_by_source(), and ast_audiohook::status.

Referenced by handle_cli_mixmonitor(), and stop_mixmonitor_exec().

00504 {
00505    struct ast_audiohook *audiohook = NULL;
00506 
00507    ast_channel_lock(chan);
00508 
00509    /* Ensure the channel has audiohooks on it */
00510    if (!chan->audiohooks) {
00511       ast_channel_unlock(chan);
00512       return -1;
00513    }
00514 
00515    audiohook = find_audiohook_by_source(chan->audiohooks, source);
00516 
00517    ast_channel_unlock(chan);
00518 
00519    if (audiohook && audiohook->status != AST_AUDIOHOOK_STATUS_DONE)
00520       ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_SHUTDOWN);
00521 
00522    return (audiohook ? 0 : -1);
00523 }

int ast_audiohook_init ( struct ast_audiohook audiohook,
enum ast_audiohook_type  type,
const char *  source 
)

Initialize an audiohook structure.

Parameters:
audiohook Audiohook structure
type 
source 
Returns:
Returns 0 on success, -1 on failure

Definition at line 60 of file audiohook.c.

References AST_AUDIOHOOK_STATUS_NEW, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_audiohook_update_status(), ast_cond_init, ast_mutex_init, and ast_slinfactory_init().

Referenced by audiohook_volume_get(), channel_spy(), enable_jack_hook(), initialize_mutehook(), launch_monitor_thread(), pitchshift_helper(), speex_write(), and volume_write().

00061 {
00062    /* Need to keep the type and source */
00063    audiohook->type = type;
00064    audiohook->source = source;
00065 
00066    /* Initialize lock that protects our audiohook */
00067    ast_mutex_init(&audiohook->lock);
00068    ast_cond_init(&audiohook->trigger, NULL);
00069 
00070    /* Setup the factories that are needed for this audiohook type */
00071    switch (type) {
00072    case AST_AUDIOHOOK_TYPE_SPY:
00073       ast_slinfactory_init(&audiohook->read_factory);
00074    case AST_AUDIOHOOK_TYPE_WHISPER:
00075       ast_slinfactory_init(&audiohook->write_factory);
00076       break;
00077    default:
00078       break;
00079    }
00080 
00081    /* Since we are just starting out... this audiohook is new */
00082    ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_NEW);
00083 
00084    return 0;
00085 }

void ast_audiohook_move_by_source ( struct ast_channel old_chan,
struct ast_channel new_chan,
const char *  source 
)

Move an audiohook from one channel to a new one.

Todo:
Currently only the first audiohook of a specific source found will be moved. We should add the capability to move multiple audiohooks from a single source as well.
Note:
It is required that both old_chan and new_chan are locked prior to calling this function. Besides needing to protect the data within the channels, not locking these channels can lead to a potential deadlock
Parameters:
old_chan The source of the audiohook to move
new_chan The destination to which we want the audiohook to move
source The source of the audiohook we want to move

Definition at line 474 of file audiohook.c.

References ast_audiohook_attach(), ast_audiohook_lock, ast_audiohook_remove(), ast_audiohook_unlock, ast_channel::audiohooks, find_audiohook_by_source(), and ast_audiohook::status.

Referenced by audiohook_inheritance_fixup().

00475 {
00476    struct ast_audiohook *audiohook;
00477    enum ast_audiohook_status oldstatus;
00478 
00479    if (!old_chan->audiohooks || !(audiohook = find_audiohook_by_source(old_chan->audiohooks, source))) {
00480       return;
00481    }
00482 
00483    /* By locking both channels and the audiohook, we can assure that
00484     * another thread will not have a chance to read the audiohook's status
00485     * as done, even though ast_audiohook_remove signals the trigger
00486     * condition.
00487     */
00488    ast_audiohook_lock(audiohook);
00489    oldstatus = audiohook->status;
00490 
00491    ast_audiohook_remove(old_chan, audiohook);
00492    ast_audiohook_attach(new_chan, audiohook);
00493 
00494    audiohook->status = oldstatus;
00495    ast_audiohook_unlock(audiohook);
00496 }

struct ast_frame* ast_audiohook_read_frame ( struct ast_audiohook audiohook,
size_t  samples,
enum ast_audiohook_direction  direction,
format_t  format 
)

Reads a frame in from the audiohook structure.

Parameters:
audiohook Audiohook structure
samples Number of samples wanted
direction Direction the audio frame came from
format Format of frame remote side wants back
Returns:
Returns frame on success, NULL on failure

Definition at line 307 of file audiohook.c.

References AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR, ast_frfree, ast_translate(), ast_translator_build_path(), ast_translator_free_path(), audiohook_read_frame_both(), audiohook_read_frame_single(), and read_frame().

Referenced by mixmonitor_thread(), and spy_generate().

00308 {
00309    struct ast_frame *read_frame = NULL, *final_frame = NULL;
00310 
00311    if (!(read_frame = (direction == AST_AUDIOHOOK_DIRECTION_BOTH ? audiohook_read_frame_both(audiohook, samples) : audiohook_read_frame_single(audiohook, samples, direction))))
00312       return NULL;
00313 
00314    /* If they don't want signed linear back out, we'll have to send it through the translation path */
00315    if (format != AST_FORMAT_SLINEAR) {
00316       /* Rebuild translation path if different format then previously */
00317       if (audiohook->format != format) {
00318          if (audiohook->trans_pvt) {
00319             ast_translator_free_path(audiohook->trans_pvt);
00320             audiohook->trans_pvt = NULL;
00321          }
00322          /* Setup new translation path for this format... if we fail we can't very well return signed linear so free the frame and return nothing */
00323          if (!(audiohook->trans_pvt = ast_translator_build_path(format, AST_FORMAT_SLINEAR))) {
00324             ast_frfree(read_frame);
00325             return NULL;
00326          }
00327       }
00328       /* Convert to requested format, and allow the read in frame to be freed */
00329       final_frame = ast_translate(audiohook->trans_pvt, read_frame, 1);
00330    } else {
00331       final_frame = read_frame;
00332    }
00333 
00334    return final_frame;
00335 }

int ast_audiohook_remove ( struct ast_channel chan,
struct ast_audiohook audiohook 
)

Remove an audiohook from a specified channel.

Parameters:
chan Channel to remove from
audiohook Audiohook to remove
Returns:
Returns 0 on success, -1 on failure
Note:
The channel does not need to be locked before calling this function

Definition at line 535 of file audiohook.c.

References AST_AUDIOHOOK_STATUS_DONE, AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_audiohook_update_status(), ast_channel_lock, ast_channel_unlock, AST_LIST_REMOVE, ast_channel::audiohooks, ast_audiohook::list, ast_audiohook_list::manipulate_list, ast_audiohook_list::spy_list, ast_audiohook::type, and ast_audiohook_list::whisper_list.

Referenced by ast_audiohook_move_by_source(), and speex_write().

00536 {
00537    ast_channel_lock(chan);
00538 
00539    if (!chan->audiohooks) {
00540       ast_channel_unlock(chan);
00541       return -1;
00542    }
00543 
00544    if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY)
00545       AST_LIST_REMOVE(&chan->audiohooks->spy_list, audiohook, list);
00546    else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER)
00547       AST_LIST_REMOVE(&chan->audiohooks->whisper_list, audiohook, list);
00548    else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE)
00549       AST_LIST_REMOVE(&chan->audiohooks->manipulate_list, audiohook, list);
00550 
00551    ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
00552 
00553    ast_channel_unlock(chan);
00554 
00555    return 0;
00556 }

int ast_audiohook_set_mute ( struct ast_channel chan,
const char *  source,
enum ast_audiohook_flags  flag,
int  clear 
)

Mute frames read from or written to a channel.

Parameters:
chan Channel to muck with
source Type of audiohook
flag which flag to set / clear
clear set or clear
Returns:
Returns 0 on success, -1 on failure

Definition at line 1057 of file audiohook.c.

References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_set_flag, ast_channel::audiohooks, and find_audiohook_by_source().

Referenced by manager_mute_mixmonitor().

01058 {
01059    struct ast_audiohook *audiohook = NULL;
01060 
01061    ast_channel_lock(chan);
01062 
01063    /* Ensure the channel has audiohooks on it */
01064    if (!chan->audiohooks) {
01065       ast_channel_unlock(chan);
01066       return -1;
01067    }
01068 
01069    audiohook = find_audiohook_by_source(chan->audiohooks, source);
01070 
01071    if (audiohook) {
01072       if (clear) {
01073          ast_clear_flag(audiohook, flag);
01074       } else {
01075          ast_set_flag(audiohook, flag);
01076       }
01077    }
01078 
01079    ast_channel_unlock(chan);
01080 
01081    return (audiohook ? 0 : -1);
01082 }

void ast_audiohook_trigger_wait ( struct ast_audiohook audiohook  ) 

Wait for audiohook trigger to be triggered.

Parameters:
audiohook Audiohook to wait on

Definition at line 770 of file audiohook.c.

References ast_cond_timedwait, ast_samp2tv(), ast_tvadd(), ast_tvnow(), ast_audiohook::lock, and ast_audiohook::trigger.

Referenced by ast_audiohook_detach(), and mixmonitor_thread().

00771 {
00772    struct timeval wait;
00773    struct timespec ts;
00774 
00775    wait = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000));
00776    ts.tv_sec = wait.tv_sec;
00777    ts.tv_nsec = wait.tv_usec * 1000;
00778    
00779    ast_cond_timedwait(&audiohook->trigger, &audiohook->lock, &ts);
00780    
00781    return;
00782 }

void ast_audiohook_update_status ( struct ast_audiohook audiohook,
enum ast_audiohook_status  status 
)

Update audiohook's status.

Parameters:
audiohook Audiohook structure
status Audiohook status enum
Note:
once status is updated to DONE, this function can not be used to set the status back to any other setting. Setting DONE effectively locks the status as such.

Definition at line 381 of file audiohook.c.

References ast_audiohook_lock, AST_AUDIOHOOK_STATUS_DONE, ast_audiohook_unlock, ast_cond_signal, ast_audiohook::status, and ast_audiohook::trigger.

Referenced by ast_audiohook_attach(), ast_audiohook_detach(), ast_audiohook_detach_list(), ast_audiohook_detach_source(), ast_audiohook_init(), ast_audiohook_remove(), audio_audiohook_write_list(), and dtmf_audiohook_write_list().

00382 {
00383    ast_audiohook_lock(audiohook);
00384    if (audiohook->status != AST_AUDIOHOOK_STATUS_DONE) {
00385       audiohook->status = status;
00386       ast_cond_signal(&audiohook->trigger);
00387    }
00388    ast_audiohook_unlock(audiohook);
00389 }

int ast_audiohook_volume_adjust ( struct ast_channel chan,
enum ast_audiohook_direction  direction,
int  volume 
)

Adjust the volume on frames read from or written to a channel.

Parameters:
chan Channel to muck with
direction Direction to increase
volume Value to adjust the adjustment by
Returns:
Returns 0 on success, -1 on failure

Definition at line 1030 of file audiohook.c.

References AST_AUDIOHOOK_DIRECTION_BOTH, AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, audiohook_volume_get(), audiohook_volume::read_adjustment, and audiohook_volume::write_adjustment.

Referenced by menu_callback().

01031 {
01032    struct audiohook_volume *audiohook_volume = NULL;
01033 
01034    /* Attempt to find the audiohook volume information, and create an audiohook if none exists */
01035    if (!(audiohook_volume = audiohook_volume_get(chan, 1))) {
01036       return -1;
01037    }
01038 
01039    /* Based on the direction change the specific adjustment value */
01040    if (direction == AST_AUDIOHOOK_DIRECTION_READ || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
01041       audiohook_volume->read_adjustment += volume;
01042    }
01043    if (direction == AST_AUDIOHOOK_DIRECTION_WRITE || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
01044       audiohook_volume->write_adjustment += volume;
01045    }
01046 
01047    return 0;
01048 }

int ast_audiohook_volume_get ( struct ast_channel chan,
enum ast_audiohook_direction  direction 
)

Retrieve the volume adjustment value on frames read from or written to a channel.

Parameters:
chan Channel to retrieve volume adjustment from
direction Direction to retrieve
Returns:
Returns adjustment value

Definition at line 1004 of file audiohook.c.

References AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, audiohook_volume_get(), audiohook_volume::read_adjustment, and audiohook_volume::write_adjustment.

Referenced by confbridge_exec().

01005 {
01006    struct audiohook_volume *audiohook_volume = NULL;
01007    int adjustment = 0;
01008 
01009    /* Attempt to find the audiohook volume information, but do not create it as we only want to look at the values */
01010    if (!(audiohook_volume = audiohook_volume_get(chan, 0))) {
01011       return 0;
01012    }
01013 
01014    /* Grab the adjustment value based on direction given */
01015    if (direction == AST_AUDIOHOOK_DIRECTION_READ) {
01016       adjustment = audiohook_volume->read_adjustment;
01017    } else if (direction == AST_AUDIOHOOK_DIRECTION_WRITE) {
01018       adjustment = audiohook_volume->write_adjustment;
01019    }
01020 
01021    return adjustment;
01022 }

int ast_audiohook_volume_set ( struct ast_channel chan,
enum ast_audiohook_direction  direction,
int  volume 
)

Adjust the volume on frames read from or written to a channel.

Parameters:
chan Channel to muck with
direction Direction to set on
volume Value to adjust the volume by
Returns:
Returns 0 on success, -1 on failure

Definition at line 979 of file audiohook.c.

References AST_AUDIOHOOK_DIRECTION_BOTH, AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, audiohook_volume_get(), audiohook_volume::read_adjustment, and audiohook_volume::write_adjustment.

Referenced by confbridge_exec().

00980 {
00981    struct audiohook_volume *audiohook_volume = NULL;
00982 
00983    /* Attempt to find the audiohook volume information, but only create it if we are not setting the adjustment value to zero */
00984    if (!(audiohook_volume = audiohook_volume_get(chan, (volume ? 1 : 0)))) {
00985       return -1;
00986    }
00987 
00988    /* Now based on the direction set the proper value */
00989    if (direction == AST_AUDIOHOOK_DIRECTION_READ || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
00990       audiohook_volume->read_adjustment = volume;
00991    }
00992    if (direction == AST_AUDIOHOOK_DIRECTION_WRITE || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
00993       audiohook_volume->write_adjustment = volume;
00994    }
00995 
00996    return 0;
00997 }

int ast_audiohook_write_frame ( struct ast_audiohook audiohook,
enum ast_audiohook_direction  direction,
struct ast_frame frame 
)

Writes a frame into the audiohook structure.

Parameters:
audiohook Audiohook structure
direction Direction the audio frame came from
frame Frame to write in
Returns:
Returns 0 on success, -1 on failure

Definition at line 121 of file audiohook.c.

References AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, AST_AUDIOHOOK_MUTE_READ, AST_AUDIOHOOK_MUTE_WRITE, AST_AUDIOHOOK_SMALL_QUEUE, AST_AUDIOHOOK_SYNC_TOLERANCE, AST_AUDIOHOOK_TRIGGER_MODE, AST_AUDIOHOOK_TRIGGER_READ, AST_AUDIOHOOK_TRIGGER_SYNC, AST_AUDIOHOOK_TRIGGER_WRITE, ast_cond_signal, ast_frame_clear(), ast_log(), ast_slinfactory_available(), ast_slinfactory_feed(), ast_slinfactory_flush(), ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_frame::datalen, LOG_DEBUG, option_debug, ast_audiohook::read_factory, ast_audiohook::read_time, ast_audiohook::trigger, ast_audiohook::write_factory, and ast_audiohook::write_time.

Referenced by audio_audiohook_write_list(), and channel_spy().

00122 {
00123    struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
00124    struct ast_slinfactory *other_factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->write_factory : &audiohook->read_factory);
00125    struct timeval *rwtime = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_time : &audiohook->write_time), previous_time = *rwtime;
00126    int our_factory_samples;
00127    int our_factory_ms;
00128    int other_factory_samples;
00129    int other_factory_ms;
00130    int muteme = 0;
00131 
00132    /* Update last feeding time to be current */
00133    *rwtime = ast_tvnow();
00134 
00135    our_factory_samples = ast_slinfactory_available(factory);
00136    our_factory_ms = ast_tvdiff_ms(*rwtime, previous_time) + (our_factory_samples / 8);
00137    other_factory_samples = ast_slinfactory_available(other_factory);
00138    other_factory_ms = other_factory_samples / 8;
00139 
00140    if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC) && other_factory_samples && (our_factory_ms - other_factory_ms > AST_AUDIOHOOK_SYNC_TOLERANCE)) {
00141       if (option_debug)
00142          ast_log(LOG_DEBUG, "Flushing audiohook %p so it remains in sync\n", audiohook);
00143       ast_slinfactory_flush(factory);
00144       ast_slinfactory_flush(other_factory);
00145    }
00146 
00147    if (ast_test_flag(audiohook, AST_AUDIOHOOK_SMALL_QUEUE) && (our_factory_samples > 640 || other_factory_samples > 640)) {
00148       if (option_debug) {
00149          ast_log(LOG_DEBUG, "Audiohook %p has stale audio in its factories. Flushing them both\n", audiohook);
00150       }
00151       ast_slinfactory_flush(factory);
00152       ast_slinfactory_flush(other_factory);
00153    }
00154 
00155    /* swap frame data for zeros if mute is required */
00156    if ((ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_READ) && (direction == AST_AUDIOHOOK_DIRECTION_READ)) ||
00157       (ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_WRITE) && (direction == AST_AUDIOHOOK_DIRECTION_WRITE)) ||
00158       (ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_READ | AST_AUDIOHOOK_MUTE_WRITE) == (AST_AUDIOHOOK_MUTE_READ | AST_AUDIOHOOK_MUTE_WRITE))) {
00159          muteme = 1;
00160    }
00161 
00162    if (muteme && frame->datalen > 0) {
00163       ast_frame_clear(frame);
00164    }
00165 
00166    /* Write frame out to respective factory */
00167    ast_slinfactory_feed(factory, frame);
00168 
00169    /* If we need to notify the respective handler of this audiohook, do so */
00170    if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_READ) && (direction == AST_AUDIOHOOK_DIRECTION_READ)) {
00171       ast_cond_signal(&audiohook->trigger);
00172    } else if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_WRITE) && (direction == AST_AUDIOHOOK_DIRECTION_WRITE)) {
00173       ast_cond_signal(&audiohook->trigger);
00174    } else if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC)) {
00175       ast_cond_signal(&audiohook->trigger);
00176    }
00177 
00178    return 0;
00179 }

struct ast_frame* ast_audiohook_write_list ( struct ast_channel chan,
struct ast_audiohook_list audiohook_list,
enum ast_audiohook_direction  direction,
struct ast_frame frame 
)

Pass a frame off to be handled by the audiohook core.

Parameters:
chan Channel that the list is coming off of
audiohook_list List of audiohooks
direction Direction frame is coming in from
frame The frame itself
Returns:
Return frame on success, NULL on failure

Definition at line 756 of file audiohook.c.

References AST_FRAME_DTMF, AST_FRAME_VOICE, audio_audiohook_write_list(), dtmf_audiohook_write_list(), and ast_frame::frametype.

Referenced by __ast_read(), and ast_write().

00757 {
00758    /* Pass off frame to it's respective list write function */
00759    if (frame->frametype == AST_FRAME_VOICE)
00760       return audio_audiohook_write_list(chan, audiohook_list, direction, frame);
00761    else if (frame->frametype == AST_FRAME_DTMF)
00762       return dtmf_audiohook_write_list(chan, audiohook_list, direction, frame);
00763    else
00764       return frame;
00765 }

int ast_audiohook_write_list_empty ( struct ast_audiohook_list audiohook_list  ) 

determines if a audiohook_list is empty or not.

retval 0 false, 1 true

Definition at line 738 of file audiohook.c.

References AST_LIST_EMPTY, ast_audiohook_list::manipulate_list, ast_audiohook_list::spy_list, and ast_audiohook_list::whisper_list.

Referenced by __ast_read(), and ast_write().

00739 {
00740    if (AST_LIST_EMPTY(&audiohook_list->spy_list) &&
00741       AST_LIST_EMPTY(&audiohook_list->whisper_list) &&
00742       AST_LIST_EMPTY(&audiohook_list->manipulate_list)) {
00743 
00744       return 1;
00745    }
00746    return 0;
00747 }

int ast_channel_audiohook_count_by_source ( struct ast_channel chan,
const char *  source,
enum ast_audiohook_type  type 
)

Find out how many audiohooks from a certain source exist on a given channel, regardless of status.

Parameters:
chan The channel on which to find the spies
source The audiohook's source
type The type of audiohook
Returns:
Return the number of audiohooks which are from the source specified
Note: Function performs nlocking.

Definition at line 785 of file audiohook.c.

References AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_channel::audiohooks, ast_audiohook::list, ast_audiohook_list::manipulate_list, ast_audiohook::source, ast_audiohook_list::spy_list, and ast_audiohook_list::whisper_list.

Referenced by builtin_automixmonitor().

00786 {
00787    int count = 0;
00788    struct ast_audiohook *ah = NULL;
00789 
00790    if (!chan->audiohooks)
00791       return -1;
00792 
00793    switch (type) {
00794       case AST_AUDIOHOOK_TYPE_SPY:
00795          AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->spy_list, ah, list) {
00796             if (!strcmp(ah->source, source)) {
00797                count++;
00798             }
00799          }
00800          AST_LIST_TRAVERSE_SAFE_END;
00801          break;
00802       case AST_AUDIOHOOK_TYPE_WHISPER:
00803          AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->whisper_list, ah, list) {
00804             if (!strcmp(ah->source, source)) {
00805                count++;
00806             }
00807          }
00808          AST_LIST_TRAVERSE_SAFE_END;
00809          break;
00810       case AST_AUDIOHOOK_TYPE_MANIPULATE:
00811          AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->manipulate_list, ah, list) {
00812             if (!strcmp(ah->source, source)) {
00813                count++;
00814             }
00815          }
00816          AST_LIST_TRAVERSE_SAFE_END;
00817          break;
00818       default:
00819          ast_log(LOG_DEBUG, "Invalid audiohook type supplied, (%d)\n", type);
00820          return -1;
00821    }
00822 
00823    return count;
00824 }

int ast_channel_audiohook_count_by_source_running ( struct ast_channel chan,
const char *  source,
enum ast_audiohook_type  type 
)

Find out how many spies of a certain type exist on a given channel, and are in state running.

Parameters:
chan The channel on which to find the spies
source The source of the audiohook
type The type of spy to look for
Returns:
Return the number of running audiohooks which are from the source specified
Note: Function performs no locking.

Definition at line 827 of file audiohook.c.

References AST_AUDIOHOOK_STATUS_RUNNING, AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_channel::audiohooks, ast_audiohook::list, ast_audiohook_list::manipulate_list, ast_audiohook::source, ast_audiohook_list::spy_list, ast_audiohook::status, and ast_audiohook_list::whisper_list.

Referenced by builtin_automixmonitor().

00828 {
00829    int count = 0;
00830    struct ast_audiohook *ah = NULL;
00831    if (!chan->audiohooks)
00832       return -1;
00833 
00834    switch (type) {
00835       case AST_AUDIOHOOK_TYPE_SPY:
00836          AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->spy_list, ah, list) {
00837             if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
00838                count++;
00839          }
00840          AST_LIST_TRAVERSE_SAFE_END;
00841          break;
00842       case AST_AUDIOHOOK_TYPE_WHISPER:
00843          AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->whisper_list, ah, list) {
00844             if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
00845                count++;
00846          }
00847          AST_LIST_TRAVERSE_SAFE_END;
00848          break;
00849       case AST_AUDIOHOOK_TYPE_MANIPULATE:
00850          AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->manipulate_list, ah, list) {
00851             if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
00852                count++;
00853          }
00854          AST_LIST_TRAVERSE_SAFE_END;
00855          break;
00856       default:
00857          ast_log(LOG_DEBUG, "Invalid audiohook type supplied, (%d)\n", type);
00858          return -1;
00859    }
00860    return count;
00861 }


Generated on Wed Apr 6 11:29:53 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7