Asterisk - The Open Source Telephony Project  18.5.0
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/linkedlists.h"
#include "asterisk/audiohook.h"
#include "asterisk/slinfactory.h"
#include "asterisk/frame.h"
#include "asterisk/translate.h"
#include "asterisk/format_cache.h"
Include dependency graph for audiohook.c:

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. 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)
 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

◆ AST_AUDIOHOOK_LONG_QUEUE_TOLERANCE

#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().

◆ AST_AUDIOHOOK_SMALL_QUEUE_TOLERANCE

#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().

◆ AST_AUDIOHOOK_SYNC_TOLERANCE

#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().

◆ DEFAULT_INTERNAL_SAMPLE_RATE

#define DEFAULT_INTERNAL_SAMPLE_RATE   8000

◆ SHOULD_MUTE

#define SHOULD_MUTE (   hook,
  dir 
)

Function Documentation

◆ ast_audiohook_attach()

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 501 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_audiohooks(), ast_channel_audiohooks_set(), ast_channel_flags(), ast_channel_is_bridged(), ast_channel_lock, ast_channel_set_unbridged_nolock(), ast_channel_unlock, AST_FLAG_ZOMBIE, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_TAIL, ast_test_flag, audiohook_list_set_samplerate_compatibility(), audiohook_set_internal_rate(), DEFAULT_INTERNAL_SAMPLE_RATE, ast_audiohook_list::list_internal_samp_rate, ast_audiohook_list::manipulate_list, ast_audiohook_list::spy_list, ast_audiohook::type, and ast_audiohook_list::whisper_list.

Referenced by audiohook_move(), audiohook_volume_get(), detect_write(), enable_jack_hook(), init_hook(), pitchshift_helper(), scramble_write(), set_talk_detect(), snoop_setup_audiohook(), speex_write(), start_spying(), startmon(), and volume_write().

502 {
503  ast_channel_lock(chan);
504 
505  /* Don't allow an audiohook to be attached to a channel that is already hung up.
506  * The hang up process is what actually notifies the audiohook that it should
507  * stop.
508  */
510  ast_channel_unlock(chan);
511  return -1;
512  }
513 
514  if (!ast_channel_audiohooks(chan)) {
515  struct ast_audiohook_list *ahlist;
516  /* Whoops... allocate a new structure */
517  if (!(ahlist = ast_calloc(1, sizeof(*ahlist)))) {
518  ast_channel_unlock(chan);
519  return -1;
520  }
521  ast_channel_audiohooks_set(chan, ahlist);
525  /* This sample rate will adjust as necessary when writing to the list. */
527  }
528 
529  /* Drop into respective list */
530  if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY) {
531  AST_LIST_INSERT_TAIL(&ast_channel_audiohooks(chan)->spy_list, audiohook, list);
532  } else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER) {
533  AST_LIST_INSERT_TAIL(&ast_channel_audiohooks(chan)->whisper_list, audiohook, list);
534  } else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) {
536  }
537 
538  /*
539  * Initialize the audiohook's rate to the default. If it needs to be,
540  * it will get updated later.
541  */
544 
545  /* Change status over to running since it is now attached */
547 
548  if (ast_channel_is_bridged(chan)) {
550  }
551 
552  ast_channel_unlock(chan);
553 
554  return 0;
555 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
struct ast_audiohook_list::@344 manipulate_list
enum ast_audiohook_type type
Definition: audiohook.h:106
int list_internal_samp_rate
Definition: audiohook.c:61
#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:565
void ast_channel_audiohooks_set(struct ast_channel *chan, struct ast_audiohook_list *value)
struct ast_audiohook_list::@342 spy_list
static int audiohook_set_internal_rate(struct ast_audiohook *audiohook, int rate, int reset)
Definition: audiohook.c:70
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:730
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10746
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680
struct ast_audiohook_list::@343 whisper_list
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
struct ast_audiohook_list * ast_channel_audiohooks(const struct ast_channel *chan)
static void audiohook_list_set_samplerate_compatibility(struct ast_audiohook_list *audiohook_list)
Definition: audiohook.c:468
#define DEFAULT_INTERNAL_SAMPLE_RATE
Definition: audiohook.c:48

◆ ast_audiohook_destroy()

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 133 of file audiohook.c.

References ao2_cleanup, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_cond_destroy, ast_mutex_destroy, 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(), channel_spy(), datastore_destroy_cb(), destroy_callback(), destroy_jack_data(), destroy_monitor_audiohook(), hook_datastore_destroy_callback(), launch_monitor_thread(), and snoop_destroy().

134 {
135  /* Drop the factories used by this audiohook type */
136  switch (audiohook->type) {
141  break;
142  default:
143  break;
144  }
145 
146  /* Destroy translation path if present */
147  if (audiohook->trans_pvt)
149 
150  ao2_cleanup(audiohook->format);
151 
152  /* Lock and trigger be gone! */
153  ast_cond_destroy(&audiohook->trigger);
154  ast_mutex_destroy(&audiohook->lock);
155 
156  return 0;
157 }
struct ast_slinfactory write_factory
Definition: audiohook.h:112
enum ast_audiohook_type type
Definition: audiohook.h:106
ast_mutex_t lock
Definition: audiohook.h:104
struct ast_format * format
Definition: audiohook.h:115
struct ast_trans_pvt * trans_pvt
Definition: audiohook.h:116
void ast_slinfactory_destroy(struct ast_slinfactory *sf)
Destroy the contents of a slinfactory.
Definition: slinfactory.c:58
#define ast_cond_destroy(cond)
Definition: lock.h:200
ast_cond_t trigger
Definition: audiohook.h:105
struct ast_slinfactory read_factory
Definition: audiohook.h:111
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define ast_mutex_destroy(a)
Definition: lock.h:186
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:475

◆ ast_audiohook_detach()

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 579 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(), hook_datastore_destroy_callback(), snoop_hangup(), and speex_write().

580 {
581  if (audiohook->status == AST_AUDIOHOOK_STATUS_NEW || audiohook->status == AST_AUDIOHOOK_STATUS_DONE) {
582  return 0;
583  }
584 
586 
587  while (audiohook->status != AST_AUDIOHOOK_STATUS_DONE) {
588  ast_audiohook_trigger_wait(audiohook);
589  }
590 
591  return 0;
592 }
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook&#39;s status.
Definition: audiohook.c:565
void ast_audiohook_trigger_wait(struct ast_audiohook *audiohook)
Wait for audiohook trigger to be triggered.
Definition: audiohook.c:1142
enum ast_audiohook_status status
Definition: audiohook.h:107

◆ ast_audiohook_detach_list()

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)
Returns
Nothing

Definition at line 594 of file audiohook.c.

References ao2_cleanup, AST_AUDIOHOOK_STATUS_DONE, ast_audiohook_update_status(), ast_free, AST_LIST_REMOVE_HEAD, ast_translator_free_path(), ast_audiohook_translate::format, ast_audiohook_list::in_translate, ast_audiohook::list, ast_audiohook::manipulate_callback, ast_audiohook_list::manipulate_list, NULL, 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_stream(), and destroy_hooks().

595 {
596  int i;
597  struct ast_audiohook *audiohook;
598 
599  if (!audiohook_list) {
600  return;
601  }
602 
603  /* Drop any spies */
604  while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->spy_list, list))) {
606  }
607 
608  /* Drop any whispering sources */
609  while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->whisper_list, list))) {
611  }
612 
613  /* Drop any manipulaters */
614  while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->manipulate_list, list))) {
616  audiohook->manipulate_callback(audiohook, NULL, NULL, 0);
617  }
618 
619  /* Drop translation paths if present */
620  for (i = 0; i < 2; i++) {
621  if (audiohook_list->in_translate[i].trans_pvt) {
622  ast_translator_free_path(audiohook_list->in_translate[i].trans_pvt);
623  ao2_cleanup(audiohook_list->in_translate[i].format);
624  }
625  if (audiohook_list->out_translate[i].trans_pvt) {
627  ao2_cleanup(audiohook_list->in_translate[i].format);
628  }
629  }
630 
631  /* Free ourselves */
632  ast_free(audiohook_list);
633 }
struct ast_audiohook_list::@344 manipulate_list
struct ast_format * format
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:565
struct ast_audiohook_translate out_translate[2]
Definition: audiohook.c:64
struct ast_trans_pvt * trans_pvt
Definition: audiohook.c:51
struct ast_audiohook_list::@342 spy_list
#define NULL
Definition: resample.c:96
ast_audiohook_manipulate_callback manipulate_callback
Definition: audiohook.h:117
struct ast_audiohook::@225 list
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define ast_free(a)
Definition: astmm.h:182
struct ast_audiohook_translate in_translate[2]
Definition: audiohook.c:63
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_audiohook_list::@343 whisper_list
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:475

◆ ast_audiohook_detach_source()

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 731 of file audiohook.c.

