Wed Jan 8 2020 09:49:58

Asterisk developer's documentation


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/linkedlists.h"
#include "asterisk/audiohook.h"
#include "asterisk/slinfactory.h"
#include "asterisk/frame.h"
#include "asterisk/translate.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...
 

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...
 
int 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)
 Initialize an audiohook structure. 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, format_t format)
 Reads a frame in from the audiohook structure. 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_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...
 
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)
 determines 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 struct ast_frameaudiohook_read_frame_both (struct ast_audiohook *audiohook, size_t samples)
 
static struct ast_frameaudiohook_read_frame_single (struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction)
 
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 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.

Function Documentation

int ast_audiohook_attach ( struct ast_channel chan,
struct ast_audiohook audiohook 
)

Attach audiohook to channel.

Parameters
chanChannel
audiohookAudiohook structure
Returns
Returns 0 on success, -1 on failure

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

349 {
350  ast_channel_lock(chan);
351 
352  if (!chan->audiohooks) {
353  /* Whoops... allocate a new structure */
354  if (!(chan->audiohooks = ast_calloc(1, sizeof(*chan->audiohooks)))) {
355  ast_channel_unlock(chan);
356  return -1;
357  }
361  }
362 
363  /* Drop into respective list */
364  if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY)
365  AST_LIST_INSERT_TAIL(&chan->audiohooks->spy_list, audiohook, list);
366  else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER)
367  AST_LIST_INSERT_TAIL(&chan->audiohooks->whisper_list, audiohook, list);
368  else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE)
369  AST_LIST_INSERT_TAIL(&chan->audiohooks->manipulate_list, audiohook, list);
370 
371  /* Change status over to running since it is now attached */
373 
374  ast_channel_unlock(chan);
375 
376  return 0;
377 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
struct ast_audiohook_list::@225 manipulate_list
enum ast_audiohook_type type
Definition: audiohook.h:106
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook&#39;s status.
Definition: audiohook.c:387
struct ast_audiohook_list * audiohooks
Definition: channel.h:764
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
struct ast_audiohook_list::@224 whisper_list
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:666
#define ast_calloc(a, b)
Definition: astmm.h:82
struct ast_audiohook_list::@223 spy_list
int ast_audiohook_destroy ( struct ast_audiohook audiohook)

Destroys an audiohook structure.

Parameters
audiohookAudiohook structure
Returns
Returns 0 on success, -1 on failure

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

97 {
98  /* Drop the factories used by this audiohook type */
99  switch (audiohook->type) {
102  /* Fall through intentionally */
105  break;
106  default:
107  break;
108  }
109 
110  /* Destroy translation path if present */
111  if (audiohook->trans_pvt)
113 
114  /* Lock and trigger be gone! */
115  ast_cond_destroy(&audiohook->trigger);
116  ast_mutex_destroy(&audiohook->lock);
117 
118  return 0;
119 }
struct ast_slinfactory write_factory
Definition: audiohook.h:111
enum ast_audiohook_type type
Definition: audiohook.h:106
ast_mutex_t lock
Definition: audiohook.h:104
struct ast_trans_pvt * trans_pvt
Definition: audiohook.h:115
void ast_slinfactory_destroy(struct ast_slinfactory *sf)
Destroy the contents of a slinfactory.
Definition: slinfactory.c:64
#define ast_cond_destroy(cond)
Definition: lock.h:168
ast_cond_t trigger
Definition: audiohook.h:105
struct ast_slinfactory read_factory
Definition: audiohook.h:110
#define ast_mutex_destroy(a)
Definition: lock.h:154
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:272
int ast_audiohook_detach ( struct ast_audiohook audiohook)

Detach audiohook from channel.

Parameters
audiohookAudiohook structure
Returns
Returns 0 on success, -1 on failure

Definition at line 401 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_callback(), destroy_monitor_audiohook(), disable_jack_hook(), and speex_write().

402 {
403  if (audiohook->status == AST_AUDIOHOOK_STATUS_NEW || audiohook->status == AST_AUDIOHOOK_STATUS_DONE)
404  return 0;
405 
407 
408  while (audiohook->status != AST_AUDIOHOOK_STATUS_DONE)
409  ast_audiohook_trigger_wait(audiohook);
410 
411  return 0;
412 }
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook&#39;s status.
Definition: audiohook.c:387
enum ast_audiohook_status status
Definition: audiohook.h:107
void ast_audiohook_trigger_wait(struct ast_audiohook *audiohook)
Wait for audiohook trigger to be triggered.
Definition: audiohook.c:776
int ast_audiohook_detach_list ( struct ast_audiohook_list audiohook_list)

Detach audiohooks from list and destroy said list.

Parameters
audiohook_listList of audiohooks
Returns
Returns 0 on success, -1 on failure

Definition at line 418 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::manipulate_callback, 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_write(), and destroy_hooks().

419 {
420  int i = 0;
421  struct ast_audiohook *audiohook = NULL;
422 
423  /* Drop any spies */
424  while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->spy_list, list))) {
426  }
427 
428  /* Drop any whispering sources */
429  while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->whisper_list, list))) {
431  }
432 
433  /* Drop any manipulaters */
434  while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->manipulate_list, list))) {
436  audiohook->manipulate_callback(audiohook, NULL, NULL, 0);
437  }
438 
439  /* Drop translation paths if present */
440  for (i = 0; i < 2; i++) {
441  if (audiohook_list->in_translate[i].trans_pvt)
442  ast_translator_free_path(audiohook_list->in_translate[i].trans_pvt);
443  if (audiohook_list->out_translate[i].trans_pvt)
445  }
446 
447  /* Free ourselves */
448  ast_free(audiohook_list);
449 
450  return 0;
451 }
struct ast_audiohook_list::@225 manipulate_list
struct ast_audiohook_translate out_translate[2]
Definition: audiohook.c:52
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook&#39;s status.
Definition: audiohook.c:387
struct ast_trans_pvt * trans_pvt
Definition: audiohook.c:46
ast_audiohook_manipulate_callback manipulate_callback
Definition: audiohook.h:116
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
struct ast_audiohook_list::@224 whisper_list
struct ast_audiohook::@143 list
#define ast_free(a)
Definition: astmm.h:97
struct ast_audiohook_translate in_translate[2]
Definition: audiohook.c:51
struct ast_audiohook_list::@223 spy_list
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:272
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
Returns
Returns 0 on success, -1 on failure

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

