Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Macros | Functions | Variables
audiohook.c File Reference

Audiohooks Architecture. More...

#include "asterisk.h"
#include <signal.h>
#include "asterisk/channel.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/audiohook.h"
#include "asterisk/slinfactory.h"
#include "asterisk/frame.h"
#include "asterisk/translate.h"
#include "asterisk/format_cache.h"
#include "asterisk/test.h"

Go to the source code of this file.

Data Structures

struct  ast_audiohook_list
 
struct  ast_audiohook_translate
 
struct  audiohook_volume
 Audiohook volume adjustment structure. More...
 

Macros

#define AST_AUDIOHOOK_LONG_QUEUE_TOLERANCE   500
 
#define AST_AUDIOHOOK_SMALL_QUEUE_TOLERANCE   100
 
#define AST_AUDIOHOOK_SYNC_TOLERANCE   100
 
#define DEFAULT_INTERNAL_SAMPLE_RATE   8000
 
#define SHOULD_MUTE(hook, dir)
 

Functions

int ast_audiohook_attach (struct ast_channel *chan, struct ast_audiohook *audiohook)
 Attach audiohook to channel. More...
 
int ast_audiohook_destroy (struct ast_audiohook *audiohook)
 Destroys an audiohook structure. More...
 
int ast_audiohook_detach (struct ast_audiohook *audiohook)
 Detach audiohook from channel. More...
 
void ast_audiohook_detach_list (struct ast_audiohook_list *audiohook_list)
 Detach audiohooks from list and destroy said list. More...
 
int ast_audiohook_detach_source (struct ast_channel *chan, const char *source)
 Detach specified source audiohook from channel. More...
 
int ast_audiohook_init (struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source, enum ast_audiohook_init_flags init_flags)
 Initialize an audiohook structure. More...
 
void ast_audiohook_move_all (struct ast_channel *old_chan, struct ast_channel *new_chan)
 Move all audiohooks from one channel to another. More...
 
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. More...
 
struct ast_frameast_audiohook_read_frame (struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, struct ast_format *format)
 Reads a frame in from the audiohook structure. More...
 
struct ast_frameast_audiohook_read_frame_all (struct ast_audiohook *audiohook, size_t samples, struct ast_format *format, struct ast_frame **read_frame, struct ast_frame **write_frame)
 Reads a frame in from the audiohook structure in mixed audio mode and copies read and write frame data to provided arguments. More...
 
int ast_audiohook_remove (struct ast_channel *chan, struct ast_audiohook *audiohook)
 Remove an audiohook from a specified channel. More...
 
int ast_audiohook_set_frame_feed_direction (struct ast_audiohook *audiohook, enum ast_audiohook_direction direction)
 Sets direction on audiohook. More...
 
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. More...
 
int ast_audiohook_set_mute_all (struct ast_channel *chan, const char *source, enum ast_audiohook_flags flag, int clearmute)
 Mute frames read from or written for all audiohooks on a channel. More...
 
void ast_audiohook_trigger_wait (struct ast_audiohook *audiohook)
 Wait for audiohook trigger to be triggered. More...
 
void ast_audiohook_update_status (struct ast_audiohook *audiohook, enum ast_audiohook_status status)
 Update audiohook's status. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
struct 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. More...
 
int ast_audiohook_write_list_empty (struct ast_audiohook_list *audiohook_list)
 Determine if a audiohook_list is empty or not. More...
 
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. More...
 
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. More...
 
static struct ast_frameaudio_audiohook_write_list (struct ast_channel *chan, struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame)
 Pass an AUDIO frame off to be handled by the audiohook core. More...
 
static void audiohook_list_set_hook_rate (struct ast_audiohook_list *audiohook_list, struct ast_audiohook *audiohook, int *rate)
 Set the audiohook's internal sample rate to the audiohook_list's rate, but only when native slin compatibility is turned on. More...
 
static void audiohook_list_set_samplerate_compatibility (struct ast_audiohook_list *audiohook_list)
 
static struct ast_frameaudiohook_list_translate_to_native (struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *slin_frame, struct ast_format *outformat)
 
static struct ast_frameaudiohook_list_translate_to_slin (struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame)
 
static void audiohook_move (struct ast_channel *old_chan, struct ast_channel *new_chan, struct ast_audiohook *audiohook)
 
static struct ast_frameaudiohook_read_frame_both (struct ast_audiohook *audiohook, size_t samples, struct ast_frame **read_reference, struct ast_frame **write_reference)
 
static struct ast_frameaudiohook_read_frame_helper (struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, struct ast_format *format, struct ast_frame **read_reference, struct ast_frame **write_reference)
 
static struct ast_frameaudiohook_read_frame_single (struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction)
 
static int audiohook_set_internal_rate (struct ast_audiohook *audiohook, int rate, int reset)
 
static int audiohook_volume_callback (struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction)
 Helper function which actually gets called by audiohooks to perform the adjustment. More...
 
static void audiohook_volume_destroy (void *data)
 Callback used to destroy the audiohook volume datastore. More...
 
static struct audiohook_volumeaudiohook_volume_get (struct ast_channel *chan, int create)
 Helper function which finds and optionally creates an audiohook_volume_datastore datastore on a channel. More...
 
static struct ast_framedtmf_audiohook_write_list (struct ast_channel *chan, struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame)
 Pass a DTMF frame off to be handled by the audiohook core. More...
 
static struct ast_audiohookfind_audiohook_by_source (struct ast_audiohook_list *audiohook_list, const char *source)
 find an audiohook based on its source More...
 

Variables

static const struct ast_datastore_info audiohook_volume_datastore
 Datastore used to store audiohook volume information. More...
 

Detailed Description

Audiohooks Architecture.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file audiohook.c.

Macro Definition Documentation

#define AST_AUDIOHOOK_LONG_QUEUE_TOLERANCE   500

Otheriwise we still don't want the queue to grow indefinitely

Definition at line 46 of file audiohook.c.

Referenced by ast_audiohook_write_frame().

#define AST_AUDIOHOOK_SMALL_QUEUE_TOLERANCE   100

When small queue is enabled, this is the maximum amount of audio that can remain queued at a time.

Definition at line 45 of file audiohook.c.

Referenced by ast_audiohook_write_frame().

#define AST_AUDIOHOOK_SYNC_TOLERANCE   100

Tolerance in milliseconds for audiohooks synchronization

Definition at line 44 of file audiohook.c.

Referenced by ast_audiohook_write_frame().

#define SHOULD_MUTE (   hook,
  dir 
)

Function Documentation

int ast_audiohook_attach ( struct ast_channel chan,
struct ast_audiohook audiohook 
)

Attach audiohook to channel.

Parameters
chan
audiohook
Returns
0 on success
Return values
-1on failure

Definition at line 484 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_is_bridged(), ast_channel_set_unbridged_nolock(), AST_FLAG_ZOMBIE, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_TAIL, ast_audiohook_list::list_internal_samp_rate, and ast_audiohook::type.

Referenced by audiohook_volume_get(), and snoop_setup_audiohook().