References AST_AUDIOHOOK_STATUS_DONE, AST_AUDIOHOOK_STATUS_SHUTDOWN, ast_audiohook_update_status(), ast_channel_audiohooks(), ast_channel_lock, ast_channel_unlock, find_audiohook_by_source(), NULL, and ast_audiohook::status.

732 {
733  struct ast_audiohook *audiohook = NULL;
734 
735  ast_channel_lock(chan);
736 
737  /* Ensure the channel has audiohooks on it */
738  if (!ast_channel_audiohooks(chan)) {
739  ast_channel_unlock(chan);
740  return -1;
741  }
742 
744 
745  ast_channel_unlock(chan);
746 
747  if (audiohook && audiohook->status != AST_AUDIOHOOK_STATUS_DONE) {
749  }
750 
751  return (audiohook ? 0 : -1);
752 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
Update audiohook&#39;s status.
Definition: audiohook.c:565
#define NULL
Definition: resample.c:96
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:640
#define ast_channel_unlock(chan)
Definition: channel.h:2946
const char * source
Definition: audiohook.h:109
enum ast_audiohook_status status
Definition: audiohook.h:107
struct ast_audiohook_list * ast_channel_audiohooks(const struct ast_channel *chan)

◆ ast_audiohook_init()

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.

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

Definition at line 108 of file audiohook.c.

References AST_AUDIOHOOK_STATUS_NEW, ast_audiohook_update_status(), ast_cond_init, ast_mutex_init, audiohook_set_internal_rate(), DEFAULT_INTERNAL_SAMPLE_RATE, ast_audiohook::init_flags, ast_audiohook::lock, NULL, ast_audiohook::source, ast_audiohook::trigger, ast_audiohook::type, and type.

Referenced by attach_barge(), audiohook_volume_get(), channel_spy(), detect_write(), enable_jack_hook(), hook_state_alloc(), launch_monitor_thread(), pitchshift_helper(), scramble_write(), set_talk_detect(), snoop_setup_audiohook(), speex_write(), and volume_write().

109 {
110  /* Need to keep the type and source */
111  audiohook->type = type;
112  audiohook->source = source;
113 
114  /* Initialize lock that protects our audiohook */
115  ast_mutex_init(&audiohook->lock);
116  ast_cond_init(&audiohook->trigger, NULL);
117 
118  audiohook->init_flags = init_flags;
119 
120  /* initialize internal rate at 8khz, this will adjust if necessary */
122 
123  /* Since we are just starting out... this audiohook is new */
125 
126  return 0;
127 }
static const char type[]
Definition: chan_ooh323.c:109
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:565
#define ast_cond_init(cond, attr)
Definition: lock.h:199
ast_mutex_t lock
Definition: audiohook.h:104
static int audiohook_set_internal_rate(struct ast_audiohook *audiohook, int rate, int reset)
Definition: audiohook.c:70
#define NULL
Definition: resample.c:96
enum ast_audiohook_init_flags init_flags
Definition: audiohook.h:108
const char * source
Definition: audiohook.h:109
ast_cond_t trigger
Definition: audiohook.h:105
#define ast_mutex_init(pmutex)
Definition: lock.h:184
#define DEFAULT_INTERNAL_SAMPLE_RATE
Definition: audiohook.c:48

◆ ast_audiohook_move_all()

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 700 of file audiohook.c.

References ast_channel_audiohooks(), AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, audiohook_move(), ast_audiohook_list::manipulate_list, ast_audiohook_list::spy_list, and ast_audiohook_list::whisper_list.

Referenced by channel_do_masquerade().

701 {
702  struct ast_audiohook *audiohook;
703  struct ast_audiohook_list *audiohook_list;
704 
705  audiohook_list = ast_channel_audiohooks(old_chan);
706  if (!audiohook_list) {
707  return;
708  }
709 
710  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
711  audiohook_move(old_chan, new_chan, audiohook);
712  }
714 
715  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->whisper_list, audiohook, list) {
716  audiohook_move(old_chan, new_chan, audiohook);
717  }
719 
720  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
721  audiohook_move(old_chan, new_chan, audiohook);
722  }
724 }
struct ast_audiohook_list::@344 manipulate_list
struct ast_audiohook_list::@342 spy_list
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
static void audiohook_move(struct ast_channel *old_chan, struct ast_channel *new_chan, struct ast_audiohook *audiohook)
Definition: audiohook.c:665
struct ast_audiohook_list::@343 whisper_list
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
struct ast_audiohook_list * ast_channel_audiohooks(const struct ast_channel *chan)

◆ ast_audiohook_move_by_source()

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 684 of file audiohook.c.

References ast_channel_audiohooks(), audiohook_move(), and find_audiohook_by_source().

685 {
686  struct ast_audiohook *audiohook;
687 
688  if (!ast_channel_audiohooks(old_chan)) {
689  return;
690  }
691 
693  if (!audiohook) {
694  return;
695  }
696 
697  audiohook_move(old_chan, new_chan, audiohook);
698 }
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:640
const char * source
Definition: audiohook.h:109
static void audiohook_move(struct ast_channel *old_chan, struct ast_channel *new_chan, struct ast_audiohook *audiohook)
Definition: audiohook.c:665
struct ast_audiohook_list * ast_channel_audiohooks(const struct ast_channel *chan)

◆ ast_audiohook_read_frame()

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
audiohookAudiohook structure
samplesNumber of samples wanted in requested output format
directionDirection the audio frame came from
formatFormat of frame remote side wants back
Returns
Returns frame on success, NULL on failure

Definition at line 449 of file audiohook.c.

References audiohook_read_frame_helper(), and NULL.

Referenced by snoop_read(), and spy_generate().

450 {
451  return audiohook_read_frame_helper(audiohook, samples, direction, format, NULL, NULL);
452 }
#define NULL
Definition: resample.c:96
static struct ast_frame * audiohook_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)
Definition: audiohook.c:380
direction

◆ ast_audiohook_read_frame_all()

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.

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

Parameters
audiohookAudiohook structure
samplesNumber of samples wanted
directionDirection the audio frame came from
formatFormat of frame remote side wants back
read_frameframe pointer for copying read frame data
write_frameframe pointer for copying write frame data
Returns
Returns frame on success, NULL on failure

Definition at line 463 of file audiohook.c.

References AST_AUDIOHOOK_DIRECTION_BOTH, and audiohook_read_frame_helper().

Referenced by mixmonitor_thread().

464 {
465  return audiohook_read_frame_helper(audiohook, samples, AST_AUDIOHOOK_DIRECTION_BOTH, format, read_frame, write_frame);
466 }
static struct ast_frame * audiohook_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)
Definition: audiohook.c:380

◆ ast_audiohook_remove()

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 764 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_audiohooks(), ast_channel_is_bridged(), ast_channel_lock, ast_channel_set_unbridged_nolock(), ast_channel_unlock, AST_LIST_REMOVE, audiohook_list_set_samplerate_compatibility(), ast_audiohook::list, and ast_audiohook::type.

Referenced by audiohook_move(), remove_detect(), remove_scrambler(), remove_talk_detect(), and speex_write().

765 {
766  ast_channel_lock(chan);
767 
768  if (!ast_channel_audiohooks(chan)) {
769  ast_channel_unlock(chan);
770  return -1;
771  }
772 
773  if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY) {
774  AST_LIST_REMOVE(&ast_channel_audiohooks(chan)->spy_list, audiohook, list);
775  } else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER) {
776  AST_LIST_REMOVE(&ast_channel_audiohooks(chan)->whisper_list, audiohook, list);
777  } else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) {
778  AST_LIST_REMOVE(&ast_channel_audiohooks(chan)->manipulate_list, audiohook, list);
779  }
780 
783 
784  if (ast_channel_is_bridged(chan)) {
786  }
787 
788  ast_channel_unlock(chan);
789 
790  return 0;
791 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
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:565
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
struct ast_audiohook::@225 list
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:10746
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_audiohook_list * ast_channel_audiohooks(const struct ast_channel *chan)
static void audiohook_list_set_samplerate_compatibility(struct ast_audiohook_list *audiohook_list)
Definition: audiohook.c:468

◆ ast_audiohook_set_mute()

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 1424 of file audiohook.c.

References ast_channel_audiohooks(), ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_set_flag, find_audiohook_by_source(), and NULL.

Referenced by manager_mute_mixmonitor().