510 {
511  struct ast_audiohook *audiohook = NULL;
512 
513  ast_channel_lock(chan);
514 
515  /* Ensure the channel has audiohooks on it */
516  if (!chan->audiohooks) {
517  ast_channel_unlock(chan);
518  return -1;
519  }
520 
521  audiohook = find_audiohook_by_source(chan->audiohooks, source);
522 
523  ast_channel_unlock(chan);
524 
525  if (audiohook && audiohook->status != AST_AUDIOHOOK_STATUS_DONE)
527 
528  return (audiohook ? 0 : -1);
529 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook&#39;s status.
Definition: audiohook.c:387
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:458
struct ast_audiohook_list * audiohooks
Definition: channel.h:764
#define ast_channel_unlock(chan)
Definition: channel.h:2467
const char * source
Definition: audiohook.h:108
enum ast_audiohook_status status
Definition: audiohook.h:107
int ast_audiohook_init ( struct ast_audiohook audiohook,
enum ast_audiohook_type  type,
const char *  source 
)

Initialize an audiohook structure.

Parameters
audiohookAudiohook structure
type
source
Returns
Returns 0 on success, -1 on failure

Definition at line 64 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, ast_slinfactory_init(), and type.

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

65 {
66  /* Need to keep the type and source */
67  audiohook->type = type;
68  audiohook->source = source;
69 
70  /* Initialize lock that protects our audiohook */
71  ast_mutex_init(&audiohook->lock);
72  ast_cond_init(&audiohook->trigger, NULL);
73 
74  /* Setup the factories that are needed for this audiohook type */
75  switch (type) {
78  /* Fall through intentionally */
81  break;
82  default:
83  break;
84  }
85 
86  /* Since we are just starting out... this audiohook is new */
88 
89  return 0;
90 }
struct ast_slinfactory write_factory
Definition: audiohook.h:111
enum ast_audiohook_type type
Definition: audiohook.h:106
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook&#39;s status.
Definition: audiohook.c:387
#define ast_cond_init(cond, attr)
Definition: lock.h:167
ast_mutex_t lock
Definition: audiohook.h:104
const char * source
Definition: audiohook.h:108
void ast_slinfactory_init(struct ast_slinfactory *sf)
Initialize a slinfactory.
Definition: slinfactory.c:39
static const char type[]
Definition: chan_nbs.c:57
ast_cond_t trigger
Definition: audiohook.h:105
struct ast_slinfactory read_factory
Definition: audiohook.h:110
#define ast_mutex_init(pmutex)
Definition: lock.h:152
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 480 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().

481 {
482  struct ast_audiohook *audiohook;
483  enum ast_audiohook_status oldstatus;
484 
485  if (!old_chan->audiohooks || !(audiohook = find_audiohook_by_source(old_chan->audiohooks, source))) {
486  return;
487  }
488 
489  /* By locking both channels and the audiohook, we can assure that
490  * another thread will not have a chance to read the audiohook's status
491  * as done, even though ast_audiohook_remove signals the trigger
492  * condition.
493  */
494  ast_audiohook_lock(audiohook);
495  oldstatus = audiohook->status;
496 
497  ast_audiohook_remove(old_chan, audiohook);
498  ast_audiohook_attach(new_chan, audiohook);
499 
500  audiohook->status = oldstatus;
501  ast_audiohook_unlock(audiohook);
502 }
int ast_audiohook_remove(struct ast_channel *chan, struct ast_audiohook *audiohook)
Remove an audiohook from a specified channel.
Definition: audiohook.c:541
int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook)
Attach audiohook to channel.
Definition: audiohook.c:348
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
Definition: audiohook.h:272
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:458
struct ast_audiohook_list * audiohooks
Definition: channel.h:764
const char * source
Definition: audiohook.h:108
enum ast_audiohook_status status
Definition: audiohook.h:107
ast_audiohook_status
Definition: audiohook.h:42
#define ast_audiohook_lock(ah)
Lock an audiohook.
Definition: audiohook.h:267
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
audiohookAudiohook structure
samplesNumber of samples wanted
directionDirection the audio frame came from
formatFormat of frame remote side wants back
Returns
Returns frame on success, NULL on failure

Definition at line 313 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(), ast_audiohook::format, read_frame(), and ast_audiohook::trans_pvt.

Referenced by mixmonitor_thread(), and spy_generate().

314 {
315  struct ast_frame *read_frame = NULL, *final_frame = NULL;
316 
317  if (!(read_frame = (direction == AST_AUDIOHOOK_DIRECTION_BOTH ? audiohook_read_frame_both(audiohook, samples) : audiohook_read_frame_single(audiohook, samples, direction))))
318  return NULL;
319 
320  /* If they don't want signed linear back out, we'll have to send it through the translation path */
321  if (format != AST_FORMAT_SLINEAR) {
322  /* Rebuild translation path if different format then previously */
323  if (audiohook->format != format) {
324  if (audiohook->trans_pvt) {
326  audiohook->trans_pvt = NULL;
327  }
328  /* 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 */
330  ast_frfree(read_frame);
331  return NULL;
332  }
333  }
334  /* Convert to requested format, and allow the read in frame to be freed */
335  final_frame = ast_translate(audiohook->trans_pvt, read_frame, 1);
336  } else {
337  final_frame = read_frame;
338  }
339 
340  return final_frame;
341 }
struct ast_frame * ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, int consume)
translates one or more frames Apply an input frame into the translator and receive zero or one output...
Definition: translate.c:328
struct ast_trans_pvt * ast_translator_build_path(format_t dest, format_t source)
Builds a translator path Build a path (possibly NULL) from source to dest.
Definition: translate.c:282
struct ast_trans_pvt * trans_pvt
Definition: audiohook.h:115
static struct ast_frame * read_frame(struct ast_filestream *s, int *whennext)
Definition: file.c:712
static struct ast_frame * audiohook_read_frame_both(struct ast_audiohook *audiohook, size_t samples)
Definition: audiohook.c:215
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
Data structure associated with a single frame of data.
Definition: frame.h:142
#define ast_frfree(fr)
Definition: frame.h:583
static snd_pcm_format_t format
Definition: chan_alsa.c:93
static struct ast_frame * audiohook_read_frame_single(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction)
Definition: audiohook.c:187
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:272
int samples
Definition: frame.h:150
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
Returns
Returns 0 on success, -1 on failure
Note
The channel does not need to be locked before calling this function

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