485 {
486  ast_channel_lock(chan);
487 
488  /* Don't allow an audiohook to be attached to a channel that is already hung up.
489  * The hang up process is what actually notifies the audiohook that it should
490  * stop.
491  */
492  if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)) {
493  ast_channel_unlock(chan);
494  return -1;
495  }
496 
497  if (!ast_channel_audiohooks(chan)) {
498  struct ast_audiohook_list *ahlist;
499  /* Whoops... allocate a new structure */
500  if (!(ahlist = ast_calloc(1, sizeof(*ahlist)))) {
501  ast_channel_unlock(chan);
502  return -1;
503  }
504  ast_channel_audiohooks_set(chan, ahlist);
505  AST_LIST_HEAD_INIT_NOLOCK(&ast_channel_audiohooks(chan)->spy_list);
506  AST_LIST_HEAD_INIT_NOLOCK(&ast_channel_audiohooks(chan)->whisper_list);
507  AST_LIST_HEAD_INIT_NOLOCK(&ast_channel_audiohooks(chan)->manipulate_list);
508  /* This sample rate will adjust as necessary when writing to the list. */
509  ast_channel_audiohooks(chan)->list_internal_samp_rate = DEFAULT_INTERNAL_SAMPLE_RATE;
510  }
511 
512  /* Drop into respective list */
513  if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY) {
514  AST_LIST_INSERT_TAIL(&ast_channel_audiohooks(chan)->spy_list, audiohook, list);
515  } else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER) {
516  AST_LIST_INSERT_TAIL(&ast_channel_audiohooks(chan)->whisper_list, audiohook, list);
517  } else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) {
518  AST_LIST_INSERT_TAIL(&ast_channel_audiohooks(chan)->manipulate_list, audiohook, list);
519  }
520 
521  /*
522  * Initialize the audiohook's rate to the default. If it needs to be,
523  * it will get updated later.
524  */
525  audiohook_set_internal_rate(audiohook, DEFAULT_INTERNAL_SAMPLE_RATE, 1);
526  audiohook_list_set_samplerate_compatibility(ast_channel_audiohooks(chan));
527 
528  /* Change status over to running since it is now attached */
530 
531  if (ast_channel_is_bridged(chan)) {
533  }
534 
535  ast_channel_unlock(chan);
536 
537  return 0;
538 }
enum ast_audiohook_type type
Definition: audiohook.h:107
int list_internal_samp_rate
Definition: audiohook.c:61
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook's status.
Definition: audiohook.c:540
void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value)
Variant of ast_channel_set_unbridged. Use this if the channel is already locked prior to calling...
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10545
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
int ast_audiohook_destroy ( struct ast_audiohook audiohook)

Destroys an audiohook structure.

Parameters
audiohook
Return values
0on success
-1on failure

Definition at line 124 of file audiohook.c.

References AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_slinfactory_destroy(), ast_translator_free_path(), ast_audiohook::format, 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(), and snoop_destroy().

125 {
126  /* Drop the factories used by this audiohook type */
127  switch (audiohook->type) {
132  break;
133  default:
134  break;
135  }
136 
137  /* Destroy translation path if present */
138  if (audiohook->trans_pvt)
140 
141  ao2_cleanup(audiohook->format);
142 
143  /* Lock and trigger be gone! */
144  ast_cond_destroy(&audiohook->trigger);
145  ast_mutex_destroy(&audiohook->lock);
146 
147  return 0;
148 }
struct ast_slinfactory write_factory
Definition: audiohook.h:113
enum ast_audiohook_type type
Definition: audiohook.h:107
ast_mutex_t lock
Definition: audiohook.h:105
struct ast_format * format
Definition: audiohook.h:116
struct ast_trans_pvt * trans_pvt
Definition: audiohook.h:117
void ast_slinfactory_destroy(struct ast_slinfactory *sf)
Destroy the contents of a slinfactory.
Definition: slinfactory.c:58
ast_cond_t trigger
Definition: audiohook.h:106
struct ast_slinfactory read_factory
Definition: audiohook.h:112
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:476
int ast_audiohook_detach ( struct ast_audiohook audiohook)

Detach audiohook from channel.

Parameters
audiohook
Returns
Returns 0 on success, -1 on failure

Definition at line 550 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 snoop_hangup().

551 {
552  if (audiohook->status == AST_AUDIOHOOK_STATUS_NEW || audiohook->status == AST_AUDIOHOOK_STATUS_DONE) {
553  return 0;
554  }
555 
557 
558  while (audiohook->status != AST_AUDIOHOOK_STATUS_DONE) {
559  ast_audiohook_trigger_wait(audiohook);
560  }
561 
562  return 0;
563 }
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook's status.
Definition: audiohook.c:540
void ast_audiohook_trigger_wait(struct ast_audiohook *audiohook)
Wait for audiohook trigger to be triggered.
Definition: audiohook.c:1094
enum ast_audiohook_status status
Definition: audiohook.h:108
void ast_audiohook_detach_list ( struct ast_audiohook_list audiohook_list)

Detach audiohooks from list and destroy said list.

Parameters
audiohook_listList of audiohooks (NULL tolerant)

Definition at line 565 of file audiohook.c.

References AST_AUDIOHOOK_STATUS_DONE, ast_audiohook_update_status(), AST_LIST_REMOVE_HEAD, ast_translator_free_path(), ast_audiohook::list, and ast_audiohook::manipulate_callback.

Referenced by __ast_read(), and ast_write_stream().

566 {
567  int i;
568  struct ast_audiohook *audiohook;
569 
570  if (!audiohook_list) {
571  return;
572  }
573 
574  /* Drop any spies */
575  while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->spy_list, list))) {
577  }
578 
579  /* Drop any whispering sources */
580  while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->whisper_list, list))) {
582  }
583 
584  /* Drop any manipulators */
585  while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->manipulate_list, list))) {
587  audiohook->manipulate_callback(audiohook, NULL, NULL, 0);
588  }
589 
590  /* Drop translation paths if present */
591  for (i = 0; i < 2; i++) {
592  if (audiohook_list->in_translate[i].trans_pvt) {
593  ast_translator_free_path(audiohook_list->in_translate[i].trans_pvt);
594  ao2_cleanup(audiohook_list->in_translate[i].format);
595  }
596  if (audiohook_list->out_translate[i].trans_pvt) {
597  ast_translator_free_path(audiohook_list->out_translate[i].trans_pvt);
598  ao2_cleanup(audiohook_list->in_translate[i].format);
599  }
600  }
601 
602  /* Free ourselves */
603  ast_free(audiohook_list);
604 }
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook's status.
Definition: audiohook.c:540
ast_audiohook_manipulate_callback manipulate_callback
Definition: audiohook.h:118
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
struct ast_audiohook::@185 list
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:476
int ast_audiohook_detach_source ( struct ast_channel chan,
const char *  source 
)

Detach specified source audiohook from channel.

Parameters
chanChannel to detach from
sourceName of source to detach
Return values
0on success
-1on failure
Note
The channel does not need to be locked before calling this function.

Definition at line 698 of file audiohook.c.

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

699 {
700  struct ast_audiohook *audiohook = NULL;
701 
702  ast_channel_lock(chan);
703 
704  /* Ensure the channel has audiohooks on it */
705  if (!ast_channel_audiohooks(chan)) {
706  ast_channel_unlock(chan);
707  return -1;
708  }
709 
710  audiohook = find_audiohook_by_source(ast_channel_audiohooks(chan), source);
711 
712  ast_channel_unlock(chan);
713 
714  if (audiohook && audiohook->status != AST_AUDIOHOOK_STATUS_DONE) {
716  }
717 
718  return (audiohook ? 0 : -1);
719 }
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook's status.
Definition: audiohook.c:540
static struct ast_audiohook * find_audiohook_by_source(struct ast_audiohook_list *audiohook_list, const char *source)
find an audiohook based on its source
Definition: audiohook.c:612
const char * source
Definition: audiohook.h:110
enum ast_audiohook_status status
Definition: audiohook.h:108
int ast_audiohook_init ( struct ast_audiohook audiohook,
enum ast_audiohook_type  type,
const char *  source,
enum ast_audiohook_init_flags  flags 
)

Initialize an audiohook structure.

Parameters
audiohook
typeType of audiohook to initialize this as
sourceWho is initializing this audiohook
flags
Return values
0on success
-1on failure

Definition at line 100 of file audiohook.c.

References AST_AUDIOHOOK_DIRECTION_BOTH, AST_AUDIOHOOK_STATUS_NEW, ast_audiohook_update_status(), ast_audiohook::direction, ast_audiohook::init_flags, ast_audiohook::lock, ast_audiohook::source, ast_audiohook::trigger, and ast_audiohook::type.