1425 {
1426  struct ast_audiohook *audiohook = NULL;
1427 
1428  ast_channel_lock(chan);
1429 
1430  /* Ensure the channel has audiohooks on it */
1431  if (!ast_channel_audiohooks(chan)) {
1432  ast_channel_unlock(chan);
1433  return -1;
1434  }
1435 
1437 
1438  if (audiohook) {
1439  if (clear) {
1440  ast_clear_flag(audiohook, flag);
1441  } else {
1442  ast_set_flag(audiohook, flag);
1443  }
1444  }
1445 
1446  ast_channel_unlock(chan);
1447 
1448  return (audiohook ? 0 : -1);
1449 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define NULL
Definition: resample.c:96
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:640
long int flag
Definition: f2c.h:83
#define ast_channel_unlock(chan)
Definition: channel.h:2946
const char * source
Definition: audiohook.h:109
#define ast_clear_flag(p, flag)
Definition: utils.h:77
struct ast_audiohook_list * ast_channel_audiohooks(const struct ast_channel *chan)

◆ ast_audiohook_trigger_wait()

void ast_audiohook_trigger_wait ( struct ast_audiohook audiohook)

Wait for audiohook trigger to be triggered.

Parameters
audiohookAudiohook to wait on

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

1143 {
1144  struct timeval wait;
1145  struct timespec ts;
1146 
1147  wait = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000));
1148  ts.tv_sec = wait.tv_sec;
1149  ts.tv_nsec = wait.tv_usec * 1000;
1150 
1151  ast_cond_timedwait(&audiohook->trigger, &audiohook->lock, &ts);
1152 
1153  return;
1154 }
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
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:238
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
ast_cond_t trigger
Definition: audiohook.h:105
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:204

◆ ast_audiohook_update_status()

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 565 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(), dtmf_audiohook_write_list(), and stop_mixmonitor_full().

566 {
567  ast_audiohook_lock(audiohook);
568  if (audiohook->status != AST_AUDIOHOOK_STATUS_DONE) {
569  audiohook->status = status;
570  ast_cond_signal(&audiohook->trigger);
571  }
572  ast_audiohook_unlock(audiohook);
573 }
#define ast_cond_signal(cond)
Definition: lock.h:201
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
Definition: audiohook.h:300
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:295
jack_status_t status
Definition: app_jack.c:146

◆ ast_audiohook_volume_adjust()

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 1397 of file audiohook.c.

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

Referenced by execute_menu_entry().

1398 {
1400 
1401  /* Attempt to find the audiohook volume information, and create an audiohook if none exists */
1402  if (!(audiohook_volume = audiohook_volume_get(chan, 1))) {
1403  return -1;
1404  }
1405 
1406  /* Based on the direction change the specific adjustment value */
1408  audiohook_volume->read_adjustment += volume;
1409  }
1411  audiohook_volume->write_adjustment += volume;
1412  }
1413 
1414  return 0;
1415 }
Audiohook volume adjustment structure.
Definition: audiohook.c:1231
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:1305
#define NULL
Definition: resample.c:96
direction

◆ ast_audiohook_volume_get()

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 1371 of file audiohook.c.

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

Referenced by confbridge_exec().

1372 {
1374  int adjustment = 0;
1375 
1376  /* Attempt to find the audiohook volume information, but do not create it as we only want to look at the values */
1377  if (!(audiohook_volume = audiohook_volume_get(chan, 0))) {
1378  return 0;
1379  }
1380 
1381  /* Grab the adjustment value based on direction given */
1383  adjustment = audiohook_volume->read_adjustment;
1384  } else if (direction == AST_AUDIOHOOK_DIRECTION_WRITE) {
1385  adjustment = audiohook_volume->write_adjustment;
1386  }
1387 
1388  return adjustment;
1389 }
Audiohook volume adjustment structure.
Definition: audiohook.c:1231
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:1305
#define NULL
Definition: resample.c:96
direction

◆ ast_audiohook_volume_set()

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 1346 of file audiohook.c.

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

Referenced by confbridge_exec(), and execute_menu_entry().

1347 {
1349 
1350  /* Attempt to find the audiohook volume information, but only create it if we are not setting the adjustment value to zero */
1351  if (!(audiohook_volume = audiohook_volume_get(chan, (volume ? 1 : 0)))) {
1352  return -1;
1353  }
1354 
1355  /* Now based on the direction set the proper value */
1357  audiohook_volume->read_adjustment = volume;
1358  }
1360  audiohook_volume->write_adjustment = volume;
1361  }
1362 
1363  return 0;
1364 }
Audiohook volume adjustment structure.
Definition: audiohook.c:1231
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:1305
#define NULL
Definition: resample.c:96
direction

◆ ast_audiohook_write_frame()

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 170 of file audiohook.c.

References 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_cond_signal, ast_debug, ast_slinfactory_available(), ast_slinfactory_feed(), ast_slinfactory_flush(), ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), 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(), channel_spy(), and snoop_write().

171 {
172  struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
173  struct ast_slinfactory *other_factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->write_factory : &audiohook->read_factory);
174  struct timeval *rwtime = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_time : &audiohook->write_time), previous_time = *rwtime;
175  int our_factory_samples;
176  int our_factory_ms;
177  int other_factory_samples;
178  int other_factory_ms;
179 
180  /* Update last feeding time to be current */
181  *rwtime = ast_tvnow();
182 
183  our_factory_samples = ast_slinfactory_available(factory);
184  our_factory_ms = ast_tvdiff_ms(*rwtime, previous_time) + (our_factory_samples / (audiohook->hook_internal_samp_rate / 1000));
185  other_factory_samples = ast_slinfactory_available(other_factory);
186  other_factory_ms = other_factory_samples / (audiohook->hook_internal_samp_rate / 1000);
187 
188  if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC) && (our_factory_ms - other_factory_ms > AST_AUDIOHOOK_SYNC_TOLERANCE)) {
189  ast_debug(1, "Flushing audiohook %p so it remains in sync\n", audiohook);
190  ast_slinfactory_flush(factory);
191  ast_slinfactory_flush(other_factory);
192  }
193 
194  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))) {
195  ast_debug(1, "Audiohook %p has stale audio in its factories. Flushing them both\n", audiohook);
196  ast_slinfactory_flush(factory);
197  ast_slinfactory_flush(other_factory);
198  } else if ((our_factory_ms > AST_AUDIOHOOK_LONG_QUEUE_TOLERANCE) || (other_factory_ms > AST_AUDIOHOOK_LONG_QUEUE_TOLERANCE)) {
199  ast_debug(1, "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  }
203 
204  /* Write frame out to respective factory */
205  ast_slinfactory_feed(factory, frame);
206 
207  /* If we need to notify the respective handler of this audiohook, do so */
209  ast_cond_signal(&audiohook->trigger);
211  ast_cond_signal(&audiohook->trigger);
212  } else if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC)) {
213  ast_cond_signal(&audiohook->trigger);
214  }
215 
216  return 0;
217 }
struct ast_slinfactory write_factory
Definition: audiohook.h:112
void ast_slinfactory_flush(struct ast_slinfactory *sf)
Flush the contents of a slinfactory.
Definition: slinfactory.c:204
#define ast_test_flag(p, flag)
Definition: utils.h:63
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:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define ast_cond_signal(cond)
Definition: lock.h:201
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.
Definition: logger.h:452
unsigned int hook_internal_samp_rate
Definition: audiohook.h:119
#define AST_AUDIOHOOK_SMALL_QUEUE_TOLERANCE
Definition: audiohook.c:45
ast_cond_t trigger
Definition: audiohook.h:105
struct ast_slinfactory read_factory
Definition: audiohook.h:111
struct timeval write_time
Definition: audiohook.h:114
struct timeval read_time
Definition: audiohook.h:113
direction

◆ ast_audiohook_write_list()

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 1127 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_stream().

1128 {
1129  /* Pass off frame to it's respective list write function */
1130  if (frame->frametype == AST_FRAME_VOICE) {
1131  return audio_audiohook_write_list(chan, audiohook_list, direction, frame);
1132  } else if (frame->frametype == AST_FRAME_DTMF) {
1133  return dtmf_audiohook_write_list(chan, audiohook_list, direction, frame);
1134  } else {
1135  return frame;
1136  }
1137 }
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:955
#define AST_FRAME_DTMF
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:800
enum ast_frame_type frametype
direction

◆ ast_audiohook_write_list_empty()

int ast_audiohook_write_list_empty ( struct ast_audiohook_list audiohook_list)

Determine if a audiohook_list is empty or not.

Parameters
audiohookAudiohook to check. (NULL also means empty)

retval 0 false, 1 true

Definition at line 1112 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(), ast_channel_has_audio_frame_or_monitor(), ast_channel_has_hook_requiring_audio(), and ast_write_stream().

1113 {
1114  return !audiohook_list
1115  || (AST_LIST_EMPTY(&audiohook_list->spy_list)
1116  && AST_LIST_EMPTY(&audiohook_list->whisper_list)
1117  && AST_LIST_EMPTY(&audiohook_list->manipulate_list));
1118 }
struct ast_audiohook_list::@344 manipulate_list
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
struct ast_audiohook_list::@342 spy_list
struct ast_audiohook_list::@343 whisper_list

◆ ast_channel_audiohook_count_by_source()

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 1157 of file audiohook.c.

References AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_channel_audiohooks(), ast_debug, AST_LIST_TRAVERSE, ast_audiohook::list, NULL, and ast_audiohook::source.

Referenced by feature_automixmonitor().