542 {
543  ast_channel_lock(chan);
544 
545  if (!chan->audiohooks) {
546  ast_channel_unlock(chan);
547  return -1;
548  }
549 
550  if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY)
551  AST_LIST_REMOVE(&chan->audiohooks->spy_list, audiohook, list);
552  else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER)
553  AST_LIST_REMOVE(&chan->audiohooks->whisper_list, audiohook, list);
554  else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE)
555  AST_LIST_REMOVE(&chan->audiohooks->manipulate_list, audiohook, list);
556 
558 
559  ast_channel_unlock(chan);
560 
561  return 0;
562 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
struct ast_audiohook_list::@225 manipulate_list
enum ast_audiohook_type type
Definition: audiohook.h:106
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook&#39;s status.
Definition: audiohook.c:387
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:841
struct ast_audiohook_list * audiohooks
Definition: channel.h:764
struct ast_audiohook_list::@224 whisper_list
#define ast_channel_unlock(chan)
Definition: channel.h:2467
struct ast_audiohook_list::@223 spy_list
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 flag to set / clear
clearset 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().

1058 {
1059  struct ast_audiohook *audiohook = NULL;
1060 
1061  ast_channel_lock(chan);
1062 
1063  /* Ensure the channel has audiohooks on it */
1064  if (!chan->audiohooks) {
1065  ast_channel_unlock(chan);
1066  return -1;
1067  }
1068 
1069  audiohook = find_audiohook_by_source(chan->audiohooks, source);
1070 
1071  if (audiohook) {
1072  if (clear) {
1073  ast_clear_flag(audiohook, flag);
1074  } else {
1075  ast_set_flag(audiohook, flag);
1076  }
1077  }
1078 
1079  ast_channel_unlock(chan);
1080 
1081  return (audiohook ? 0 : -1);
1082 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
#define ast_set_flag(p, flag)
Definition: utils.h:70
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:458
struct ast_audiohook_list * audiohooks
Definition: channel.h:764
#define ast_channel_unlock(chan)
Definition: channel.h:2467
const char * source
Definition: audiohook.h:108
#define ast_clear_flag(p, flag)
Definition: utils.h:77
void ast_audiohook_trigger_wait ( struct ast_audiohook audiohook)

Wait for audiohook trigger to be triggered.

Parameters
audiohookAudiohook to wait on

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

777 {
778  struct timeval wait;
779  struct timespec ts;
780 
781  wait = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000));
782  ts.tv_sec = wait.tv_sec;
783  ts.tv_nsec = wait.tv_usec * 1000;
784 
785  ast_cond_timedwait(&audiohook->trigger, &audiohook->lock, &ts);
786 
787  return;
788 }
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
ast_mutex_t lock
Definition: audiohook.h:104
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:191
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: utils.c:1587
ast_cond_t trigger
Definition: audiohook.h:105
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:172
void ast_audiohook_update_status ( struct ast_audiohook audiohook,
enum ast_audiohook_status  status 
)

Update audiohook's status.

Parameters
audiohookAudiohook structure
statusAudiohook 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 387 of file audiohook.c.

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

388 {
389  ast_audiohook_lock(audiohook);
390  if (audiohook->status != AST_AUDIOHOOK_STATUS_DONE) {
391  audiohook->status = status;
392  ast_cond_signal(&audiohook->trigger);
393  }
394  ast_audiohook_unlock(audiohook);
395 }
#define ast_cond_signal(cond)
Definition: lock.h:169
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
Definition: audiohook.h:272
ast_cond_t trigger
Definition: audiohook.h:105
enum ast_audiohook_status status
Definition: audiohook.h:107
#define ast_audiohook_lock(ah)
Lock an audiohook.
Definition: audiohook.h:267
jack_status_t status
Definition: app_jack.c:143
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
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().

1031 {
1032  struct audiohook_volume *audiohook_volume = NULL;
1033 
1034  /* Attempt to find the audiohook volume information, and create an audiohook if none exists */
1035  if (!(audiohook_volume = audiohook_volume_get(chan, 1))) {
1036  return -1;
1037  }
1038 
1039  /* Based on the direction change the specific adjustment value */
1040  if (direction == AST_AUDIOHOOK_DIRECTION_READ || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
1041  audiohook_volume->read_adjustment += volume;
1042  }
1043  if (direction == AST_AUDIOHOOK_DIRECTION_WRITE || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
1044  audiohook_volume->write_adjustment += volume;
1045  }
1046 
1047  return 0;
1048 }
Audiohook volume adjustment structure.
Definition: audiohook.c:864
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:938
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
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().

1005 {
1006  struct audiohook_volume *audiohook_volume = NULL;
1007  int adjustment = 0;
1008 
1009  /* Attempt to find the audiohook volume information, but do not create it as we only want to look at the values */
1010  if (!(audiohook_volume = audiohook_volume_get(chan, 0))) {
1011  return 0;
1012  }
1013 
1014  /* Grab the adjustment value based on direction given */
1015  if (direction == AST_AUDIOHOOK_DIRECTION_READ) {
1016  adjustment = audiohook_volume->read_adjustment;
1017  } else if (direction == AST_AUDIOHOOK_DIRECTION_WRITE) {
1018  adjustment = audiohook_volume->write_adjustment;
1019  }
1020 
1021  return adjustment;
1022 }
Audiohook volume adjustment structure.
Definition: audiohook.c:864
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:938
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
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().

980 {
981  struct audiohook_volume *audiohook_volume = NULL;
982 
983  /* Attempt to find the audiohook volume information, but only create it if we are not setting the adjustment value to zero */
984  if (!(audiohook_volume = audiohook_volume_get(chan, (volume ? 1 : 0)))) {
985  return -1;
986  }
987 
988  /* Now based on the direction set the proper value */
989  if (direction == AST_AUDIOHOOK_DIRECTION_READ || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
990  audiohook_volume->read_adjustment = volume;
991  }
992  if (direction == AST_AUDIOHOOK_DIRECTION_WRITE || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
993  audiohook_volume->write_adjustment = volume;
994  }
995 
996  return 0;
997 }
Audiohook volume adjustment structure.
Definition: audiohook.c:864
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:938
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
audiohookAudiohook structure
directionDirection the audio frame came from
frameFrame to write in
Returns
Returns 0 on success, -1 on failure

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