Referenced by audiohook_volume_get(), and snoop_setup_audiohook().

101 {
102  /* Need to keep the type and source */
103  audiohook->type = type;
104  audiohook->source = source;
105 
106  /* Initialize lock that protects our audiohook */
107  ast_mutex_init(&audiohook->lock);
108  ast_cond_init(&audiohook->trigger, NULL);
109 
110  audiohook->init_flags = init_flags;
111 
112  /* Set direction to BOTH so that we feed frames in both directions */
114 
115  /* initialize internal rate at 8khz, this will adjust if necessary */
116  audiohook_set_internal_rate(audiohook, DEFAULT_INTERNAL_SAMPLE_RATE, 0);
117 
118  /* Since we are just starting out... this audiohook is new */
120 
121  return 0;
122 }
enum ast_audiohook_type type
Definition: audiohook.h:107
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook's status.
Definition: audiohook.c:540
ast_mutex_t lock
Definition: audiohook.h:105
enum ast_audiohook_init_flags init_flags
Definition: audiohook.h:109
enum ast_audiohook_direction direction
Definition: audiohook.h:121
const char * source
Definition: audiohook.h:110
ast_cond_t trigger
Definition: audiohook.h:106
void ast_audiohook_move_all ( struct ast_channel old_chan,
struct ast_channel new_chan 
)

Move all audiohooks from one channel to another.

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_chanThe source of the audiohooks being moved
new_chanThe destination channel for the audiohooks to be moved to

Definition at line 672 of file audiohook.c.

References AST_LIST_TRAVERSE_SAFE_BEGIN, and AST_LIST_TRAVERSE_SAFE_END.

Referenced by channel_do_masquerade().

673 {
674  struct ast_audiohook *audiohook;
675  struct ast_audiohook_list *audiohook_list;
676 
677  audiohook_list = ast_channel_audiohooks(old_chan);
678  if (!audiohook_list) {
679  return;
680  }
681 
682  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
683  audiohook_move(old_chan, new_chan, audiohook);
684  }
686 
687  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->whisper_list, audiohook, list) {
688  audiohook_move(old_chan, new_chan, audiohook);
689  }
691 
692  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
693  audiohook_move(old_chan, new_chan, audiohook);
694  }
696 }
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
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_chanThe source of the audiohook to move
new_chanThe destination to which we want the audiohook to move
sourceThe source of the audiohook we want to move

Definition at line 656 of file audiohook.c.

References find_audiohook_by_source().

657 {
658  struct ast_audiohook *audiohook;
659 
660  if (!ast_channel_audiohooks(old_chan)) {
661  return;
662  }
663 
664  audiohook = find_audiohook_by_source(ast_channel_audiohooks(old_chan), source);
665  if (!audiohook) {
666  return;
667  }
668 
669  audiohook_move(old_chan, new_chan, audiohook);
670 }
static struct ast_audiohook * find_audiohook_by_source(struct ast_audiohook_list *audiohook_list, const char *source)
find an audiohook based on its source
Definition: audiohook.c:612
const char * source
Definition: audiohook.h:110
struct ast_frame* ast_audiohook_read_frame ( struct ast_audiohook audiohook,
size_t  samples,
enum ast_audiohook_direction  direction,
struct ast_format format 
)

Reads a frame in from the audiohook structure.

Parameters
audiohook
samplesNumber of samples wanted
directionDirection the audio frame came from
formatFormat of frame remote side wants back
Returns
frame on success
Return values
NULLon failure

Definition at line 446 of file audiohook.c.

Referenced by snoop_read().

447 {
448  return audiohook_read_frame_helper(audiohook, samples, direction, format, NULL, NULL);
449 }
struct ast_frame* ast_audiohook_read_frame_all ( struct ast_audiohook audiohook,
size_t  samples,
struct ast_format format,
struct ast_frame **  read_frame,
struct ast_frame **  write_frame 
)

Reads a frame in from the audiohook structure in mixed audio mode and copies read and write frame data to provided arguments.

Parameters
audiohook
samplesNumber of samples wanted
formatFormat of frame remote side wants back
read_frameif available, we'll copy the read buffer to this.
write_frameif available, we'll copy the write buffer to this.
Returns
frame on success
Return values
NULLon failure

Definition at line 451 of file audiohook.c.

References AST_AUDIOHOOK_DIRECTION_BOTH.

452 {
453  return audiohook_read_frame_helper(audiohook, samples, AST_AUDIOHOOK_DIRECTION_BOTH, format, read_frame, write_frame);
454 }
int ast_audiohook_remove ( struct ast_channel chan,
struct ast_audiohook audiohook 
)

Remove an audiohook from a specified channel.

Parameters
chanChannel to remove from
audiohookAudiohook to remove
Return values
0on success
-1on failure
Note
The channel does not need to be locked before calling this function

Definition at line 721 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_is_bridged(), ast_channel_set_unbridged_nolock(), AST_LIST_REMOVE, ast_audiohook::list, and ast_audiohook::type.

722 {
723  ast_channel_lock(chan);
724 
725  if (!ast_channel_audiohooks(chan)) {
726  ast_channel_unlock(chan);
727  return -1;
728  }
729 
730  if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY) {
731  AST_LIST_REMOVE(&ast_channel_audiohooks(chan)->spy_list, audiohook, list);
732  } else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER) {
733  AST_LIST_REMOVE(&ast_channel_audiohooks(chan)->whisper_list, audiohook, list);
734  } else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) {
735  AST_LIST_REMOVE(&ast_channel_audiohooks(chan)->manipulate_list, audiohook, list);
736  }
737 
738  audiohook_list_set_samplerate_compatibility(ast_channel_audiohooks(chan));
740 
741  if (ast_channel_is_bridged(chan)) {
743  }
744 
745  ast_channel_unlock(chan);
746 
747  return 0;
748 }
enum ast_audiohook_type type
Definition: audiohook.h:107
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook's status.
Definition: audiohook.c:540
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:856
void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value)
Variant of ast_channel_set_unbridged. Use this if the channel is already locked prior to calling...
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10545
struct ast_audiohook::@185 list
int ast_audiohook_set_frame_feed_direction ( struct ast_audiohook audiohook,
enum ast_audiohook_direction  direction 
)

Sets direction on audiohook.

Parameters
audiohook
directionIn which direction should the audiohook feed frames, ie if we are snooping 'in', set direction to READ so that only the 'in' frames are fed to the slin factory
Return values
0on success
-1on failure due to audiohook already in use or in shutdown. Can only set direction on NEW audiohooks

Definition at line 150 of file audiohook.c.

References AST_AUDIOHOOK_STATUS_NEW, ast_debug, ast_audiohook::direction, and ast_audiohook::status.

Referenced by snoop_setup_audiohook().

151 {
152  /* Only set the direction on new audiohooks */
153  if (audiohook->status != AST_AUDIOHOOK_STATUS_NEW) {
154  ast_debug(3, "Can not set direction on attached Audiohook %p\n", audiohook);
155  return -1;
156  }
157 
158  audiohook->direction = direction;
159  return 0;
160 }
#define ast_debug(level,...)
Log a DEBUG message.
enum ast_audiohook_direction direction
Definition: audiohook.h:121
enum ast_audiohook_status status
Definition: audiohook.h:108
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
chanChannel to muck with
sourceType of audiohook
flagwhich direction to set / clear
clearset or clear muted frames on direction based on flag parameter
Return values
0success
-1failure

Definition at line 1353 of file audiohook.c.

References find_audiohook_by_source().