1158 {
1159  int count = 0;
1160  struct ast_audiohook *ah = NULL;
1161 
1162  if (!ast_channel_audiohooks(chan)) {
1163  return -1;
1164  }
1165 
1166  switch (type) {
1168  AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->spy_list, ah, list) {
1169  if (!strcmp(ah->source, source)) {
1170  count++;
1171  }
1172  }
1173  break;
1175  AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->whisper_list, ah, list) {
1176  if (!strcmp(ah->source, source)) {
1177  count++;
1178  }
1179  }
1180  break;
1182  AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->manipulate_list, ah, list) {
1183  if (!strcmp(ah->source, source)) {
1184  count++;
1185  }
1186  }
1187  break;
1188  default:
1189  ast_debug(1, "Invalid audiohook type supplied, (%u)\n", type);
1190  return -1;
1191  }
1192 
1193  return count;
1194 }
static const char type[]
Definition: chan_ooh323.c:109
#define NULL
Definition: resample.c:96
struct ast_audiohook::@225 list
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
const char * source
Definition: audiohook.h:109
struct ast_audiohook_list * ast_channel_audiohooks(const struct ast_channel *chan)

◆ ast_channel_audiohook_count_by_source_running()

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 1197 of file audiohook.c.

References AST_AUDIOHOOK_STATUS_RUNNING, AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_channel_audiohooks(), ast_debug, AST_LIST_TRAVERSE, ast_audiohook::list, NULL, ast_audiohook::source, and ast_audiohook::status.

1198 {
1199  int count = 0;
1200  struct ast_audiohook *ah = NULL;
1201  if (!ast_channel_audiohooks(chan))
1202  return -1;
1203 
1204  switch (type) {
1206  AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->spy_list, ah, list) {
1207  if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
1208  count++;
1209  }
1210  break;
1212  AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->whisper_list, ah, list) {
1213  if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
1214  count++;
1215  }
1216  break;
1218  AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->manipulate_list, ah, list) {
1219  if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
1220  count++;
1221  }
1222  break;
1223  default:
1224  ast_debug(1, "Invalid audiohook type supplied, (%u)\n", type);
1225  return -1;
1226  }
1227  return count;
1228 }
static const char type[]
Definition: chan_ooh323.c:109
#define NULL
Definition: resample.c:96
struct ast_audiohook::@225 list
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
const char * source
Definition: audiohook.h:109
enum ast_audiohook_status status
Definition: audiohook.h:107
struct ast_audiohook_list * ast_channel_audiohooks(const struct ast_channel *chan)

◆ audio_audiohook_write_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. 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
Return frame on success, NULL on failure

Definition at line 955 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_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(), audiohook_list_set_hook_rate(), audiohook_list_set_samplerate_compatibility(), audiohook_list_translate_to_native(), audiohook_list_translate_to_slin(), ast_frame_subclass::format, ast_audiohook::list, ast_audiohook_list::list_internal_samp_rate, ast_audiohook::manipulate_callback, ast_audiohook_list::manipulate_list, NULL, ast_audiohook::read_factory, ast_frame::samples, ast_audiohook_list::spy_list, ast_audiohook::status, ast_frame::subclass, ast_audiohook_list::whisper_list, and ast_audiohook::write_factory.

Referenced by ast_audiohook_write_list().

956 {
957  struct ast_frame *start_frame = frame, *middle_frame = frame, *end_frame = frame;
958  struct ast_audiohook *audiohook = NULL;
959  int samples;
960  int middle_frame_manipulated = 0;
961  int removed = 0;
962  int internal_sample_rate;
963 
964  /* ---Part_1. translate start_frame to SLINEAR if necessary. */
965  if (!(middle_frame = audiohook_list_translate_to_slin(audiohook_list, direction, start_frame))) {
966  return frame;
967  }
968 
969  /* If the translation resulted in an interpolated frame then immediately return as audiohooks
970  * rely on actual media being present to do things.
971  */
972  if (!middle_frame->data.ptr) {
973  if (middle_frame != start_frame) {
974  ast_frfree(middle_frame);
975  }
976  return start_frame;
977  }
978 
979  samples = middle_frame->samples;
980 
981  /*
982  * While processing each audiohook check to see if the internal sample rate needs
983  * to be adjusted (it should be the highest rate specified between formats and
984  * hooks). The given audiohook_list's internal sample rate is then set to the
985  * updated value before returning.
986  *
987  * If slin compatibility mode is turned on then an audiohook's internal sample
988  * rate is set to its audiohook_list's rate. If an audiohook_list's rate is
989  * adjusted during this pass then the change is picked up by the audiohooks
990  * on the next pass.
991  */
992  internal_sample_rate = audiohook_list->list_internal_samp_rate;
993 
994  /* ---Part_2: Send middle_frame to spy and manipulator lists. middle_frame is guaranteed to be SLINEAR here.*/
995  /* Queue up signed linear frame to each spy */
996  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
997  ast_audiohook_lock(audiohook);
998  if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
1000  removed = 1;
1002  ast_audiohook_unlock(audiohook);
1003  if (ast_channel_is_bridged(chan)) {
1005  }
1006  continue;
1007  }
1008  audiohook_list_set_hook_rate(audiohook_list, audiohook, &internal_sample_rate);
1009  ast_audiohook_write_frame(audiohook, direction, middle_frame);
1010  ast_audiohook_unlock(audiohook);
1011  }
1013 
1014  /* If this frame is being written out to the channel then we need to use whisper sources */
1015  if (!AST_LIST_EMPTY(&audiohook_list->whisper_list)) {
1016  int i = 0;
1017  short read_buf[samples], combine_buf[samples], *data1 = NULL, *data2 = NULL;
1018  memset(&combine_buf, 0, sizeof(combine_buf));
1019  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->whisper_list, audiohook, list) {
1020  struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
1021  ast_audiohook_lock(audiohook);
1022  if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
1024  removed = 1;
1026  ast_audiohook_unlock(audiohook);
1027  if (ast_channel_is_bridged(chan)) {
1029  }
1030  continue;
1031  }
1032  audiohook_list_set_hook_rate(audiohook_list, audiohook, &internal_sample_rate);
1033  if (ast_slinfactory_available(factory) >= samples && ast_slinfactory_read(factory, read_buf, samples)) {
1034  /* Take audio from this whisper source and combine it into our main buffer */
1035  for (i = 0, data1 = combine_buf, data2 = read_buf; i < samples; i++, data1++, data2++) {
1036  ast_slinear_saturated_add(data1, data2);
1037  }
1038  }
1039  ast_audiohook_unlock(audiohook);
1040  }
1042  /* We take all of the combined whisper sources and combine them into the audio being written out */
1043  for (i = 0, data1 = middle_frame->data.ptr, data2 = combine_buf; i < samples; i++, data1++, data2++) {
1044  ast_slinear_saturated_add(data1, data2);
1045  }
1046  middle_frame_manipulated = 1;
1047  }
1048 
1049  /* Pass off frame to manipulate audiohooks */
1050  if (!AST_LIST_EMPTY(&audiohook_list->manipulate_list)) {
1051  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
1052  ast_audiohook_lock(audiohook);
1053  if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
1055  removed = 1;
1057  ast_audiohook_unlock(audiohook);
1058  /* We basically drop all of our links to the manipulate audiohook and prod it to do it's own destructive things */
1059  audiohook->manipulate_callback(audiohook, chan, NULL, direction);
1060  if (ast_channel_is_bridged(chan)) {
1062  }
1063  continue;
1064  }
1065  audiohook_list_set_hook_rate(audiohook_list, audiohook, &internal_sample_rate);
1066  /*
1067  * Feed in frame to manipulation.
1068  */
1069  if (!audiohook->manipulate_callback(audiohook, chan, middle_frame, direction)) {
1070  /*
1071  * XXX FAILURES ARE IGNORED XXX
1072  * If the manipulation fails then the frame will be returned in its original state.
1073  * Since there are potentially more manipulator callbacks in the list, no action should
1074  * be taken here to exit early.
1075  */
1076  middle_frame_manipulated = 1;
1077  }
1078  ast_audiohook_unlock(audiohook);
1079  }
1081  }
1082 
1083  /* ---Part_3: Decide what to do with the end_frame (whether to transcode or not) */
1084  if (middle_frame_manipulated) {
1085  if (!(end_frame = audiohook_list_translate_to_native(audiohook_list, direction, middle_frame, start_frame->subclass.format))) {
1086  /* translation failed, so just pass back the input frame */
1087  end_frame = start_frame;
1088  }
1089  } else {
1090  end_frame = start_frame;
1091  }
1092  /* clean up our middle_frame if required */
1093  if (middle_frame != end_frame) {
1094  ast_frfree(middle_frame);
1095  middle_frame = NULL;
1096  }
1097 
1098  /* Before returning, if an audiohook got removed, reset samplerate compatibility */
1099  if (removed) {
1101  } else {
1102  /*
1103  * Set the audiohook_list's rate to the updated rate. Note that if a hook
1104  * was removed then the list's internal rate is reset to the default.
1105  */
1106  audiohook_list->list_internal_samp_rate = internal_sample_rate;
1107  }
1108 
1109  return end_frame;
1110 }
struct ast_slinfactory write_factory
Definition: audiohook.h:112
struct ast_audiohook_list::@344 manipulate_list
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&#39;s status.
Definition: audiohook.c:565
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:170
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
struct ast_audiohook_list::@342 spy_list
#define NULL
Definition: resample.c:96
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
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:117
struct ast_audiohook::@225 list
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
Definition: audiohook.h:300
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
static force_inline void ast_slinear_saturated_add(short *input, short *value)
Definition: utils.h:425
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&#39;s internal sample rate to the audiohook_list&#39;s rate, but only when native slin comp...
Definition: audiohook.c:910
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10746
struct ast_slinfactory read_factory
Definition: audiohook.h:111
#define ast_frfree(fr)
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:107
struct ast_audiohook_list::@343 whisper_list
static struct ast_frame * audiohook_list_translate_to_native(struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *slin_frame, struct ast_format *outformat)
Definition: audiohook.c:878
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
struct ast_format * format
static struct ast_frame * audiohook_list_translate_to_slin(struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame)
Definition: audiohook.c:832
direction
#define ast_audiohook_lock(ah)
Lock an audiohook.
Definition: audiohook.h:295
static void audiohook_list_set_samplerate_compatibility(struct ast_audiohook_list *audiohook_list)
Definition: audiohook.c:468