128 {
129  struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
130  struct ast_slinfactory *other_factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->write_factory : &audiohook->read_factory);
131  struct timeval *rwtime = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_time : &audiohook->write_time), previous_time = *rwtime;
132  int our_factory_samples;
133  int our_factory_ms;
134  int other_factory_samples;
135  int other_factory_ms;
136  int muteme = 0;
137 
138  /* Update last feeding time to be current */
139  *rwtime = ast_tvnow();
140 
141  our_factory_samples = ast_slinfactory_available(factory);
142  our_factory_ms = ast_tvdiff_ms(*rwtime, previous_time) + (our_factory_samples / 8);
143  other_factory_samples = ast_slinfactory_available(other_factory);
144  other_factory_ms = other_factory_samples / 8;
145 
146  if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC) && other_factory_samples && (our_factory_ms - other_factory_ms > AST_AUDIOHOOK_SYNC_TOLERANCE)) {
147  if (option_debug)
148  ast_log(LOG_DEBUG, "Flushing audiohook %p so it remains in sync\n", audiohook);
149  ast_slinfactory_flush(factory);
150  ast_slinfactory_flush(other_factory);
151  }
152 
153  if (ast_test_flag(audiohook, AST_AUDIOHOOK_SMALL_QUEUE) && (our_factory_samples > 640 || other_factory_samples > 640)) {
154  if (option_debug) {
155  ast_log(LOG_DEBUG, "Audiohook %p has stale audio in its factories. Flushing them both\n", audiohook);
156  }
157  ast_slinfactory_flush(factory);
158  ast_slinfactory_flush(other_factory);
159  }
160 
161  /* swap frame data for zeros if mute is required */
162  if ((ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_READ) && (direction == AST_AUDIOHOOK_DIRECTION_READ)) ||
163  (ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_WRITE) && (direction == AST_AUDIOHOOK_DIRECTION_WRITE)) ||
165  muteme = 1;
166  }
167 
168  if (muteme && frame->datalen > 0) {
169  ast_frame_clear(frame);
170  }
171 
172  /* Write frame out to respective factory */
173  ast_slinfactory_feed(factory, frame);
174 
175  /* If we need to notify the respective handler of this audiohook, do so */
177  ast_cond_signal(&audiohook->trigger);
179  ast_cond_signal(&audiohook->trigger);
180  } else if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC)) {
181  ast_cond_signal(&audiohook->trigger);
182  }
183 
184  return 0;
185 }
struct ast_slinfactory write_factory
Definition: audiohook.h:111
int ast_frame_clear(struct ast_frame *frame)
Clear all audio samples from an ast_frame. The frame must be AST_FRAME_VOICE and AST_FORMAT_SLINEAR.
Definition: frame.c:1629
void ast_slinfactory_flush(struct ast_slinfactory *sf)
Flush the contents of a slinfactory.
Definition: slinfactory.c:201
#define ast_test_flag(p, flag)
Definition: utils.h:63
int option_debug
Definition: asterisk.c:182
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:142
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
#define LOG_DEBUG
Definition: logger.h:122
#define ast_cond_signal(cond)
Definition: lock.h:169
unsigned int ast_slinfactory_available(const struct ast_slinfactory *sf)
Retrieve number of samples currently in a slinfactory.
Definition: slinfactory.c:196
int datalen
Definition: frame.h:148
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
ast_cond_t trigger
Definition: audiohook.h:105
struct ast_slinfactory read_factory
Definition: audiohook.h:110
#define AST_AUDIOHOOK_SYNC_TOLERANCE
Definition: audiohook.h:76
struct timeval write_time
Definition: audiohook.h:113
struct timeval read_time
Definition: audiohook.h:112
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
Return frame on success, NULL on failure

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

763 {
764  /* Pass off frame to it's respective list write function */
765  if (frame->frametype == AST_FRAME_VOICE)
766  return audio_audiohook_write_list(chan, audiohook_list, direction, frame);
767  else if (frame->frametype == AST_FRAME_DTMF)
768  return dtmf_audiohook_write_list(chan, audiohook_list, direction, frame);
769  else
770  return frame;
771 }
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:622
#define AST_FRAME_DTMF
Definition: frame.h:128
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:571
enum ast_frame_type frametype
Definition: frame.h:144
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 744 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().

745 {
746  if (AST_LIST_EMPTY(&audiohook_list->spy_list) &&
747  AST_LIST_EMPTY(&audiohook_list->whisper_list) &&
748  AST_LIST_EMPTY(&audiohook_list->manipulate_list)) {
749 
750  return 1;
751  }
752  return 0;
753 }
struct ast_audiohook_list::@225 manipulate_list
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
struct ast_audiohook_list::@224 whisper_list
struct ast_audiohook_list::@223 spy_list
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
Return the number of audiohooks which are from the source specified

Note: Function performs nlocking.

Definition at line 791 of file audiohook.c.

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

Referenced by builtin_automixmonitor().

792 {
793  int count = 0;
794  struct ast_audiohook *ah = NULL;
795 
796  if (!chan->audiohooks)
797  return -1;
798 
799  switch (type) {
801  AST_LIST_TRAVERSE(&chan->audiohooks->spy_list, ah, list) {
802  if (!strcmp(ah->source, source)) {
803  count++;
804  }
805  }
806  break;
809  if (!strcmp(ah->source, source)) {
810  count++;
811  }
812  }
813  break;
816  if (!strcmp(ah->source, source)) {
817  count++;
818  }
819  }
820  break;
821  default:
822  ast_log(LOG_DEBUG, "Invalid audiohook type supplied, (%u)\n", type);
823  return -1;
824  }
825 
826  return count;
827 }
struct ast_audiohook_list::@225 manipulate_list
#define LOG_DEBUG
Definition: logger.h:122
struct ast_audiohook_list * audiohooks
Definition: channel.h:764
struct ast_audiohook_list::@224 whisper_list
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_audiohook::@143 list
const char * source
Definition: audiohook.h:108
static const char type[]
Definition: chan_nbs.c:57
struct ast_audiohook_list::@223 spy_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
Return the number of running audiohooks which are from the source specified

Note: Function performs no locking.

Definition at line 830 of file audiohook.c.

References AST_AUDIOHOOK_STATUS_RUNNING, AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, AST_LIST_TRAVERSE, ast_log(), ast_channel::audiohooks, ast_audiohook::list, LOG_DEBUG, 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().