1354 {
1355  struct ast_audiohook *audiohook = NULL;
1356 
1357  ast_channel_lock(chan);
1358 
1359  /* Ensure the channel has audiohooks on it */
1360  if (!ast_channel_audiohooks(chan)) {
1361  ast_channel_unlock(chan);
1362  return -1;
1363  }
1364 
1365  audiohook = find_audiohook_by_source(ast_channel_audiohooks(chan), source);
1366 
1367  if (audiohook) {
1368  if (clear) {
1369  ast_clear_flag(audiohook, flag);
1370  } else {
1371  ast_set_flag(audiohook, flag);
1372  }
1373  }
1374 
1375  ast_channel_unlock(chan);
1376 
1377  return (audiohook ? 0 : -1);
1378 }
static struct ast_audiohook * find_audiohook_by_source(struct ast_audiohook_list *audiohook_list, const char *source)
find an audiohook based on its source
Definition: audiohook.c:612
const char * source
Definition: audiohook.h:110
int ast_audiohook_set_mute_all ( struct ast_channel chan,
const char *  source,
enum ast_audiohook_flags  flag,
int  clear 
)

Mute frames read from or written for all audiohooks on a channel.

Parameters
chanChannel to muck with
sourceType of audiohooks
flagwhich direction to set / clear
clearset or clear muted frames on direction based on flag parameter
Return values
>=0number of muted audiohooks
-1failure

Definition at line 1380 of file audiohook.c.

References AST_LIST_TRAVERSE, ast_test_suite_event_notify, ast_audiohook::list, and ast_audiohook::source.

Referenced by manager_mute_mixmonitor().

1381 {
1382  struct ast_audiohook *audiohook = NULL;
1383  int count = 0;
1384 
1385  ast_channel_lock(chan);
1386 
1387  if (!ast_channel_audiohooks(chan)) {
1388  ast_channel_unlock(chan);
1389  return -1;
1390  }
1391 
1392  AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->spy_list, audiohook, list) {
1393  if (!strcasecmp(audiohook->source, source)) {
1394  count++;
1395  if (clearmute) {
1396  ast_clear_flag(audiohook, flag);
1397  } else {
1398  ast_set_flag(audiohook, flag);
1399  }
1400  }
1401  }
1402 
1403  ast_test_suite_event_notify("AUDIOHOOK_GROUP_MUTE_TOGGLE", "Channel: %s\r\nSource: %s\r\nCount: %d\r\n",
1404  ast_channel_name(chan), source, count);
1405 
1406  ast_channel_unlock(chan);
1407 
1408  return count;
1409 }
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:189
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
const char * source
Definition: audiohook.h:110
struct ast_audiohook::@185 list
void ast_audiohook_trigger_wait ( struct ast_audiohook audiohook)

Wait for audiohook trigger to be triggered.

Parameters
audiohookAudiohook to wait on

Definition at line 1094 of file audiohook.c.

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

Referenced by ast_audiohook_detach().

1095 {
1096  struct timeval wait;
1097  struct timespec ts;
1098 
1099  wait = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000));
1100  ts.tv_sec = wait.tv_sec;
1101  ts.tv_nsec = wait.tv_usec * 1000;
1102 
1103  ast_cond_timedwait(&audiohook->trigger, &audiohook->lock, &ts);
1104 
1105  return;
1106 }
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
ast_mutex_t lock
Definition: audiohook.h:105
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:282
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
ast_cond_t trigger
Definition: audiohook.h:106
void ast_audiohook_update_status ( struct ast_audiohook audiohook,
enum ast_audiohook_status  status 
)

Update audiohook's status.

Parameters
audiohook
status
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 540 of file audiohook.c.

References ast_audiohook_lock, AST_AUDIOHOOK_STATUS_DONE, ast_audiohook_unlock, 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().

541 {
542  ast_audiohook_lock(audiohook);
543  if (audiohook->status != AST_AUDIOHOOK_STATUS_DONE) {
544  audiohook->status = status;
545  ast_cond_signal(&audiohook->trigger);
546  }
547  ast_audiohook_unlock(audiohook);
548 }
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
Definition: audiohook.h:318
ast_cond_t trigger
Definition: audiohook.h:106
enum ast_audiohook_status status
Definition: audiohook.h:108
#define ast_audiohook_lock(ah)
Lock an audiohook.
Definition: audiohook.h:313
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
chanChannel to muck with
directionDirection to increase
volumeValue to adjust the adjustment by
Return values
0on success
-1on failure
Since
1.6.1

Definition at line 1333 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.

1334 {
1335  struct audiohook_volume *audiohook_volume = NULL;
1336 
1337  /* Attempt to find the audiohook volume information, and create an audiohook if none exists */
1338  if (!(audiohook_volume = audiohook_volume_get(chan, 1))) {
1339  return -1;
1340  }
1341 
1342  /* Based on the direction change the specific adjustment value */
1343  if (direction == AST_AUDIOHOOK_DIRECTION_READ || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
1344  audiohook_volume->read_adjustment += volume;
1345  }
1346  if (direction == AST_AUDIOHOOK_DIRECTION_WRITE || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
1347  audiohook_volume->write_adjustment += volume;
1348  }
1349 
1350  return 0;
1351 }
Audiohook volume adjustment structure.
Definition: audiohook.c:1183
static struct audiohook_volume * audiohook_volume_get(struct ast_channel *chan, int create)
Helper function which finds and optionally creates an audiohook_volume_datastore datastore on a chann...
Definition: audiohook.c:1258
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
chanChannel to retrieve volume adjustment from
directionDirection to retrieve
Returns
adjustment value
Since
1.6.1

Definition at line 1313 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().

1314 {
1315  struct audiohook_volume *audiohook_volume = NULL;
1316  int adjustment = 0;
1317 
1318  /* Attempt to find the audiohook volume information, but do not create it as we only want to look at the values */
1319  if (!(audiohook_volume = audiohook_volume_get(chan, 0))) {
1320  return 0;
1321  }
1322 
1323  /* Grab the adjustment value based on direction given */
1324  if (direction == AST_AUDIOHOOK_DIRECTION_READ) {
1325  adjustment = audiohook_volume->read_adjustment;
1326  } else if (direction == AST_AUDIOHOOK_DIRECTION_WRITE) {
1327  adjustment = audiohook_volume->write_adjustment;
1328  }
1329 
1330  return adjustment;
1331 }
Audiohook volume adjustment structure.
Definition: audiohook.c:1183
static struct audiohook_volume * audiohook_volume_get(struct ast_channel *chan, int create)
Helper function which finds and optionally creates an audiohook_volume_datastore datastore on a chann...
Definition: audiohook.c:1258
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
chanChannel to muck with
directionDirection to set on
volumeValue to adjust the volume by
Return values
0on success
-1on failure
Since
1.6.1

Definition at line 1293 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().

1294 {
1295  struct audiohook_volume *audiohook_volume = NULL;
1296 
1297  /* Attempt to find the audiohook volume information, but only create it if we are not setting the adjustment value to zero */
1298  if (!(audiohook_volume = audiohook_volume_get(chan, (volume ? 1 : 0)))) {
1299  return -1;
1300  }
1301 
1302  /* Now based on the direction set the proper value */
1303  if (direction == AST_AUDIOHOOK_DIRECTION_READ || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
1304  audiohook_volume->read_adjustment = volume;
1305  }
1306  if (direction == AST_AUDIOHOOK_DIRECTION_WRITE || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
1307  audiohook_volume->write_adjustment = volume;
1308  }
1309 
1310  return 0;
1311 }
Audiohook volume adjustment structure.
Definition: audiohook.c:1183
static struct audiohook_volume * audiohook_volume_get(struct ast_channel *chan, int create)
Helper function which finds and optionally creates an audiohook_volume_datastore datastore on a chann...
Definition: audiohook.c:1258
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
directionDirection the audio frame came from
frameFrame to write in
Return values
0on success
-1on failure

Definition at line 167 of file audiohook.c.