◆ audiohook_list_set_hook_rate()

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 910 of file audiohook.c.

References AST_AUDIOHOOK_COMPATIBLE, ast_clear_flag, ast_set_flag, audiohook_set_internal_rate(), ast_audiohook::hook_internal_samp_rate, ast_audiohook_list::list_internal_samp_rate, and ast_audiohook_list::native_slin_compatible.

Referenced by audio_audiohook_write_list().

912 {
913  /* The rate should always be the max between itself and the hook */
914  if (audiohook->hook_internal_samp_rate > *rate) {
915  *rate = audiohook->hook_internal_samp_rate;
916  }
917 
918  /*
919  * If native slin compatibility is turned on then update the audiohook
920  * with the audiohook_list's current rate. Note, the audiohook's rate is
921  * set to the audiohook_list's rate and not the given rate. If there is
922  * a change in rate the hook's rate is changed on its next check.
923  */
924  if (audiohook_list->native_slin_compatible) {
926  audiohook_set_internal_rate(audiohook, audiohook_list->list_internal_samp_rate, 1);
927  } else {
929  }
930 }
int list_internal_samp_rate
Definition: audiohook.c:61
#define ast_set_flag(p, flag)
Definition: utils.h:70
int native_slin_compatible
Definition: audiohook.c:60
static int audiohook_set_internal_rate(struct ast_audiohook *audiohook, int rate, int reset)
Definition: audiohook.c:70
unsigned int hook_internal_samp_rate
Definition: audiohook.h:119
#define ast_clear_flag(p, flag)
Definition: utils.h:77

◆ audiohook_list_set_samplerate_compatibility()

static void audiohook_list_set_samplerate_compatibility ( struct ast_audiohook_list audiohook_list)
static

Definition at line 468 of file audiohook.c.

References AST_AUDIOHOOK_MANIPULATE_ALL_RATES, AST_LIST_TRAVERSE, DEFAULT_INTERNAL_SAMPLE_RATE, ast_audiohook::init_flags, ast_audiohook::list, ast_audiohook_list::list_internal_samp_rate, ast_audiohook_list::manipulate_list, ast_audiohook_list::native_slin_compatible, and NULL.

Referenced by ast_audiohook_attach(), ast_audiohook_remove(), audio_audiohook_write_list(), and dtmf_audiohook_write_list().

469 {
470  struct ast_audiohook *ah = NULL;
471 
472  /*
473  * Anytime the samplerate compatibility is set (attach/remove an audiohook) the
474  * list's internal sample rate needs to be reset so that the next time processing
475  * through write_list, if needed, it will get updated to the correct rate.
476  *
477  * A list's internal rate always chooses the higher between its own rate and a
478  * given rate. If the current rate is being driven by an audiohook that wanted a
479  * higher rate then when this audiohook is removed the list's rate would remain
480  * at that level when it should be lower, and with no way to lower it since any
481  * rate compared against it would be lower.
482  *
483  * By setting it back to the lowest rate it can recalulate the new highest rate.
484  */
486 
487  audiohook_list->native_slin_compatible = 1;
488  AST_LIST_TRAVERSE(&audiohook_list->manipulate_list, ah, list) {
490  audiohook_list->native_slin_compatible = 0;
491  return;
492  }
493  }
494 }
struct ast_audiohook_list::@344 manipulate_list
int list_internal_samp_rate
Definition: audiohook.c:61
int native_slin_compatible
Definition: audiohook.c:60
#define NULL
Definition: resample.c:96
struct ast_audiohook::@225 list
enum ast_audiohook_init_flags init_flags
Definition: audiohook.h:108
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define DEFAULT_INTERNAL_SAMPLE_RATE
Definition: audiohook.c:48

◆ audiohook_list_translate_to_native()

static struct ast_frame* audiohook_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

Definition at line 878 of file audiohook.c.

References ao2_replace, AST_AUDIOHOOK_DIRECTION_READ, ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_audiohook_translate::format, ast_frame_subclass::format, NULL, ast_audiohook_list::out_translate, ast_frame::subclass, and ast_audiohook_translate::trans_pvt.

Referenced by audio_audiohook_write_list().

880 {
881  struct ast_audiohook_translate *out_translate = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook_list->out_translate[0] : &audiohook_list->out_translate[1]);
882  struct ast_frame *outframe = NULL;
883  if (ast_format_cmp(slin_frame->subclass.format, outformat) == AST_FORMAT_CMP_NOT_EQUAL) {
884  /* rebuild translators if necessary */
885  if (ast_format_cmp(out_translate->format, outformat) == AST_FORMAT_CMP_NOT_EQUAL) {
886  if (out_translate->trans_pvt) {
887  ast_translator_free_path(out_translate->trans_pvt);
888  }
889  if (!(out_translate->trans_pvt = ast_translator_build_path(outformat, slin_frame->subclass.format))) {
890  return NULL;
891  }
892  ao2_replace(out_translate->format, outformat);
893  }
894  /* translate back to the format the frame came in as. */
895  if (!(outframe = ast_translate(out_translate->trans_pvt, slin_frame, 0))) {
896  return NULL;
897  }
898  }
899  return outframe;
900 }
struct ast_format * format
Definition: audiohook.c:52
struct ast_audiohook_translate out_translate[2]
Definition: audiohook.c:64
struct ast_trans_pvt * trans_pvt
Definition: audiohook.c:51
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:565
#define NULL
Definition: resample.c:96
struct ast_frame_subclass subclass
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
struct ast_trans_pvt * ast_translator_build_path(struct ast_format *dest, struct ast_format *source)
Builds a translator path Build a path (possibly NULL) from source to dest.
Definition: translate.c:485
#define ao2_replace(dst, src)
Definition: astobj2.h:517
Data structure associated with a single frame of data.
struct ast_format * format
direction
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:475

◆ audiohook_list_translate_to_slin()

static struct ast_frame* audiohook_list_translate_to_slin ( struct ast_audiohook_list audiohook_list,
enum ast_audiohook_direction  direction,
struct ast_frame frame 
)
static

Definition at line 832 of file audiohook.c.

References ao2_replace, AST_AUDIOHOOK_DIRECTION_READ, ast_format_cache_get_slin_by_rate(), ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_get_sample_rate(), ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_audiohook_translate::format, ast_frame_subclass::format, ast_audiohook_list::in_translate, ast_audiohook_list::list_internal_samp_rate, MAX, NULL, ast_frame::subclass, and ast_audiohook_translate::trans_pvt.

Referenced by audio_audiohook_write_list().