831 {
832  int count = 0;
833  struct ast_audiohook *ah = NULL;
834  if (!chan->audiohooks)
835  return -1;
836 
837  switch (type) {
839  AST_LIST_TRAVERSE(&chan->audiohooks->spy_list, ah, list) {
840  if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
841  count++;
842  }
843  break;
846  if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
847  count++;
848  }
849  break;
852  if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
853  count++;
854  }
855  break;
856  default:
857  ast_log(LOG_DEBUG, "Invalid audiohook type supplied, (%u)\n", type);
858  return -1;
859  }
860  return count;
861 }
struct ast_audiohook_list::@225 manipulate_list
#define LOG_DEBUG
Definition: logger.h:122
struct ast_audiohook_list * audiohooks
Definition: channel.h:764
struct ast_audiohook_list::@224 whisper_list
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_audiohook::@143 list
const char * source
Definition: audiohook.h:108
static const char type[]
Definition: chan_nbs.c:57
enum ast_audiohook_status status
Definition: audiohook.h:107
struct ast_audiohook_list::@223 spy_list
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. The result of this part is end_frame will be updated to point to middle_frame if any audiohook manipulation took place. Part_3: Translate end_frame's audio back into the format of start frame if necessary. At this point if middle_frame != end_frame, we are guaranteed that no manipulation took place and middle_frame can be freed as it was translated... If middle_frame was not translated and still pointed to start_frame, it would be equal to end_frame as well regardless if manipulation took place which would not result in this free. The result of this part is end_frame is guaranteed to be the format of start_frame for the return.

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

Definition at line 622 of file audiohook.c.

References AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_lock, AST_AUDIOHOOK_STATUS_DONE, AST_AUDIOHOOK_STATUS_RUNNING, ast_audiohook_unlock, ast_audiohook_update_status(), ast_audiohook_write_frame(), AST_FORMAT_SLINEAR, ast_frfree, AST_LIST_EMPTY, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_slinear_saturated_add(), ast_slinfactory_available(), ast_slinfactory_read(), ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_frame_subclass::codec, ast_audiohook_translate::format, ast_audiohook_list::in_translate, ast_audiohook::list, ast_audiohook::manipulate_callback, ast_audiohook_list::manipulate_list, ast_audiohook_list::out_translate, ast_frame::samples, ast_audiohook_list::spy_list, ast_audiohook::status, ast_frame::subclass, ast_audiohook_translate::trans_pvt, ast_audiohook_list::whisper_list, and ast_audiohook::write_factory.

Referenced by ast_audiohook_write_list().

623 {
624  struct ast_audiohook_translate *in_translate = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook_list->in_translate[0] : &audiohook_list->in_translate[1]);
625  struct ast_audiohook_translate *out_translate = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook_list->out_translate[0] : &audiohook_list->out_translate[1]);
626  struct ast_frame *start_frame = frame, *middle_frame = frame, *end_frame = frame;
627  struct ast_audiohook *audiohook = NULL;
628  int samples = frame->samples;
629 
630  /* ---Part_1. translate start_frame to SLINEAR if necessary. */
631  /* If the frame coming in is not signed linear we have to send it through the in_translate path */
632  if (frame->subclass.codec != AST_FORMAT_SLINEAR) {
633  if (in_translate->format != frame->subclass.codec) {
634  if (in_translate->trans_pvt)
635  ast_translator_free_path(in_translate->trans_pvt);
636  if (!(in_translate->trans_pvt = ast_translator_build_path(AST_FORMAT_SLINEAR, frame->subclass.codec)))
637  return frame;
638  in_translate->format = frame->subclass.codec;
639  }
640  if (!(middle_frame = ast_translate(in_translate->trans_pvt, frame, 0)))
641  return frame;
642  samples = middle_frame->samples;
643  }
644 
645  /* ---Part_2: Send middle_frame to spy and manipulator lists. middle_frame is guaranteed to be SLINEAR here.*/
646  /* Queue up signed linear frame to each spy */
647  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
648  ast_audiohook_lock(audiohook);
649  if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
652  ast_audiohook_unlock(audiohook);
653  continue;
654  }
655  ast_audiohook_write_frame(audiohook, direction, middle_frame);
656  ast_audiohook_unlock(audiohook);
657  }
659 
660  /* If this frame is being written out to the channel then we need to use whisper sources */
661  if (direction == AST_AUDIOHOOK_DIRECTION_WRITE && !AST_LIST_EMPTY(&audiohook_list->whisper_list)) {
662  int i = 0;
663  short read_buf[samples], combine_buf[samples], *data1 = NULL, *data2 = NULL;
664  memset(&combine_buf, 0, sizeof(combine_buf));
665  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->whisper_list, audiohook, list) {
666  ast_audiohook_lock(audiohook);
667  if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
670  ast_audiohook_unlock(audiohook);
671  continue;
672  }
673  if (ast_slinfactory_available(&audiohook->write_factory) >= samples && ast_slinfactory_read(&audiohook->write_factory, read_buf, samples)) {
674  /* Take audio from this whisper source and combine it into our main buffer */
675  for (i = 0, data1 = combine_buf, data2 = read_buf; i < samples; i++, data1++, data2++)
676  ast_slinear_saturated_add(data1, data2);
677  }
678  ast_audiohook_unlock(audiohook);
679  }
681  /* We take all of the combined whisper sources and combine them into the audio being written out */
682  for (i = 0, data1 = middle_frame->data.ptr, data2 = combine_buf; i < samples; i++, data1++, data2++)
683  ast_slinear_saturated_add(data1, data2);
684  end_frame = middle_frame;
685  }
686 
687  /* Pass off frame to manipulate audiohooks */
688  if (!AST_LIST_EMPTY(&audiohook_list->manipulate_list)) {
689  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
690  ast_audiohook_lock(audiohook);
691  if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
694  ast_audiohook_unlock(audiohook);
695  /* We basically drop all of our links to the manipulate audiohook and prod it to do it's own destructive things */
696  audiohook->manipulate_callback(audiohook, chan, NULL, direction);
697  continue;
698  }
699  /* Feed in frame to manipulation. */
700  if (audiohook->manipulate_callback(audiohook, chan, middle_frame, direction)) {
701  /* XXX IGNORE FAILURE */
702 
703  /* If the manipulation fails then the frame will be returned in its original state.
704  * Since there are potentially more manipulator callbacks in the list, no action should
705  * be taken here to exit early. */
706  }
707  ast_audiohook_unlock(audiohook);
708  }
710  end_frame = middle_frame;
711  }
712 
713  /* ---Part_3: Decide what to do with the end_frame (whether to transcode or not) */
714  if (middle_frame == end_frame) {
715  /* Middle frame was modified and became the end frame... let's see if we need to transcode */
716  if (end_frame->subclass.codec != start_frame->subclass.codec) {
717  if (out_translate->format != start_frame->subclass.codec) {
718  if (out_translate->trans_pvt)
719  ast_translator_free_path(out_translate->trans_pvt);
720  if (!(out_translate->trans_pvt = ast_translator_build_path(start_frame->subclass.codec, AST_FORMAT_SLINEAR))) {
721  /* We can't transcode this... drop our middle frame and return the original */
722  ast_frfree(middle_frame);
723  return start_frame;
724  }
725  out_translate->format = start_frame->subclass.codec;
726  }
727  /* Transcode from our middle (signed linear) frame to new format of the frame that came in */
728  if (!(end_frame = ast_translate(out_translate->trans_pvt, middle_frame, 0))) {
729  /* Failed to transcode the frame... drop it and return the original */
730  ast_frfree(middle_frame);
731  return start_frame;
732  }
733  /* Here's the scoop... middle frame is no longer of use to us */
734  ast_frfree(middle_frame);
735  }
736  } else {
737  /* No frame was modified, we can just drop our middle frame and pass the frame we got in out */
738  ast_frfree(middle_frame);
739  }
740 
741  return end_frame;
742 }
union ast_frame_subclass subclass
Definition: frame.h:146
struct ast_audiohook_list::@225 manipulate_list
struct ast_slinfactory write_factory
Definition: audiohook.h:111
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:127
struct ast_audiohook_translate out_translate[2]
Definition: audiohook.c:52
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook&#39;s status.
Definition: audiohook.c:387
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
struct ast_trans_pvt * trans_pvt
Definition: audiohook.c:46
struct ast_frame * ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, int consume)
translates one or more frames Apply an input frame into the translator and receive zero or one output...
Definition: translate.c:328
format_t codec
Definition: frame.h:137
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
unsigned int ast_slinfactory_available(const struct ast_slinfactory *sf)
Retrieve number of samples currently in a slinfactory.
Definition: slinfactory.c:196
ast_audiohook_manipulate_callback manipulate_callback
Definition: audiohook.h:116
struct ast_trans_pvt * ast_translator_build_path(format_t dest, format_t source)
Builds a translator path Build a path (possibly NULL) from source to dest.
Definition: translate.c:282
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
Definition: audiohook.h:272
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
static force_inline void ast_slinear_saturated_add(short *input, short *value)
Definition: utils.h:312
struct ast_audiohook_list::@224 whisper_list
struct ast_audiohook::@143 list
struct ast_audiohook_translate in_translate[2]
Definition: audiohook.c:51
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
Data structure associated with a single frame of data.
Definition: frame.h:142
int ast_slinfactory_read(struct ast_slinfactory *sf, short *buf, size_t samples)
Read samples from a slinfactory.
Definition: slinfactory.c:142
enum ast_audiohook_status status
Definition: audiohook.h:107
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
#define ast_frfree(fr)
Definition: frame.h:583
struct ast_audiohook_list::@223 spy_list
#define ast_audiohook_lock(ah)
Lock an audiohook.
Definition: audiohook.h:267
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:272
int samples
Definition: frame.h:150
static struct ast_frame* audiohook_read_frame_both ( struct ast_audiohook audiohook,
size_t  samples 
)
static