References AST_AUDIOHOOK_DIRECTION_BOTH, AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, AST_AUDIOHOOK_LONG_QUEUE_TOLERANCE, AST_AUDIOHOOK_SMALL_QUEUE, AST_AUDIOHOOK_SMALL_QUEUE_TOLERANCE, AST_AUDIOHOOK_SYNC_TOLERANCE, AST_AUDIOHOOK_TRIGGER_MODE, AST_AUDIOHOOK_TRIGGER_READ, AST_AUDIOHOOK_TRIGGER_SYNC, AST_AUDIOHOOK_TRIGGER_WRITE, ast_debug, ast_slinfactory_available(), ast_slinfactory_feed(), ast_slinfactory_flush(), ast_tvdiff_ms(), ast_tvnow(), ast_audiohook::direction, ast_audiohook::hook_internal_samp_rate, 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 snoop_write().

168 {
169  struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
170  struct ast_slinfactory *other_factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->write_factory : &audiohook->read_factory);
171  struct timeval *rwtime = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_time : &audiohook->write_time), previous_time = *rwtime;
172  int our_factory_samples;
173  int our_factory_ms;
174  int other_factory_samples;
175  int other_factory_ms;
176 
177  /* Don't feed the frame if we are set to read and this is a write frame or if set to
178  write and this is a read frame as we don't want it. Plus, it can cause mis-resampling
179  if the READ and WRITE frames have different bitrates */
180  if (audiohook->direction != AST_AUDIOHOOK_DIRECTION_BOTH && audiohook->direction != direction) {
181  return 0;
182  }
183 
184  /* Update last feeding time to be current */
185  *rwtime = ast_tvnow();
186 
187  our_factory_samples = ast_slinfactory_available(factory);
188  our_factory_ms = ast_tvdiff_ms(*rwtime, previous_time) + (our_factory_samples / (audiohook->hook_internal_samp_rate / 1000));
189  other_factory_samples = ast_slinfactory_available(other_factory);
190  other_factory_ms = other_factory_samples / (audiohook->hook_internal_samp_rate / 1000);
191 
192  if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC) && (our_factory_ms - other_factory_ms > AST_AUDIOHOOK_SYNC_TOLERANCE)) {
193  ast_debug(4, "Flushing audiohook %p so it remains in sync\n", audiohook);
194  ast_slinfactory_flush(factory);
195  ast_slinfactory_flush(other_factory);
196  }
197 
198  if (ast_test_flag(audiohook, AST_AUDIOHOOK_SMALL_QUEUE) && ((our_factory_ms > AST_AUDIOHOOK_SMALL_QUEUE_TOLERANCE) || (other_factory_ms > AST_AUDIOHOOK_SMALL_QUEUE_TOLERANCE))) {
199  ast_debug(4, "Audiohook %p has stale audio in its factories. Flushing them both\n", audiohook);
200  ast_slinfactory_flush(factory);
201  ast_slinfactory_flush(other_factory);
202  } else if ((our_factory_ms > AST_AUDIOHOOK_LONG_QUEUE_TOLERANCE) || (other_factory_ms > AST_AUDIOHOOK_LONG_QUEUE_TOLERANCE)) {
203  ast_debug(4, "Audiohook %p has stale audio in its factories. Flushing them both\n", audiohook);
204  ast_slinfactory_flush(factory);
205  ast_slinfactory_flush(other_factory);
206  }
207 
208  /* Write frame out to respective factory */
209  ast_slinfactory_feed(factory, frame);
210 
211  /* If we need to notify the respective handler of this audiohook, do so */
212  if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_READ) && (direction == AST_AUDIOHOOK_DIRECTION_READ)) {
213  ast_cond_signal(&audiohook->trigger);
214  } else if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_WRITE) && (direction == AST_AUDIOHOOK_DIRECTION_WRITE)) {
215  ast_cond_signal(&audiohook->trigger);
216  } else if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC)) {
217  ast_cond_signal(&audiohook->trigger);
218  }
219 
220  return 0;
221 }
struct ast_slinfactory write_factory
Definition: audiohook.h:113
void ast_slinfactory_flush(struct ast_slinfactory *sf)
Flush the contents of a slinfactory.
Definition: slinfactory.c:204
int ast_slinfactory_feed(struct ast_slinfactory *sf, struct ast_frame *f)
Feed audio into a slinfactory.
Definition: slinfactory.c:77
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
unsigned int ast_slinfactory_available(const struct ast_slinfactory *sf)
Retrieve number of samples currently in a slinfactory.
Definition: slinfactory.c:199
#define AST_AUDIOHOOK_LONG_QUEUE_TOLERANCE
Definition: audiohook.c:46
#define AST_AUDIOHOOK_SYNC_TOLERANCE
Definition: audiohook.c:44
#define ast_debug(level,...)
Log a DEBUG message.
enum ast_audiohook_direction direction
Definition: audiohook.h:121
unsigned int hook_internal_samp_rate
Definition: audiohook.h:120
#define AST_AUDIOHOOK_SMALL_QUEUE_TOLERANCE
Definition: audiohook.c:45
ast_cond_t trigger
Definition: audiohook.h:106
struct ast_slinfactory read_factory
Definition: audiohook.h:112
struct timeval write_time
Definition: audiohook.h:115
struct timeval read_time
Definition: audiohook.h:114
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
chanChannel that the list is coming off of
audiohook_listList of audiohooks
directionDirection frame is coming in from
frameThe frame itself
Returns
frame on success
Return values
NULLon failure

Definition at line 1079 of file audiohook.c.

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

Referenced by __ast_read(), and ast_write_stream().

1080 {
1081  /* Pass off frame to it's respective list write function */
1082  if (frame->frametype == AST_FRAME_VOICE) {
1083  return audio_audiohook_write_list(chan, audiohook_list, direction, frame);
1084  } else if (frame->frametype == AST_FRAME_DTMF) {
1085  return dtmf_audiohook_write_list(chan, audiohook_list, direction, frame);
1086  } else {
1087  return frame;
1088  }
1089 }
static struct ast_frame * audio_audiohook_write_list(struct ast_channel *chan, struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame)
Pass an AUDIO frame off to be handled by the audiohook core.
Definition: audiohook.c:914
static struct ast_frame * dtmf_audiohook_write_list(struct ast_channel *chan, struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame)
Pass a DTMF frame off to be handled by the audiohook core.
Definition: audiohook.c:758
enum ast_frame_type frametype
int ast_audiohook_write_list_empty ( struct ast_audiohook_list audiohook_list)

Determine if a audiohook_list is empty or not.

Parameters
audiohook_listAudiohook to check. (NULL also means empty)
Return values
0false
1true

Definition at line 1071 of file audiohook.c.

References AST_LIST_EMPTY.

Referenced by __ast_read(), ast_channel_has_audio_frame_or_monitor(), ast_channel_has_hook_requiring_audio(), and ast_write_stream().

1072 {
1073  return !audiohook_list
1074  || (AST_LIST_EMPTY(&audiohook_list->spy_list)
1075  && AST_LIST_EMPTY(&audiohook_list->whisper_list)
1076  && AST_LIST_EMPTY(&audiohook_list->manipulate_list));
1077 }
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
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
chanThe channel on which to find the spies
sourceThe audiohook's source
typeThe type of audiohook
Returns
number of audiohooks which are from the source specified

Note: Function performs nlocking.

Definition at line 1109 of file audiohook.c.

References AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_debug, AST_LIST_TRAVERSE, ast_audiohook::list, and ast_audiohook::source.