834 {
836  &audiohook_list->in_translate[0] : &audiohook_list->in_translate[1]);
837  struct ast_frame *new_frame = frame;
838  struct ast_format *slin;
839 
840  /*
841  * If we are capable of sample rates other that 8khz, update the internal
842  * audiohook_list's rate and higher sample rate audio arrives. If native
843  * slin compatibility is turned on all audiohooks in the list will be
844  * updated as well during read/write processing.
845  */
846  audiohook_list->list_internal_samp_rate =
848 
850  if (ast_format_cmp(frame->subclass.format, slin) == AST_FORMAT_CMP_EQUAL) {
851  return new_frame;
852  }
853 
854  if (!in_translate->format ||
855  ast_format_cmp(frame->subclass.format, in_translate->format) != AST_FORMAT_CMP_EQUAL) {
856  struct ast_trans_pvt *new_trans;
857 
858  new_trans = ast_translator_build_path(slin, frame->subclass.format);
859  if (!new_trans) {
860  return NULL;
861  }
862 
863  if (in_translate->trans_pvt) {
864  ast_translator_free_path(in_translate->trans_pvt);
865  }
866  in_translate->trans_pvt = new_trans;
867 
868  ao2_replace(in_translate->format, frame->subclass.format);
869  }
870 
871  if (!(new_frame = ast_translate(in_translate->trans_pvt, frame, 0))) {
872  return NULL;
873  }
874 
875  return new_frame;
876 }
struct ast_format * format
Definition: audiohook.c:52
int list_internal_samp_rate
Definition: audiohook.c:61
Definition of a media format.
Definition: format.c:43
struct ast_trans_pvt * trans_pvt
Definition: audiohook.c:51
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:565
#define NULL
Definition: resample.c:96
struct ast_frame_subclass subclass
#define MAX(a, b)
Definition: utils.h:228
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
struct ast_trans_pvt * ast_translator_build_path(struct ast_format *dest, struct ast_format *source)
Builds a translator path Build a path (possibly NULL) from source to dest.
Definition: translate.c:485
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:213
struct ast_audiohook_translate in_translate[2]
Definition: audiohook.c:63
#define ao2_replace(dst, src)
Definition: astobj2.h:517
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
Data structure associated with a single frame of data.
struct ast_format * format
direction
struct ast_format * ast_format_cache_get_slin_by_rate(unsigned int rate)
Retrieve the best signed linear format given a sample rate.
Definition: format_cache.c:520
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:475

◆ audiohook_move()

static void audiohook_move ( struct ast_channel old_chan,
struct ast_channel new_chan,
struct ast_audiohook audiohook 
)
static

Definition at line 665 of file audiohook.c.

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

Referenced by ast_audiohook_move_all(), and ast_audiohook_move_by_source().

666 {
667  enum ast_audiohook_status oldstatus;
668 
669  /* By locking both channels and the audiohook, we can assure that
670  * another thread will not have a chance to read the audiohook's status
671  * as done, even though ast_audiohook_remove signals the trigger
672  * condition.
673  */
674  ast_audiohook_lock(audiohook);
675  oldstatus = audiohook->status;
676 
677  ast_audiohook_remove(old_chan, audiohook);
678  ast_audiohook_attach(new_chan, audiohook);
679 
680  audiohook->status = oldstatus;
681  ast_audiohook_unlock(audiohook);
682 }
int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook)
Attach audiohook to channel.
Definition: audiohook.c:501
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
Definition: audiohook.h:300
enum ast_audiohook_status status
Definition: audiohook.h:107
ast_audiohook_status
Definition: audiohook.h:41
#define ast_audiohook_lock(ah)
Lock an audiohook.
Definition: audiohook.h:295
int ast_audiohook_remove(struct ast_channel *chan, struct ast_audiohook *audiohook)
Remove an audiohook from a specified channel.
Definition: audiohook.c:764

◆ audiohook_read_frame_both()

static struct ast_frame* audiohook_read_frame_both ( struct ast_audiohook audiohook,
size_t  samples,
struct ast_frame **  read_reference,
struct ast_frame **  write_reference 
)
static

Definition at line 253 of file audiohook.c.

References abs, AST_AUDIOHOOK_MUTE_READ, AST_AUDIOHOOK_MUTE_WRITE, AST_AUDIOHOOK_SUBSTITUTE_SILENCE, ast_debug, ast_format_cache_get_slin_by_rate(), AST_FRAME_VOICE, ast_frdup, ast_slinear_saturated_add(), ast_slinear_saturated_divide(), ast_slinear_saturated_multiply(), ast_slinfactory_available(), ast_slinfactory_read(), ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), buf1, buf2, ast_frame::data, ast_frame_subclass::format, ast_frame::frametype, ast_audiohook::hook_internal_samp_rate, NULL, ast_audiohook::options, ast_frame::ptr, ast_audiohook::read_factory, ast_audiohook::read_time, ast_audiohook_options::read_volume, ast_frame::samples, ast_frame::subclass, write_buf(), ast_audiohook::write_factory, ast_audiohook::write_time, and ast_audiohook_options::write_volume.

Referenced by audiohook_read_frame_helper().

254 {
255  int count;
256  int usable_read;
257  int usable_write;
258  short adjust_value;
259  short buf1[samples];
260  short buf2[samples];
261  short *read_buf = NULL;
262  short *write_buf = NULL;
263  struct ast_frame frame = {
265  .datalen = sizeof(buf1),
266  .samples = samples,
267  };
268 
269  /* Make sure both factories have the required samples */
270  usable_read = (ast_slinfactory_available(&audiohook->read_factory) >= samples ? 1 : 0);
271  usable_write = (ast_slinfactory_available(&audiohook->write_factory) >= samples ? 1 : 0);
272 
273  if (!usable_read && !usable_write) {
274  /* If both factories are unusable bail out */
275  ast_debug(1, "Read factory %p and write factory %p both fail to provide %zu samples\n", &audiohook->read_factory, &audiohook->write_factory, samples);
276  return NULL;
277  }
278 
279  /* If we want to provide only a read factory make sure we aren't waiting for other audio */
280  if (usable_read && !usable_write && (ast_tvdiff_ms(ast_tvnow(), audiohook->write_time) < (samples/8)*2)) {
281  ast_debug(3, "Write factory %p was pretty quick last time, waiting for them.\n", &audiohook->write_factory);
282  return NULL;
283  }
284 
285  /* If we want to provide only a write factory make sure we aren't waiting for other audio */
286  if (usable_write && !usable_read && (ast_tvdiff_ms(ast_tvnow(), audiohook->read_time) < (samples/8)*2)) {
287  ast_debug(3, "Read factory %p was pretty quick last time, waiting for them.\n", &audiohook->read_factory);
288  return NULL;
289  }
290 
291  /* Start with the read factory... if there are enough samples, read them in */
292  if (usable_read) {
293  if (ast_slinfactory_read(&audiohook->read_factory, buf1, samples)) {
294  read_buf = buf1;
295 
296  if ((ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_READ))) {
297  /* Clear the frame data if we are muting */
298  memset(buf1, 0, sizeof(buf1));
299  } else if (audiohook->options.read_volume) {
300  /* Adjust read volume if need be */
301  adjust_value = abs(audiohook->options.read_volume);
302  for (count = 0; count < samples; count++) {
303  if (audiohook->options.read_volume > 0) {
304  ast_slinear_saturated_multiply(&buf1[count], &adjust_value);
305  } else if (audiohook->options.read_volume < 0) {
306  ast_slinear_saturated_divide(&buf1[count], &adjust_value);
307  }
308  }
309  }
310  }
311  } else {
312  ast_debug(1, "Failed to get %d samples from read factory %p\n", (int)samples, &audiohook->read_factory);
313  }
314 
315  /* Move on to the write factory... if there are enough samples, read them in */
316  if (usable_write) {
317  if (ast_slinfactory_read(&audiohook->write_factory, buf2, samples)) {
318  write_buf = buf2;
319 
320  if ((ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_WRITE))) {
321  /* Clear the frame data if we are muting */
322  memset(buf2, 0, sizeof(buf2));
323  } else if (audiohook->options.write_volume) {
324  /* Adjust write volume if need be */
325  adjust_value = abs(audiohook->options.write_volume);
326  for (count = 0; count < samples; count++) {
327  if (audiohook->options.write_volume > 0) {
328  ast_slinear_saturated_multiply(&buf2[count], &adjust_value);
329  } else if (audiohook->options.write_volume < 0) {
330  ast_slinear_saturated_divide(&buf2[count], &adjust_value);
331  }
332  }
333  }
334  }
335  } else {
336  ast_debug(1, "Failed to get %d samples from write factory %p\n", (int)samples, &audiohook->write_factory);
337  }
338 
340 
341  /* Should we substitute silence if one side lacks audio? */
343  if (read_reference && !read_buf && write_buf) {
344  read_buf = buf1;
345  memset(buf1, 0, sizeof(buf1));
346  } else if (write_reference && read_buf && !write_buf) {
347  write_buf = buf2;
348  memset(buf2, 0, sizeof(buf2));
349  }
350  }
351 
352  /* Basically we figure out which buffer to use... and if mixing can be done here */
353  if (read_buf && read_reference) {
354  frame.data.ptr = read_buf;
355  *read_reference = ast_frdup(&frame);
356  }
357  if (write_buf && write_reference) {
358  frame.data.ptr = write_buf;
359  *write_reference = ast_frdup(&frame);
360  }
361 
362  /* Make the correct buffer part of the built frame, so it gets duplicated. */
363  if (read_buf) {
364  frame.data.ptr = read_buf;
365  if (write_buf) {
366  for (count = 0; count < samples; count++) {
367  ast_slinear_saturated_add(read_buf++, write_buf++);
368  }
369  }
370  } else if (write_buf) {
371  frame.data.ptr = write_buf;
372  } else {
373  return NULL;
374  }
375 
376  /* Yahoo, a combined copy of the audio! */
377  return ast_frdup(&frame);
378 }
#define ast_frdup(fr)
Copies a frame.
struct ast_slinfactory write_factory
Definition: audiohook.h:112
#define ast_test_flag(p, flag)
Definition: utils.h:63
static struct ast_threadstorage buf2
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define NULL
Definition: resample.c:96
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
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
void write_buf(int file, char *buffer, int num)
Definition: eagi_proxy.c:312
static force_inline void ast_slinear_saturated_add(short *input, short *value)
Definition: utils.h:425
static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
Definition: utils.h:451
unsigned int hook_internal_samp_rate
Definition: audiohook.h:119
static struct ast_threadstorage buf1
static force_inline void ast_slinear_saturated_divide(short *input, short *value)
Definition: utils.h:477
struct ast_slinfactory read_factory
Definition: audiohook.h:111
struct ast_audiohook_options options
Definition: audiohook.h:118
#define abs(x)
Definition: f2c.h:195
struct timeval write_time
Definition: audiohook.h:114
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
union ast_frame::@263 data
enum ast_frame_type frametype
struct ast_format * format
struct timeval read_time
Definition: audiohook.h:113
struct ast_format * ast_format_cache_get_slin_by_rate(unsigned int rate)
Retrieve the best signed linear format given a sample rate.
Definition: format_cache.c:520