Definition at line 215 of file audiohook.c.

References ast_debug, AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_frdup(), ast_log(), ast_slinear_saturated_add(), ast_slinear_saturated_divide(), ast_slinear_saturated_multiply(), ast_slinfactory_available(), ast_slinfactory_read(), ast_tvdiff_ms(), ast_tvnow(), buf1, buf2, ast_frame::data, ast_frame::frametype, LOG_DEBUG, option_debug, ast_audiohook::options, ast_frame::ptr, ast_audiohook::read_factory, ast_audiohook::read_time, ast_audiohook_options::read_volume, ast_frame::samples, ast_audiohook::write_factory, ast_audiohook::write_time, and ast_audiohook_options::write_volume.

Referenced by ast_audiohook_read_frame().

216 {
217  int i = 0, usable_read, usable_write;
218  short buf1[samples], buf2[samples], *read_buf = NULL, *write_buf = NULL, *final_buf = NULL, *data1 = NULL, *data2 = NULL;
219  struct ast_frame frame = {
221  .subclass.codec = AST_FORMAT_SLINEAR,
222  .data.ptr = NULL,
223  .datalen = sizeof(buf1),
224  .samples = samples,
225  };
226 
227  /* Make sure both factories have the required samples */
228  usable_read = (ast_slinfactory_available(&audiohook->read_factory) >= samples ? 1 : 0);
229  usable_write = (ast_slinfactory_available(&audiohook->write_factory) >= samples ? 1 : 0);
230 
231  if (!usable_read && !usable_write) {
232  /* If both factories are unusable bail out */
233  ast_debug(2, "Read factory %p and write factory %p both fail to provide %zu samples\n", &audiohook->read_factory, &audiohook->write_factory, samples);
234  return NULL;
235  }
236 
237  /* If we want to provide only a read factory make sure we aren't waiting for other audio */
238  if (usable_read && !usable_write && (ast_tvdiff_ms(ast_tvnow(), audiohook->write_time) < (samples/8)*2)) {
239  ast_debug(3, "Write factory %p was pretty quick last time, waiting for them.\n", &audiohook->write_factory);
240  return NULL;
241  }
242 
243  /* If we want to provide only a write factory make sure we aren't waiting for other audio */
244  if (usable_write && !usable_read && (ast_tvdiff_ms(ast_tvnow(), audiohook->read_time) < (samples/8)*2)) {
245  ast_debug(3, "Read factory %p was pretty quick last time, waiting for them.\n", &audiohook->read_factory);
246  return NULL;
247  }
248 
249  /* Start with the read factory... if there are enough samples, read them in */
250  if (usable_read) {
251  if (ast_slinfactory_read(&audiohook->read_factory, buf1, samples)) {
252  read_buf = buf1;
253  /* Adjust read volume if need be */
254  if (audiohook->options.read_volume) {
255  int count = 0;
256  short adjust_value = abs(audiohook->options.read_volume);
257  for (count = 0; count < samples; count++) {
258  if (audiohook->options.read_volume > 0)
259  ast_slinear_saturated_multiply(&buf1[count], &adjust_value);
260  else if (audiohook->options.read_volume < 0)
261  ast_slinear_saturated_divide(&buf1[count], &adjust_value);
262  }
263  }
264  }
265  } else if (option_debug > 2)
266  ast_log(LOG_DEBUG, "Failed to get %d samples from read factory %p\n", (int)samples, &audiohook->read_factory);
267 
268  /* Move on to the write factory... if there are enough samples, read them in */
269  if (usable_write) {
270  if (ast_slinfactory_read(&audiohook->write_factory, buf2, samples)) {
271  write_buf = buf2;
272  /* Adjust write volume if need be */
273  if (audiohook->options.write_volume) {
274  int count = 0;
275  short adjust_value = abs(audiohook->options.write_volume);
276  for (count = 0; count < samples; count++) {
277  if (audiohook->options.write_volume > 0)
278  ast_slinear_saturated_multiply(&buf2[count], &adjust_value);
279  else if (audiohook->options.write_volume < 0)
280  ast_slinear_saturated_divide(&buf2[count], &adjust_value);
281  }
282  }
283  }
284  } else if (option_debug > 2)
285  ast_log(LOG_DEBUG, "Failed to get %d samples from write factory %p\n", (int)samples, &audiohook->write_factory);
286 
287  /* Basically we figure out which buffer to use... and if mixing can be done here */
288  if (!read_buf && !write_buf)
289  return NULL;
290  else if (read_buf && write_buf) {
291  for (i = 0, data1 = read_buf, data2 = write_buf; i < samples; i++, data1++, data2++)
292  ast_slinear_saturated_add(data1, data2);
293  final_buf = buf1;
294  } else if (read_buf)
295  final_buf = buf1;
296  else if (write_buf)
297  final_buf = buf2;
298 
299  /* Make the final buffer part of the frame, so it gets duplicated fine */
300  frame.data.ptr = final_buf;
301 
302  /* Yahoo, a combined copy of the audio! */
303  return ast_frdup(&frame);
304 }
struct ast_slinfactory write_factory
Definition: audiohook.h:111
int option_debug
Definition: asterisk.c:182
void * ptr
Definition: frame.h:160
static struct ast_threadstorage buf2
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
#define LOG_DEBUG
Definition: logger.h:122
unsigned int ast_slinfactory_available(const struct ast_slinfactory *sf)
Retrieve number of samples currently in a slinfactory.
Definition: slinfactory.c:196
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline void ast_slinear_saturated_add(short *input, short *value)
Definition: utils.h:312
static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
Definition: utils.h:338
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct ast_threadstorage buf1
static force_inline void ast_slinear_saturated_divide(short *input, short *value)
Definition: utils.h:351
struct ast_slinfactory read_factory
Definition: audiohook.h:110
struct ast_audiohook_options options
Definition: audiohook.h:117
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
struct timeval write_time
Definition: audiohook.h:113
Data structure associated with a single frame of data.
Definition: frame.h:142
int ast_slinfactory_read(struct ast_slinfactory *sf, short *buf, size_t samples)
Read samples from a slinfactory.
Definition: slinfactory.c:142
enum ast_frame_type frametype
Definition: frame.h:144
struct timeval read_time
Definition: audiohook.h:112
union ast_frame::@172 data
struct ast_frame * ast_frdup(const struct ast_frame *fr)
Copies a frame.
Definition: frame.c:474
int samples
Definition: frame.h:150
static struct ast_frame* audiohook_read_frame_single ( struct ast_audiohook audiohook,
size_t  samples,
enum ast_audiohook_direction  direction 
)
static