1110 {
1111  int count = 0;
1112  struct ast_audiohook *ah = NULL;
1113 
1114  if (!ast_channel_audiohooks(chan)) {
1115  return -1;
1116  }
1117 
1118  switch (type) {
1120  AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->spy_list, ah, list) {
1121  if (!strcmp(ah->source, source)) {
1122  count++;
1123  }
1124  }
1125  break;
1127  AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->whisper_list, ah, list) {
1128  if (!strcmp(ah->source, source)) {
1129  count++;
1130  }
1131  }
1132  break;
1134  AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->manipulate_list, ah, list) {
1135  if (!strcmp(ah->source, source)) {
1136  count++;
1137  }
1138  }
1139  break;
1140  default:
1141  ast_debug(1, "Invalid audiohook type supplied, (%u)\n", type);
1142  return -1;
1143  }
1144 
1145  return count;
1146 }
enum ast_audiohook_type type
Definition: audiohook.h:107
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
const char * source
Definition: audiohook.h:110
struct ast_audiohook::@185 list
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
chanThe channel on which to find the spies
sourceThe source of the audiohook
typeThe type of spy to look for
Returns
number of running audiohooks which are from the source specified

Note: Function performs no locking.

Definition at line 1149 of file audiohook.c.

References AST_AUDIOHOOK_STATUS_RUNNING, AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_debug, AST_LIST_TRAVERSE, ast_audiohook::list, ast_audiohook::source, and ast_audiohook::status.

1150 {
1151  int count = 0;
1152  struct ast_audiohook *ah = NULL;
1153  if (!ast_channel_audiohooks(chan))
1154  return -1;
1155 
1156  switch (type) {
1158  AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->spy_list, ah, list) {
1159  if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
1160  count++;
1161  }
1162  break;
1164  AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->whisper_list, ah, list) {
1165  if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
1166  count++;
1167  }
1168  break;
1170  AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->manipulate_list, ah, list) {
1171  if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
1172  count++;
1173  }
1174  break;
1175  default:
1176  ast_debug(1, "Invalid audiohook type supplied, (%u)\n", type);
1177  return -1;
1178  }
1179  return count;
1180 }
enum ast_audiohook_type type
Definition: audiohook.h:107
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
const char * source
Definition: audiohook.h:110
struct ast_audiohook::@185 list
enum ast_audiohook_status status
Definition: audiohook.h:108
static struct ast_frame* audio_audiohook_write_list ( struct ast_channel chan,
struct ast_audiohook_list audiohook_list,
enum ast_audiohook_direction  direction,
struct ast_frame frame 
)
static

Pass an AUDIO frame off to be handled by the audiohook core.

This function has 3 ast_frames and 3 parts to handle each. At the beginning of this function all 3 frames, start_frame, middle_frame, and end_frame point to the initial input frame.

Part_1: Translate the start_frame into SLINEAR audio if it is not already in that format. The result of this part is middle_frame is guaranteed to be in SLINEAR format for Part_2. Part_2: Send middle_frame off to spies and manipulators. At this point middle_frame is either a new frame as result of the translation, or points directly to the start_frame because no translation to SLINEAR audio was required. Part_3: Translate end_frame's audio back into the format of start frame if necessary. This is only necessary if manipulation of middle_frame occurred.

Parameters
chanChannel that the list is coming off of
audiohook_listList of audiohooks
directionDirection frame is coming in from
frameThe frame itself
Returns
frame on success
Return values
NULLon failure

Definition at line 914 of file audiohook.c.

References AST_AUDIOHOOK_DIRECTION_READ, ast_audiohook_lock, AST_AUDIOHOOK_STATUS_DONE, AST_AUDIOHOOK_STATUS_RUNNING, ast_audiohook_unlock, ast_audiohook_update_status(), ast_audiohook_write_frame(), ast_channel_is_bridged(), ast_channel_set_unbridged_nolock(), AST_LIST_EMPTY, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_slinfactory_available(), ast_slinfactory_read(), audiohook_list_set_hook_rate(), ast_frame_subclass::format, ast_audiohook::list, ast_audiohook_list::list_internal_samp_rate, ast_audiohook::manipulate_callback, ast_audiohook::read_factory, ast_frame::samples, ast_audiohook::status, ast_frame::subclass, and ast_audiohook::write_factory.

Referenced by ast_audiohook_write_list().

915 {
916  struct ast_frame *start_frame = frame, *middle_frame = frame, *end_frame = frame;
917  struct ast_audiohook *audiohook = NULL;
918  int samples;
919  int middle_frame_manipulated = 0;
920  int removed = 0;
921  int internal_sample_rate;
922 
923  /* ---Part_1. translate start_frame to SLINEAR if necessary. */
924  if (!(middle_frame = audiohook_list_translate_to_slin(audiohook_list, direction, start_frame))) {
925  return frame;
926  }
927 
928  /* If the translation resulted in an interpolated frame then immediately return as audiohooks
929  * rely on actual media being present to do things.
930  */
931  if (!middle_frame->data.ptr) {
932  if (middle_frame != start_frame) {
933  ast_frfree(middle_frame);
934  }
935  return start_frame;
936  }
937 
938  samples = middle_frame->samples;
939 
940  /*
941  * While processing each audiohook check to see if the internal sample rate needs
942  * to be adjusted (it should be the highest rate specified between formats and
943  * hooks). The given audiohook_list's internal sample rate is then set to the
944  * updated value before returning.
945  *
946  * If slin compatibility mode is turned on then an audiohook's internal sample
947  * rate is set to its audiohook_list's rate. If an audiohook_list's rate is
948  * adjusted during this pass then the change is picked up by the audiohooks
949  * on the next pass.
950  */
951  internal_sample_rate = audiohook_list->list_internal_samp_rate;
952 
953  /* ---Part_2: Send middle_frame to spy and manipulator lists. middle_frame is guaranteed to be SLINEAR here.*/
954  /* Queue up signed linear frame to each spy */
955  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
956  ast_audiohook_lock(audiohook);
957  if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
959  removed = 1;
961  ast_audiohook_unlock(audiohook);
962  if (ast_channel_is_bridged(chan)) {
964  }
965  continue;
966  }
967  audiohook_list_set_hook_rate(audiohook_list, audiohook, &internal_sample_rate);
968  ast_audiohook_write_frame(audiohook, direction, middle_frame);
969  ast_audiohook_unlock(audiohook);
970  }
972 
973  /* If this frame is being written out to the channel then we need to use whisper sources */
974  if (!AST_LIST_EMPTY(&audiohook_list->whisper_list)) {
975  int i = 0;
976  short read_buf[samples], combine_buf[samples], *data1 = NULL, *data2 = NULL;
977  memset(&combine_buf, 0, sizeof(combine_buf));
978  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->whisper_list, audiohook, list) {
979  struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
980  ast_audiohook_lock(audiohook);
981  if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
983  removed = 1;
985  ast_audiohook_unlock(audiohook);
986  if (ast_channel_is_bridged(chan)) {
988  }
989  continue;
990  }
991  audiohook_list_set_hook_rate(audiohook_list, audiohook, &internal_sample_rate);
992  if (ast_slinfactory_available(factory) >= samples && ast_slinfactory_read(factory, read_buf, samples)) {
993  /* Take audio from this whisper source and combine it into our main buffer */
994  for (i = 0, data1 = combine_buf, data2 = read_buf; i < samples; i++, data1++, data2++) {
995  ast_slinear_saturated_add(data1, data2);
996  }
997  }
998  ast_audiohook_unlock(audiohook);
999  }
1001  /* We take all of the combined whisper sources and combine them into the audio being written out */
1002  for (i = 0, data1 = middle_frame->data.ptr, data2 = combine_buf; i < samples; i++, data1++, data2++) {
1003  ast_slinear_saturated_add(data1, data2);
1004  }
1005  middle_frame_manipulated = 1;
1006  }
1007 
1008  /* Pass off frame to manipulate audiohooks */
1009  if (!AST_LIST_EMPTY(&audiohook_list->manipulate_list)) {
1010  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
1011  ast_audiohook_lock(audiohook);
1012  if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
1014  removed = 1;
1016  ast_audiohook_unlock(audiohook);
1017  /* We basically drop all of our links to the manipulate audiohook and prod it to do it's own destructive things */
1018  audiohook->manipulate_callback(audiohook, chan, NULL, direction);
1019  if (ast_channel_is_bridged(chan)) {
1021  }
1022  continue;
1023  }
1024  audiohook_list_set_hook_rate(audiohook_list, audiohook, &internal_sample_rate);
1025  /*
1026  * Feed in frame to manipulation.
1027  */
1028  if (!audiohook->manipulate_callback(audiohook, chan, middle_frame, direction)) {
1029  /*
1030  * XXX FAILURES ARE IGNORED XXX
1031  * If the manipulation fails then the frame will be returned in its original state.
1032  * Since there are potentially more manipulator callbacks in the list, no action should
1033  * be taken here to exit early.
1034  */
1035  middle_frame_manipulated = 1;
1036  }
1037  ast_audiohook_unlock(audiohook);
1038  }
1040  }
1041 
1042  /* ---Part_3: Decide what to do with the end_frame (whether to transcode or not) */
1043  if (middle_frame_manipulated) {
1044  if (!(end_frame = audiohook_list_translate_to_native(audiohook_list, direction, middle_frame, start_frame->subclass.format))) {
1045  /* translation failed, so just pass back the input frame */
1046  end_frame = start_frame;
1047  }
1048  } else {
1049  end_frame = start_frame;
1050  }
1051  /* clean up our middle_frame if required */
1052  if (middle_frame != end_frame) {
1053  ast_frfree(middle_frame);
1054  middle_frame = NULL;
1055  }
1056 
1057  /* Before returning, if an audiohook got removed, reset samplerate compatibility */
1058  if (removed) {
1059  audiohook_list_set_samplerate_compatibility(audiohook_list);
1060  } else {
1061  /*
1062  * Set the audiohook_list's rate to the updated rate. Note that if a hook
1063  * was removed then the list's internal rate is reset to the default.
1064  */
1065  audiohook_list->list_internal_samp_rate = internal_sample_rate;
1066  }
1067 
1068  return end_frame;
1069 }
struct ast_slinfactory write_factory
Definition: audiohook.h:113
int list_internal_samp_rate
Definition: audiohook.c:61
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook's status.
Definition: audiohook.c:540
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.
Definition: audiohook.c:167
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
unsigned int ast_slinfactory_available(const struct ast_slinfactory *sf)
Retrieve number of samples currently in a slinfactory.
Definition: slinfactory.c:199
struct ast_frame_subclass subclass
ast_audiohook_manipulate_callback manipulate_callback
Definition: audiohook.h:118
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
Definition: audiohook.h:318
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value)
Variant of ast_channel_set_unbridged. Use this if the channel is already locked prior to calling...
static void audiohook_list_set_hook_rate(struct ast_audiohook_list *audiohook_list, struct ast_audiohook *audiohook, int *rate)
Set the audiohook's internal sample rate to the audiohook_list's rate, but only when native slin comp...
Definition: audiohook.c:868
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10545
struct ast_slinfactory read_factory
Definition: audiohook.h:112
struct ast_audiohook::@185 list
Data structure associated with a single frame of data.
int ast_slinfactory_read(struct ast_slinfactory *sf, short *buf, size_t samples)
Read samples from a slinfactory.
Definition: slinfactory.c:145
enum ast_audiohook_status status
Definition: audiohook.h:108
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
struct ast_format * format
#define ast_audiohook_lock(ah)
Lock an audiohook.
Definition: audiohook.h:313
static void audiohook_list_set_hook_rate ( struct ast_audiohook_list audiohook_list,
struct ast_audiohook audiohook,
int *  rate 
)
static