◆ audiohook_read_frame_helper()

static struct ast_frame* audiohook_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

Definition at line 380 of file audiohook.c.

References ao2_replace, AST_AUDIOHOOK_COMPATIBLE, AST_AUDIOHOOK_DIRECTION_BOTH, ast_format_cache_get_slin_by_rate(), ast_format_cmp(), AST_FORMAT_CMP_EQUAL, AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_sample_rate(), ast_frfree, ast_test_flag, ast_translate(), ast_translator_build_path(), ast_translator_free_path(), audiohook_read_frame_both(), audiohook_read_frame_single(), audiohook_set_internal_rate(), ast_audiohook::format, ast_audiohook::hook_internal_samp_rate, NULL, read_frame(), and ast_audiohook::trans_pvt.

Referenced by ast_audiohook_read_frame(), and ast_audiohook_read_frame_all().

381 {
382  struct ast_frame *read_frame = NULL, *final_frame = NULL;
383  struct ast_format *slin;
384 
385  /*
386  * Update the rate if compatibility mode is turned off or if it is
387  * turned on and the format rate is higher than the current rate.
388  *
389  * This makes it so any unnecessary rate switching/resetting does
390  * not take place and also any associated audiohook_list's internal
391  * sample rate maintains the highest sample rate between hooks.
392  */
393  if (!ast_test_flag(audiohook, AST_AUDIOHOOK_COMPATIBLE) ||
395  ast_format_get_sample_rate(format) > audiohook->hook_internal_samp_rate)) {
397  }
398 
399  /* If the sample rate of the requested format differs from that of the underlying audiohook
400  * sample rate determine how many samples we actually need to get from the audiohook. This
401  * needs to occur as the signed linear factory stores them at the rate of the audiohook.
402  * We do this by determining the duration of audio they've requested and then determining
403  * how many samples that would be in the audiohook format.
404  */
405  if (ast_format_get_sample_rate(format) != audiohook->hook_internal_samp_rate) {
406  samples = (audiohook->hook_internal_samp_rate / 1000) * (samples / (ast_format_get_sample_rate(format) / 1000));
407  }
408 
409  if (!(read_frame = (direction == AST_AUDIOHOOK_DIRECTION_BOTH ?
410  audiohook_read_frame_both(audiohook, samples, read_reference, write_reference) :
411  audiohook_read_frame_single(audiohook, samples, direction)))) {
412  return NULL;
413  }
414 
416 
417  /* If they don't want signed linear back out, we'll have to send it through the translation path */
418  if (ast_format_cmp(format, slin) != AST_FORMAT_CMP_EQUAL) {
419  /* Rebuild translation path if different format then previously */
420  if (ast_format_cmp(format, audiohook->format) == AST_FORMAT_CMP_NOT_EQUAL) {
421  if (audiohook->trans_pvt) {
423  audiohook->trans_pvt = NULL;
424  }
425 
426  /* 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 */
427  if (!(audiohook->trans_pvt = ast_translator_build_path(format, slin))) {
428  ast_frfree(read_frame);
429  return NULL;
430  }
431  ao2_replace(audiohook->format, format);
432  }
433  /* Convert to requested format, and allow the read in frame to be freed */
434  final_frame = ast_translate(audiohook->trans_pvt, read_frame, 1);
435  } else {
436  final_frame = read_frame;
437  }
438 
439  return final_frame;
440 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
Definition of a media format.
Definition: format.c:43
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:565
static int audiohook_set_internal_rate(struct ast_audiohook *audiohook, int rate, int reset)
Definition: audiohook.c:70
#define NULL
Definition: resample.c:96
struct ast_format * format
Definition: audiohook.h:115
static struct ast_frame * audiohook_read_frame_both(struct ast_audiohook *audiohook, size_t samples, struct ast_frame **read_reference, struct ast_frame **write_reference)
Definition: audiohook.c:253
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
struct ast_trans_pvt * ast_translator_build_path(struct ast_format *dest, struct ast_format *source)
Builds a translator path Build a path (possibly NULL) from source to dest.
Definition: translate.c:485
struct ast_trans_pvt * trans_pvt
Definition: audiohook.h:116
unsigned int hook_internal_samp_rate
Definition: audiohook.h:119
static struct ast_frame * read_frame(struct ast_filestream *s, int *whennext)
Definition: file.c:874
#define ao2_replace(dst, src)
Definition: astobj2.h:517
#define ast_frfree(fr)
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
Data structure associated with a single frame of data.
direction
static struct ast_frame * audiohook_read_frame_single(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction)
Definition: audiohook.c:219
struct ast_format * ast_format_cache_get_slin_by_rate(unsigned int rate)
Retrieve the best signed linear format given a sample rate.
Definition: format_cache.c:520
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:475

◆ audiohook_read_frame_single()

static struct ast_frame* audiohook_read_frame_single ( struct ast_audiohook audiohook,
size_t  samples,
enum ast_audiohook_direction  direction 
)
static

Definition at line 219 of file audiohook.c.

References AST_AUDIOHOOK_DIRECTION_READ, ast_format_cache_get_slin_by_rate(), ast_frame_adjust_volume(), ast_frame_clear(), AST_FRAME_VOICE, ast_frdup, ast_slinfactory_available(), ast_slinfactory_read(), buf, ast_frame::frametype, ast_audiohook::hook_internal_samp_rate, NULL, ast_audiohook::options, ast_audiohook::read_factory, ast_audiohook_options::read_volume, SHOULD_MUTE, ast_audiohook::write_factory, and ast_audiohook_options::write_volume.

Referenced by audiohook_read_frame_helper().

220 {
221  struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
222  int vol = (direction == AST_AUDIOHOOK_DIRECTION_READ ? audiohook->options.read_volume : audiohook->options.write_volume);
223  short buf[samples];
224  struct ast_frame frame = {
226  .subclass.format = ast_format_cache_get_slin_by_rate(audiohook->hook_internal_samp_rate),
227  .data.ptr = buf,
228  .datalen = sizeof(buf),
229  .samples = samples,
230  };
231 
232  /* Ensure the factory is able to give us the samples we want */
233  if (samples > ast_slinfactory_available(factory)) {
234  return NULL;
235  }
236 
237  /* Read data in from factory */
238  if (!ast_slinfactory_read(factory, buf, samples)) {
239  return NULL;
240  }
241 
242  if (SHOULD_MUTE(audiohook, direction)) {
243  /* Swap frame data for zeros if mute is required */
244  ast_frame_clear(&frame);
245  } else if (vol) {
246  /* If a volume adjustment needs to be applied apply it */
247  ast_frame_adjust_volume(&frame, vol);
248  }
249 
250  return ast_frdup(&frame);
251 }
#define ast_frdup(fr)
Copies a frame.
struct ast_slinfactory write_factory
Definition: audiohook.h:112
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define NULL
Definition: resample.c:96
unsigned int ast_slinfactory_available(const struct ast_slinfactory *sf)
Retrieve number of samples currently in a slinfactory.
Definition: slinfactory.c:199
#define SHOULD_MUTE(hook, dir)
Definition: audiohook.c:159
unsigned int hook_internal_samp_rate
Definition: audiohook.h:119
struct ast_slinfactory read_factory
Definition: audiohook.h:111
struct ast_audiohook_options options
Definition: audiohook.h:118
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: main/frame.c:859
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_frame_type frametype
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
direction
struct ast_format * ast_format_cache_get_slin_by_rate(unsigned int rate)
Retrieve the best signed linear format given a sample rate.
Definition: format_cache.c:520

◆ audiohook_set_internal_rate()

static int audiohook_set_internal_rate ( struct ast_audiohook audiohook,
int  rate,
int  reset 
)
static