Definition at line 187 of file audiohook.c.

References AST_AUDIOHOOK_DIRECTION_READ, AST_FORMAT_SLINEAR, ast_frame_adjust_volume(), AST_FRAME_VOICE, ast_frdup(), ast_slinfactory_available(), ast_slinfactory_read(), ast_frame::frametype, ast_audiohook::options, ast_audiohook::read_factory, ast_audiohook_options::read_volume, ast_audiohook::write_factory, and ast_audiohook_options::write_volume.

Referenced by ast_audiohook_read_frame().

188 {
189  struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
190  int vol = (direction == AST_AUDIOHOOK_DIRECTION_READ ? audiohook->options.read_volume : audiohook->options.write_volume);
191  short buf[samples];
192  struct ast_frame frame = {
194  .subclass.codec = AST_FORMAT_SLINEAR,
195  .data.ptr = buf,
196  .datalen = sizeof(buf),
197  .samples = samples,
198  };
199 
200  /* Ensure the factory is able to give us the samples we want */
201  if (samples > ast_slinfactory_available(factory))
202  return NULL;
203 
204  /* Read data in from factory */
205  if (!ast_slinfactory_read(factory, buf, samples))
206  return NULL;
207 
208  /* If a volume adjustment needs to be applied apply it */
209  if (vol)
210  ast_frame_adjust_volume(&frame, vol);
211 
212  return ast_frdup(&frame);
213 }
struct ast_slinfactory write_factory
Definition: audiohook.h:111
unsigned int ast_slinfactory_available(const struct ast_slinfactory *sf)
Retrieve number of samples currently in a slinfactory.
Definition: slinfactory.c:196
struct ast_slinfactory read_factory
Definition: audiohook.h:110
struct ast_audiohook_options options
Definition: audiohook.h:117
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
int ast_frame_adjust_volume(struct ast_frame *f, int adjustment)
Adjusts the volume of the audio samples contained in a frame.
Definition: frame.c:1584
Data structure associated with a single frame of data.
Definition: frame.h:142
int ast_slinfactory_read(struct ast_slinfactory *sf, short *buf, size_t samples)
Read samples from a slinfactory.
Definition: slinfactory.c:142
enum ast_frame_type frametype
Definition: frame.h:144
struct ast_frame * ast_frdup(const struct ast_frame *fr)
Copies a frame.
Definition: frame.c:474
int samples
Definition: frame.h:150
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
Returns
Returns 0 on success, -1 on failure

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

901 {
902  struct ast_datastore *datastore = NULL;
903  struct audiohook_volume *audiohook_volume = NULL;
904  int *gain = NULL;
905 
906  /* If the audiohook is shutting down don't even bother */
907  if (audiohook->status == AST_AUDIOHOOK_STATUS_DONE) {
908  return 0;
909  }
910 
911  /* Try to find the datastore containg adjustment information, if we can't just bail out */
912  if (!(datastore = ast_channel_datastore_find(chan, &audiohook_volume_datastore, NULL))) {
913  return 0;
914  }
915 
916  audiohook_volume = datastore->data;
917 
918  /* Based on direction grab the appropriate adjustment value */
919  if (direction == AST_AUDIOHOOK_DIRECTION_READ) {
920  gain = &audiohook_volume->read_adjustment;
921  } else if (direction == AST_AUDIOHOOK_DIRECTION_WRITE) {
922  gain = &audiohook_volume->write_adjustment;
923  }
924 
925  /* If an adjustment value is present modify the frame */
926  if (gain && *gain) {
927  ast_frame_adjust_volume(frame, *gain);
928  }
929 
930  return 0;
931 }
static struct ast_datastore_info audiohook_volume_datastore
Datastore used to store audiohook volume information.
Definition: audiohook.c:888
Audiohook volume adjustment structure.
Definition: audiohook.c:864
Structure for a data store object.
Definition: datastore.h:54
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:2604
void * data
Definition: datastore.h:56
int ast_frame_adjust_volume(struct ast_frame *f, int adjustment)
Adjusts the volume of the audio samples contained in a frame.
Definition: frame.c:1584
enum ast_audiohook_status status
Definition: audiohook.h:107
static void audiohook_volume_destroy ( void *  data)
static