Set the audiohook's internal sample rate to the audiohook_list's rate, but only when native slin compatibility is turned on.

Parameters
audiohook_listaudiohook_list data object
audiohookthe audiohook to update
ratethe current max internal sample rate

Definition at line 868 of file audiohook.c.

References AST_AUDIOHOOK_COMPATIBLE, ast_audiohook::hook_internal_samp_rate, and ast_audiohook_list::list_internal_samp_rate.

Referenced by audio_audiohook_write_list().

870 {
871  /* The rate should always be the max between itself and the hook */
872  if (audiohook->hook_internal_samp_rate > *rate) {
873  *rate = audiohook->hook_internal_samp_rate;
874  }
875 
876  /*
877  * If native slin compatibility is turned on then update the audiohook
878  * with the audiohook_list's current rate. Note, the audiohook's rate is
879  * set to the audiohook_list's rate and not the given rate. If there is
880  * a change in rate the hook's rate is changed on its next check.
881  */
882  if (audiohook_list->native_slin_compatible) {
883  ast_set_flag(audiohook, AST_AUDIOHOOK_COMPATIBLE);
884  audiohook_set_internal_rate(audiohook, audiohook_list->list_internal_samp_rate, 1);
885  } else {
886  ast_clear_flag(audiohook, AST_AUDIOHOOK_COMPATIBLE);
887  }
888 }
int list_internal_samp_rate
Definition: audiohook.c:61
unsigned int hook_internal_samp_rate
Definition: audiohook.h:120
static int audiohook_volume_callback ( struct ast_audiohook audiohook,
struct ast_channel chan,
struct ast_frame frame,
enum ast_audiohook_direction  direction 
)
static

Helper function which actually gets called by audiohooks to perform the adjustment.

Parameters
audiohookAudiohook attached to the channel
chanChannel we are attached to
frameFrame of audio we want to manipulate
directionDirection the audio came in from
Return values
0on success
-1on failure

Definition at line 1219 of file audiohook.c.

References AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, AST_AUDIOHOOK_STATUS_DONE, ast_channel_datastore_find(), ast_frame_adjust_volume(), ast_datastore::data, audiohook_volume::read_adjustment, ast_audiohook::status, and audiohook_volume::write_adjustment.

Referenced by audiohook_volume_get().

1220 {
1221  struct ast_datastore *datastore = NULL;
1222  struct audiohook_volume *audiohook_volume = NULL;
1223  int *gain = NULL;
1224 
1225  /* If the audiohook is shutting down don't even bother */
1226  if (audiohook->status == AST_AUDIOHOOK_STATUS_DONE) {
1227  return 0;
1228  }
1229 
1230  /* Try to find the datastore containg adjustment information, if we can't just bail out */
1231  if (!(datastore = ast_channel_datastore_find(chan, &audiohook_volume_datastore, NULL))) {
1232  return 0;
1233  }
1234 
1235  audiohook_volume = datastore->data;
1236 
1237  /* Based on direction grab the appropriate adjustment value */
1238  if (direction == AST_AUDIOHOOK_DIRECTION_READ) {
1239  gain = &audiohook_volume->read_adjustment;
1240  } else if (direction == AST_AUDIOHOOK_DIRECTION_WRITE) {
1241  gain = &audiohook_volume->write_adjustment;
1242  }
1243 
1244  /* If an adjustment value is present modify the frame */
1245  if (gain && *gain) {
1246  ast_frame_adjust_volume(frame, *gain);
1247  }
1248 
1249  return 0;
1250 }
Audiohook volume adjustment structure.
Definition: audiohook.c:1183
static const struct ast_datastore_info audiohook_volume_datastore
Datastore used to store audiohook volume information.
Definition: audiohook.c:1206
Structure for a data store object.
Definition: datastore.h:64
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
void * data
Definition: datastore.h:66
enum ast_audiohook_status status
Definition: audiohook.h:108
int ast_frame_adjust_volume(struct ast_frame *f, int adjustment)
Adjusts the volume of the audio samples contained in a frame.
Definition: main/frame.c:787
static void audiohook_volume_destroy ( void *  data)
static

Callback used to destroy the audiohook volume datastore.

Parameters
dataVolume information structure