Definition at line 70 of file audiohook.c.

References AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_format_cache_get_slin_by_rate(), ast_slinfactory_destroy(), ast_slinfactory_init_with_format(), ast_audiohook::hook_internal_samp_rate, ast_audiohook::read_factory, ast_audiohook::type, and ast_audiohook::write_factory.

Referenced by ast_audiohook_attach(), ast_audiohook_init(), audiohook_list_set_hook_rate(), and audiohook_read_frame_helper().

71 {
72  struct ast_format *slin;
73 
74  if (audiohook->hook_internal_samp_rate == rate) {
75  return 0;
76  }
77 
78  audiohook->hook_internal_samp_rate = rate;
79 
81 
82  /* Setup the factories that are needed for this audiohook type */
83  switch (audiohook->type) {
86  if (reset) {
89  }
92  break;
93  default:
94  break;
95  }
96 
97  return 0;
98 }
struct ast_slinfactory write_factory
Definition: audiohook.h:112
enum ast_audiohook_type type
Definition: audiohook.h:106
Definition of a media format.
Definition: format.c:43
void ast_slinfactory_destroy(struct ast_slinfactory *sf)
Destroy the contents of a slinfactory.
Definition: slinfactory.c:58
unsigned int hook_internal_samp_rate
Definition: audiohook.h:119
int ast_slinfactory_init_with_format(struct ast_slinfactory *sf, struct ast_format *slin_out)
Initialize a slinfactory.
Definition: slinfactory.c:46
struct ast_slinfactory read_factory
Definition: audiohook.h:111
struct ast_format * ast_format_cache_get_slin_by_rate(unsigned int rate)
Retrieve the best signed linear format given a sample rate.
Definition: format_cache.c:520

◆ audiohook_volume_callback()

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 1267 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, NULL, audiohook_volume::read_adjustment, ast_audiohook::status, and audiohook_volume::write_adjustment.

Referenced by audiohook_volume_get().

1268 {
1269  struct ast_datastore *datastore = NULL;
1271  int *gain = NULL;
1272 
1273  /* If the audiohook is shutting down don't even bother */
1274  if (audiohook->status == AST_AUDIOHOOK_STATUS_DONE) {
1275  return 0;
1276  }
1277 
1278  /* Try to find the datastore containg adjustment information, if we can't just bail out */
1279  if (!(datastore = ast_channel_datastore_find(chan, &audiohook_volume_datastore, NULL))) {
1280  return 0;
1281  }
1282 
1283  audiohook_volume = datastore->data;
1284 
1285  /* Based on direction grab the appropriate adjustment value */
1287  gain = &audiohook_volume->read_adjustment;
1288  } else if (direction == AST_AUDIOHOOK_DIRECTION_WRITE) {
1289  gain = &audiohook_volume->write_adjustment;
1290  }
1291 
1292  /* If an adjustment value is present modify the frame */
1293  if (gain && *gain) {
1294  ast_frame_adjust_volume(frame, *gain);
1295  }
1296 
1297  return 0;
1298 }
Audiohook volume adjustment structure.
Definition: audiohook.c:1231
static const struct ast_datastore_info audiohook_volume_datastore
Datastore used to store audiohook volume information.
Definition: audiohook.c:1255
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
void * data
Definition: datastore.h:70
enum ast_audiohook_status status
Definition: audiohook.h:107
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
direction

◆ audiohook_volume_destroy()

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 1241 of file audiohook.c.

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

1242 {
1243  struct audiohook_volume *audiohook_volume = data;
1244 
1245  /* Destroy the audiohook as it is no longer in use */
1246  ast_audiohook_destroy(&audiohook_volume->audiohook);
1247 
1248  /* Finally free ourselves, we are of no more use */
1249  ast_free(audiohook_volume);
1250 
1251  return;
1252 }
struct ast_audiohook audiohook
Definition: audiohook.c:1232
Audiohook volume adjustment structure.
Definition: audiohook.c:1231
int ast_audiohook_destroy(struct ast_audiohook *audiohook)
Destroys an audiohook structure.
Definition: audiohook.c:133
#define ast_free(a)
Definition: astmm.h:182

◆ audiohook_volume_get()

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 1305 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_alloc, ast_datastore_free(), audiohook_volume::audiohook, audiohook_volume_callback(), ast_datastore::data, ast_audiohook::manipulate_callback, and NULL.

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

1306 {
1307  struct ast_datastore *datastore = NULL;
1309 
1310  /* If we are able to find the datastore return the contents (which is actually an audiohook_volume structure) */
1311  if ((datastore = ast_channel_datastore_find(chan, &audiohook_volume_datastore, NULL))) {
1312  return datastore->data;
1313  }
1314 
1315  /* 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 */
1316  if (!create || !(datastore = ast_datastore_alloc(&audiohook_volume_datastore, NULL))) {
1317  return NULL;
1318  }
1319 
1320  /* Create a new audiohook_volume structure to contain our adjustments and audiohook */
1321  if (!(audiohook_volume = ast_calloc(1, sizeof(*audiohook_volume)))) {
1322  ast_datastore_free(datastore);
1323  return NULL;
1324  }
1325 
1326  /* Setup our audiohook structure so we can manipulate the audio */
1329 
1330  /* Attach the audiohook_volume blob to the datastore and attach to the channel */
1331  datastore->data = audiohook_volume;
1332  ast_channel_datastore_add(chan, datastore);
1333 
1334  /* All is well... put the audiohook into motion */
1335  ast_audiohook_attach(chan, &audiohook_volume->audiohook);
1336 
1337  return audiohook_volume;
1338 }
struct ast_audiohook audiohook
Definition: audiohook.c:1232
Audiohook volume adjustment structure.
Definition: audiohook.c:1231
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:108
int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook)
Attach audiohook to channel.
Definition: audiohook.c:501
static const struct ast_datastore_info audiohook_volume_datastore
Datastore used to store audiohook volume information.
Definition: audiohook.c:1255
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
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:117
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void * data
Definition: datastore.h:70
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390
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:1267

◆ dtmf_audiohook_write_list()

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 800 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_test_flag, audiohook_list_set_samplerate_compatibility(), ast_audiohook::list, ast_audiohook::manipulate_callback, ast_audiohook_list::manipulate_list, NULL, and ast_audiohook::status.

Referenced by ast_audiohook_write_list().

801 {
802  struct ast_audiohook *audiohook = NULL;
803  int removed = 0;
804 
805  AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
806  ast_audiohook_lock(audiohook);
807  if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
809  removed = 1;
811  ast_audiohook_unlock(audiohook);
812  audiohook->manipulate_callback(audiohook, NULL, NULL, 0);
813  if (ast_channel_is_bridged(chan)) {
815  }
816  continue;
817  }
818  if (ast_test_flag(audiohook, AST_AUDIOHOOK_WANTS_DTMF)) {
819  audiohook->manipulate_callback(audiohook, chan, frame, direction);
820  }
821  ast_audiohook_unlock(audiohook);
822  }
824 
825  /* if an audiohook got removed, reset samplerate compatibility */
826  if (removed) {
828  }
829  return frame;
830 }
struct ast_audiohook_list::@344 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:565
#define NULL
Definition: resample.c:96
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
ast_audiohook_manipulate_callback manipulate_callback
Definition: audiohook.h:117
struct ast_audiohook::@225 list
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
Definition: audiohook.h:300
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
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:10746
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
direction
#define ast_audiohook_lock(ah)
Lock an audiohook.
Definition: audiohook.h:295
static void audiohook_list_set_samplerate_compatibility(struct ast_audiohook_list *audiohook_list)
Definition: audiohook.c:468

◆ find_audiohook_by_source()

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 640 of file audiohook.c.

References AST_LIST_TRAVERSE, ast_audiohook::list, ast_audiohook_list::manipulate_list, NULL, 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().

641 {
642  struct ast_audiohook *audiohook = NULL;
643 
644  AST_LIST_TRAVERSE(&audiohook_list->spy_list, audiohook, list) {
645  if (!strcasecmp(audiohook->source, source)) {
646  return audiohook;
647  }
648  }
649 
650  AST_LIST_TRAVERSE(&audiohook_list->whisper_list, audiohook, list) {
651  if (!strcasecmp(audiohook->source, source)) {
652  return audiohook;
653  }
654  }
655 
656  AST_LIST_TRAVERSE(&audiohook_list->manipulate_list, audiohook, list) {
657  if (!strcasecmp(audiohook->source, source)) {
658  return audiohook;
659  }
660  }
661 
662  return NULL;
663 }
struct ast_audiohook_list::@344 manipulate_list
struct ast_audiohook_list::@342 spy_list
#define NULL
Definition: resample.c:96
struct ast_audiohook::@225 list
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
const char * source
Definition: audiohook.h:109
struct ast_audiohook_list::@343 whisper_list

Variable Documentation

◆ audiohook_volume_datastore

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

Datastore used to store audiohook volume information.

Definition at line 1255 of file audiohook.c.