Callback used to destroy the audiohook volume datastore.

Parameters
dataVolume information structure
Returns
Returns nothing

Definition at line 874 of file audiohook.c.

References ast_audiohook_destroy(), ast_free, and audiohook_volume::audiohook.

875 {
876  struct audiohook_volume *audiohook_volume = data;
877 
878  /* Destroy the audiohook as it is no longer in use */
879  ast_audiohook_destroy(&audiohook_volume->audiohook);
880 
881  /* Finally free ourselves, we are of no more use */
882  ast_free(audiohook_volume);
883 
884  return;
885 }
struct ast_audiohook audiohook
Definition: audiohook.c:865
Audiohook volume adjustment structure.
Definition: audiohook.c:864
int ast_audiohook_destroy(struct ast_audiohook *audiohook)
Destroys an audiohook structure.
Definition: audiohook.c:96
#define ast_free(a)
Definition: astmm.h:97
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
Returns audiohook_volume structure on success, NULL on failure

Definition at line 938 of file audiohook.c.

References ast_audiohook_attach(), ast_audiohook_init(), AST_AUDIOHOOK_TYPE_MANIPULATE, ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc(), 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().

939 {
940  struct ast_datastore *datastore = NULL;
941  struct audiohook_volume *audiohook_volume = NULL;
942 
943  /* If we are able to find the datastore return the contents (which is actually an audiohook_volume structure) */
944  if ((datastore = ast_channel_datastore_find(chan, &audiohook_volume_datastore, NULL))) {
945  return datastore->data;
946  }
947 
948  /* 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 */
949  if (!create || !(datastore = ast_datastore_alloc(&audiohook_volume_datastore, NULL))) {
950  return NULL;
951  }
952 
953  /* Create a new audiohook_volume structure to contain our adjustments and audiohook */
954  if (!(audiohook_volume = ast_calloc(1, sizeof(*audiohook_volume)))) {
955  ast_datastore_free(datastore);
956  return NULL;
957  }
958 
959  /* Setup our audiohook structure so we can manipulate the audio */
960  ast_audiohook_init(&audiohook_volume->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "Volume");
962 
963  /* Attach the audiohook_volume blob to the datastore and attach to the channel */
964  datastore->data = audiohook_volume;
965  ast_channel_datastore_add(chan, datastore);
966 
967  /* All is well... put the audiohook into motion */
968  ast_audiohook_attach(chan, &audiohook_volume->audiohook);
969 
970  return audiohook_volume;
971 }
struct ast_audiohook audiohook
Definition: audiohook.c:865
static struct ast_datastore_info audiohook_volume_datastore
Datastore used to store audiohook volume information.
Definition: audiohook.c:888
Audiohook volume adjustment structure.
Definition: audiohook.c:864
int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source)
Initialize an audiohook structure.
Definition: audiohook.c:64
int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook)
Attach audiohook to channel.
Definition: audiohook.c:348
Structure for a data store object.
Definition: datastore.h:54
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:2604
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:65
ast_audiohook_manipulate_callback manipulate_callback
Definition: audiohook.h:116
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
Definition: datastore.c:98
void * data
Definition: datastore.h:56
#define ast_calloc(a, b)
Definition: astmm.h:82
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2590
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:900
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
Return frame on success, NULL on failure

Definition at line 571 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_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_test_flag, ast_audiohook::list, ast_audiohook::manipulate_callback, ast_audiohook_list::manipulate_list, and ast_audiohook::status.

Referenced by ast_audiohook_write_list().

572 {
573  struct ast_audiohook *audiohook = NULL;
574 
575  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
576  ast_audiohook_lock(audiohook);
577  if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
580  ast_audiohook_unlock(audiohook);
581  audiohook->manipulate_callback(audiohook, NULL, NULL, 0);
582  continue;
583  }
584  if (ast_test_flag(audiohook, AST_AUDIOHOOK_WANTS_DTMF))
585  audiohook->manipulate_callback(audiohook, chan, frame, direction);
586  ast_audiohook_unlock(audiohook);
587  }
589 
590  return frame;
591 }
struct ast_audiohook_list::@225 manipulate_list
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook&#39;s status.
Definition: audiohook.c:387
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
ast_audiohook_manipulate_callback manipulate_callback
Definition: audiohook.h:116
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
Definition: audiohook.h:272
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
struct ast_audiohook::@143 list
enum ast_audiohook_status status
Definition: audiohook.h:107
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
#define ast_audiohook_lock(ah)
Lock an audiohook.
Definition: audiohook.h:267
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
Return the corresponding audiohook or NULL if it cannot be found.

Definition at line 458 of file audiohook.c.

References AST_LIST_TRAVERSE, ast_audiohook::list, ast_audiohook_list::manipulate_list, ast_audiohook::source, ast_audiohook_list::spy_list, and ast_audiohook_list::whisper_list.

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

459 {
460  struct ast_audiohook *audiohook = NULL;
461 
462  AST_LIST_TRAVERSE(&audiohook_list->spy_list, audiohook, list) {
463  if (!strcasecmp(audiohook->source, source))
464  return audiohook;
465  }
466 
467  AST_LIST_TRAVERSE(&audiohook_list->whisper_list, audiohook, list) {
468  if (!strcasecmp(audiohook->source, source))
469  return audiohook;
470  }
471 
472  AST_LIST_TRAVERSE(&audiohook_list->manipulate_list, audiohook, list) {
473  if (!strcasecmp(audiohook->source, source))
474  return audiohook;
475  }
476 
477  return NULL;
478 }
struct ast_audiohook_list::@225 manipulate_list
struct ast_audiohook_list::@224 whisper_list
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_audiohook::@143 list
const char * source
Definition: audiohook.h:108
struct ast_audiohook_list::@223 spy_list

Variable Documentation

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:874

Datastore used to store audiohook volume information.

Definition at line 888 of file audiohook.c.