Definition at line 1192 of file audiohook.c.

References ast_audiohook_destroy(), and audiohook_volume::audiohook.

1193 {
1194  struct audiohook_volume *audiohook_volume = data;
1195 
1196  /* Destroy the audiohook as it is no longer in use */
1197  ast_audiohook_destroy(&audiohook_volume->audiohook);
1198 
1199  /* Finally free ourselves, we are of no more use */
1200  ast_free(audiohook_volume);
1201 
1202  return;
1203 }
struct ast_audiohook audiohook
Definition: audiohook.c:1184
Audiohook volume adjustment structure.
Definition: audiohook.c:1183
int ast_audiohook_destroy(struct ast_audiohook *audiohook)
Destroys an audiohook structure.
Definition: audiohook.c:124
static struct audiohook_volume* audiohook_volume_get ( struct ast_channel chan,
int  create 
)
static

Helper function which finds and optionally creates an audiohook_volume_datastore datastore on a channel.

Parameters
chanChannel to look on
createWhether to create the datastore if not found
Returns
audiohook_volume structure on success
Return values
NULLon failure

Definition at line 1258 of file audiohook.c.

References ast_audiohook_attach(), ast_audiohook_init(), AST_AUDIOHOOK_MANIPULATE_ALL_RATES, AST_AUDIOHOOK_TYPE_MANIPULATE, ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_free(), audiohook_volume::audiohook, audiohook_volume_callback(), ast_datastore::data, and ast_audiohook::manipulate_callback.

Referenced by ast_audiohook_volume_adjust(), ast_audiohook_volume_get(), and ast_audiohook_volume_set().

1259 {
1260  struct ast_datastore *datastore = NULL;
1261  struct audiohook_volume *audiohook_volume = NULL;
1262 
1263  /* If we are able to find the datastore return the contents (which is actually an audiohook_volume structure) */
1264  if ((datastore = ast_channel_datastore_find(chan, &audiohook_volume_datastore, NULL))) {
1265  return datastore->data;
1266  }
1267 
1268  /* If we are not allowed to create a datastore or if we fail to create a datastore, bail out now as we have nothing for them */
1269  if (!create || !(datastore = ast_datastore_alloc(&audiohook_volume_datastore, NULL))) {
1270  return NULL;
1271  }
1272 
1273  /* Create a new audiohook_volume structure to contain our adjustments and audiohook */
1274  if (!(audiohook_volume = ast_calloc(1, sizeof(*audiohook_volume)))) {
1275  ast_datastore_free(datastore);
1276  return NULL;
1277  }
1278 
1279  /* Setup our audiohook structure so we can manipulate the audio */
1282 
1283  /* Attach the audiohook_volume blob to the datastore and attach to the channel */
1284  datastore->data = audiohook_volume;
1285  ast_channel_datastore_add(chan, datastore);
1286 
1287  /* All is well... put the audiohook into motion */
1288  ast_audiohook_attach(chan, &audiohook_volume->audiohook);
1289 
1290  return audiohook_volume;
1291 }
struct ast_audiohook audiohook
Definition: audiohook.c:1184
Audiohook volume adjustment structure.
Definition: audiohook.c:1183
int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source, enum ast_audiohook_init_flags init_flags)
Initialize an audiohook structure.
Definition: audiohook.c:100
int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook)
Attach audiohook to channel.
Definition: audiohook.c:484
static const struct ast_datastore_info audiohook_volume_datastore
Datastore used to store audiohook volume information.
Definition: audiohook.c:1206
Structure for a data store object.
Definition: datastore.h:64
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
ast_audiohook_manipulate_callback manipulate_callback
Definition: audiohook.h:118
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
void * data
Definition: datastore.h:66
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
static int audiohook_volume_callback(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction)
Helper function which actually gets called by audiohooks to perform the adjustment.
Definition: audiohook.c:1219
static struct ast_frame* dtmf_audiohook_write_list ( struct ast_channel chan,
struct ast_audiohook_list audiohook_list,
enum ast_audiohook_direction  direction,
struct ast_frame frame 
)
static

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

Parameters
chanChannel that the list is coming off of
audiohook_listList of audiohooks
directionDirection frame is coming in from
frameThe frame itself
Returns
frame on success
Return values
NULLon failure

Definition at line 758 of file audiohook.c.

References ast_audiohook_lock, AST_AUDIOHOOK_STATUS_DONE, AST_AUDIOHOOK_STATUS_RUNNING, ast_audiohook_unlock, ast_audiohook_update_status(), AST_AUDIOHOOK_WANTS_DTMF, ast_channel_is_bridged(), ast_channel_set_unbridged_nolock(), AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_audiohook::list, ast_audiohook::manipulate_callback, and ast_audiohook::status.

Referenced by ast_audiohook_write_list().

759 {
760  struct ast_audiohook *audiohook = NULL;
761  int removed = 0;
762 
763  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
764  ast_audiohook_lock(audiohook);
765  if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
767  removed = 1;
769  ast_audiohook_unlock(audiohook);
770  audiohook->manipulate_callback(audiohook, NULL, NULL, 0);
771  if (ast_channel_is_bridged(chan)) {
773  }
774  continue;
775  }
776  if (ast_test_flag(audiohook, AST_AUDIOHOOK_WANTS_DTMF)) {
777  audiohook->manipulate_callback(audiohook, chan, frame, direction);
778  }
779  ast_audiohook_unlock(audiohook);
780  }
782 
783  /* if an audiohook got removed, reset samplerate compatibility */
784  if (removed) {
785  audiohook_list_set_samplerate_compatibility(audiohook_list);
786  }
787  return frame;
788 }
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook's status.
Definition: audiohook.c:540
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
ast_audiohook_manipulate_callback manipulate_callback
Definition: audiohook.h:118
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
Definition: audiohook.h:318
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value)
Variant of ast_channel_set_unbridged. Use this if the channel is already locked prior to calling...
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10545
struct ast_audiohook::@185 list
enum ast_audiohook_status status
Definition: audiohook.h:108
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define ast_audiohook_lock(ah)
Lock an audiohook.
Definition: audiohook.h:313
static struct ast_audiohook* find_audiohook_by_source ( struct ast_audiohook_list audiohook_list,
const char *  source 
)
static

find an audiohook based on its source

Parameters
audiohook_listThe list of audiohooks to search in
sourceThe source of the audiohook we wish to find
Returns
corresponding audiohook
Return values
NULLif it cannot be found

Definition at line 612 of file audiohook.c.

References AST_LIST_TRAVERSE, ast_audiohook::list, and ast_audiohook::source.

Referenced by ast_audiohook_detach_source(), ast_audiohook_move_by_source(), and ast_audiohook_set_mute().

613 {
614  struct ast_audiohook *audiohook = NULL;
615 
616  AST_LIST_TRAVERSE(&audiohook_list->spy_list, audiohook, list) {
617  if (!strcasecmp(audiohook->source, source)) {
618  return audiohook;
619  }
620  }
621 
622  AST_LIST_TRAVERSE(&audiohook_list->whisper_list, audiohook, list) {
623  if (!strcasecmp(audiohook->source, source)) {
624  return audiohook;
625  }
626  }
627 
628  AST_LIST_TRAVERSE(&audiohook_list->manipulate_list, audiohook, list) {
629  if (!strcasecmp(audiohook->source, source)) {
630  return audiohook;
631  }
632  }
633 
634  return NULL;
635 }
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
const char * source
Definition: audiohook.h:110
struct ast_audiohook::@185 list

Variable Documentation

const struct ast_datastore_info audiohook_volume_datastore
static
Initial value:
= {
.type = "Volume",
}
static void audiohook_volume_destroy(void *data)
Callback used to destroy the audiohook volume datastore.
Definition: audiohook.c:1192

Datastore used to store audiohook volume information.

Definition at line 1206 of file audiohook.c.