#include "asterisk/lock.h"
#include "asterisk/linkedlists.h"
#include "asterisk/frame_defs.h"
#include "asterisk/slinfactory.h"
Go to the source code of this file.
Data Structures | |
struct | ast_audiohook |
struct | ast_audiohook_options |
Defines | |
#define | ast_audiohook_lock(ah) ast_mutex_lock(&(ah)->lock) |
Lock an audiohook. | |
#define | AST_AUDIOHOOK_SYNC_TOLERANCE 100 |
#define | ast_audiohook_unlock(ah) ast_mutex_unlock(&(ah)->lock) |
Unlock an audiohook. | |
Typedefs | |
typedef int(*) | ast_audiohook_manipulate_callback (struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction) |
Callback function for manipulate audiohook type. | |
Enumerations | |
enum | ast_audiohook_direction { AST_AUDIOHOOK_DIRECTION_READ = 0, AST_AUDIOHOOK_DIRECTION_WRITE, AST_AUDIOHOOK_DIRECTION_BOTH } |
enum | ast_audiohook_flags { AST_AUDIOHOOK_TRIGGER_MODE = (3 << 0), AST_AUDIOHOOK_TRIGGER_READ = (1 << 0), AST_AUDIOHOOK_TRIGGER_WRITE = (2 << 0), AST_AUDIOHOOK_WANTS_DTMF = (1 << 1), AST_AUDIOHOOK_TRIGGER_SYNC = (1 << 2), AST_AUDIOHOOK_SMALL_QUEUE = (1 << 3), AST_AUDIOHOOK_MUTE_READ = (1 << 4), AST_AUDIOHOOK_MUTE_WRITE = (1 << 5) } |
enum | ast_audiohook_status { AST_AUDIOHOOK_STATUS_NEW = 0, AST_AUDIOHOOK_STATUS_RUNNING, AST_AUDIOHOOK_STATUS_SHUTDOWN, AST_AUDIOHOOK_STATUS_DONE } |
enum | ast_audiohook_type { AST_AUDIOHOOK_TYPE_SPY = 0, AST_AUDIOHOOK_TYPE_WHISPER, AST_AUDIOHOOK_TYPE_MANIPULATE } |
Functions | |
int | ast_audiohook_attach (struct ast_channel *chan, struct ast_audiohook *audiohook) |
Attach audiohook to channel. | |
int | ast_audiohook_destroy (struct ast_audiohook *audiohook) |
Destroys an audiohook structure. | |
int | ast_audiohook_detach (struct ast_audiohook *audiohook) |
Detach audiohook from channel. | |
int | ast_audiohook_detach_list (struct ast_audiohook_list *audiohook_list) |
Detach audiohooks from list and destroy said list. | |
int | ast_audiohook_detach_source (struct ast_channel *chan, const char *source) |
Detach specified source audiohook from channel. | |
int | ast_audiohook_init (struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source) |
Initialize an audiohook structure. | |
void | ast_audiohook_move_by_source (struct ast_channel *old_chan, struct ast_channel *new_chan, const char *source) |
Move an audiohook from one channel to a new one. | |
ast_frame * | ast_audiohook_read_frame (struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, format_t format) |
Reads a frame in from the audiohook structure. | |
int | ast_audiohook_remove (struct ast_channel *chan, struct ast_audiohook *audiohook) |
Remove an audiohook from a specified channel. | |
int | ast_audiohook_set_mute (struct ast_channel *chan, const char *source, enum ast_audiohook_flags flag, int clear) |
Mute frames read from or written to a channel. | |
void | ast_audiohook_trigger_wait (struct ast_audiohook *audiohook) |
Wait for audiohook trigger to be triggered. | |
void | ast_audiohook_update_status (struct ast_audiohook *audiohook, enum ast_audiohook_status status) |
Update audiohook's status. | |
int | ast_audiohook_volume_adjust (struct ast_channel *chan, enum ast_audiohook_direction direction, int volume) |
Adjust the volume on frames read from or written to a channel. | |
int | ast_audiohook_volume_get (struct ast_channel *chan, enum ast_audiohook_direction direction) |
Retrieve the volume adjustment value on frames read from or written to a channel. | |
int | ast_audiohook_volume_set (struct ast_channel *chan, enum ast_audiohook_direction direction, int volume) |
Adjust the volume on frames read from or written to a channel. | |
int | ast_audiohook_write_frame (struct ast_audiohook *audiohook, enum ast_audiohook_direction direction, struct ast_frame *frame) |
Writes a frame into the audiohook structure. | |
ast_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. | |
int | ast_audiohook_write_list_empty (struct ast_audiohook_list *audiohook_list) |
determines if a audiohook_list is empty or not. | |
int | ast_channel_audiohook_count_by_source (struct ast_channel *chan, const char *source, enum ast_audiohook_type type) |
Find out how many audiohooks from a certain source exist on a given channel, regardless of status. | |
int | ast_channel_audiohook_count_by_source_running (struct ast_channel *chan, const char *source, enum ast_audiohook_type type) |
Find out how many spies of a certain type exist on a given channel, and are in state running. |
Definition in file audiohook.h.
#define ast_audiohook_lock | ( | ah | ) | ast_mutex_lock(&(ah)->lock) |
Lock an audiohook.
ah | Audiohook structure |
Definition at line 260 of file audiohook.h.
Referenced by ast_audiohook_move_by_source(), ast_audiohook_update_status(), audio_audiohook_write_list(), channel_spy(), destroy_monitor_audiohook(), dtmf_audiohook_write_list(), mixmonitor_thread(), spy_generate(), and stop_mixmonitor_exec().
#define AST_AUDIOHOOK_SYNC_TOLERANCE 100 |
#define ast_audiohook_unlock | ( | ah | ) | ast_mutex_unlock(&(ah)->lock) |
Unlock an audiohook.
ah | Audiohook structure |
Definition at line 265 of file audiohook.h.
Referenced by ast_audiohook_move_by_source(), ast_audiohook_update_status(), audio_audiohook_write_list(), channel_spy(), destroy_monitor_audiohook(), dtmf_audiohook_write_list(), mixmonitor_thread(), spy_generate(), and stop_mixmonitor_exec().
typedef int(*) ast_audiohook_manipulate_callback(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction) |
Callback function for manipulate audiohook type.
audiohook | Audiohook structure | |
chan | Channel | |
frame | Frame of audio to manipulate | |
direction | Direction frame came from |
The input frame should never be freed or corrupted during a manipulate callback. If the callback has the potential to corrupt the frame's data during manipulation, local data should be used for the manipulation and only copied to the frame on success.
A failure return value indicates that the frame was not manipulated and that is being returned in its original state.
Definition at line 89 of file audiohook.h.
AST_AUDIOHOOK_DIRECTION_READ | Reading audio in |
AST_AUDIOHOOK_DIRECTION_WRITE | Writing audio out |
AST_AUDIOHOOK_DIRECTION_BOTH | Both reading audio in and writing audio out |
Definition at line 49 of file audiohook.h.
00049 { 00050 AST_AUDIOHOOK_DIRECTION_READ = 0, /*!< Reading audio in */ 00051 AST_AUDIOHOOK_DIRECTION_WRITE, /*!< Writing audio out */ 00052 AST_AUDIOHOOK_DIRECTION_BOTH, /*!< Both reading audio in and writing audio out */ 00053 };
enum ast_audiohook_flags |
Definition at line 55 of file audiohook.h.
00055 { 00056 AST_AUDIOHOOK_TRIGGER_MODE = (3 << 0), /*!< When audiohook should be triggered to do something */ 00057 AST_AUDIOHOOK_TRIGGER_READ = (1 << 0), /*!< Audiohook wants to be triggered when reading audio in */ 00058 AST_AUDIOHOOK_TRIGGER_WRITE = (2 << 0), /*!< Audiohook wants to be triggered when writing audio out */ 00059 AST_AUDIOHOOK_WANTS_DTMF = (1 << 1), /*!< Audiohook also wants to receive DTMF frames */ 00060 AST_AUDIOHOOK_TRIGGER_SYNC = (1 << 2), /*!< Audiohook wants to be triggered when both sides have combined audio available */ 00061 /*! Audiohooks with this flag set will not allow for a large amount of samples to build up on its 00062 * slinfactories. We will flush the factories if they contain too many samples. 00063 */ 00064 AST_AUDIOHOOK_SMALL_QUEUE = (1 << 3), 00065 AST_AUDIOHOOK_MUTE_READ = (1 << 4), /*!< audiohook should be mute frames read */ 00066 AST_AUDIOHOOK_MUTE_WRITE = (1 << 5), /*!< audiohook should be mute frames written */ 00067 };
enum ast_audiohook_status |
Definition at line 42 of file audiohook.h.
00042 { 00043 AST_AUDIOHOOK_STATUS_NEW = 0, /*!< Audiohook was just created, not in use yet */ 00044 AST_AUDIOHOOK_STATUS_RUNNING, /*!< Audiohook is running on a channel */ 00045 AST_AUDIOHOOK_STATUS_SHUTDOWN, /*!< Audiohook is being shutdown */ 00046 AST_AUDIOHOOK_STATUS_DONE, /*!< Audiohook has shutdown and is not running on a channel any longer */ 00047 };
enum ast_audiohook_type |
Definition at line 36 of file audiohook.h.
00036 { 00037 AST_AUDIOHOOK_TYPE_SPY = 0, /*!< Audiohook wants to receive audio */ 00038 AST_AUDIOHOOK_TYPE_WHISPER, /*!< Audiohook wants to provide audio to be mixed with existing audio */ 00039 AST_AUDIOHOOK_TYPE_MANIPULATE, /*!< Audiohook wants to manipulate the audio */ 00040 };
int ast_audiohook_attach | ( | struct ast_channel * | chan, | |
struct ast_audiohook * | audiohook | |||
) |
Attach audiohook to channel.
chan | Channel | |
audiohook | Audiohook structure |
Definition at line 342 of file audiohook.c.
References AST_AUDIOHOOK_STATUS_RUNNING, AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_audiohook_update_status(), ast_calloc, ast_channel_lock, ast_channel_unlock, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_TAIL, ast_channel::audiohooks, ast_audiohook_list::manipulate_list, ast_audiohook_list::spy_list, ast_audiohook::type, and ast_audiohook_list::whisper_list.
Referenced by ast_audiohook_move_by_source(), audiohook_volume_get(), enable_jack_hook(), mute_add_audiohook(), pitchshift_helper(), speex_write(), start_spying(), startmon(), and volume_write().
00343 { 00344 ast_channel_lock(chan); 00345 00346 if (!chan->audiohooks) { 00347 /* Whoops... allocate a new structure */ 00348 if (!(chan->audiohooks = ast_calloc(1, sizeof(*chan->audiohooks)))) { 00349 ast_channel_unlock(chan); 00350 return -1; 00351 } 00352 AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->spy_list); 00353 AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->whisper_list); 00354 AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->manipulate_list); 00355 } 00356 00357 /* Drop into respective list */ 00358 if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY) 00359 AST_LIST_INSERT_TAIL(&chan->audiohooks->spy_list, audiohook, list); 00360 else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER) 00361 AST_LIST_INSERT_TAIL(&chan->audiohooks->whisper_list, audiohook, list); 00362 else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) 00363 AST_LIST_INSERT_TAIL(&chan->audiohooks->manipulate_list, audiohook, list); 00364 00365 /* Change status over to running since it is now attached */ 00366 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_RUNNING); 00367 00368 ast_channel_unlock(chan); 00369 00370 return 0; 00371 }
int ast_audiohook_destroy | ( | struct ast_audiohook * | audiohook | ) |
Destroys an audiohook structure.
audiohook | Audiohook structure |
Definition at line 91 of file audiohook.c.
References AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_cond_destroy, ast_mutex_destroy, ast_slinfactory_destroy(), ast_translator_free_path(), ast_audiohook::lock, ast_audiohook::read_factory, ast_audiohook::trans_pvt, ast_audiohook::trigger, ast_audiohook::type, and ast_audiohook::write_factory.
Referenced by audiohook_volume_destroy(), channel_spy(), destroy_callback(), destroy_jack_data(), destroy_monitor_audiohook(), and launch_monitor_thread().
00092 { 00093 /* Drop the factories used by this audiohook type */ 00094 switch (audiohook->type) { 00095 case AST_AUDIOHOOK_TYPE_SPY: 00096 ast_slinfactory_destroy(&audiohook->read_factory); 00097 case AST_AUDIOHOOK_TYPE_WHISPER: 00098 ast_slinfactory_destroy(&audiohook->write_factory); 00099 break; 00100 default: 00101 break; 00102 } 00103 00104 /* Destroy translation path if present */ 00105 if (audiohook->trans_pvt) 00106 ast_translator_free_path(audiohook->trans_pvt); 00107 00108 /* Lock and trigger be gone! */ 00109 ast_cond_destroy(&audiohook->trigger); 00110 ast_mutex_destroy(&audiohook->lock); 00111 00112 return 0; 00113 }
int ast_audiohook_detach | ( | struct ast_audiohook * | audiohook | ) |
Detach audiohook from channel.
audiohook | Audiohook structure |
Definition at line 395 of file audiohook.c.
References AST_AUDIOHOOK_STATUS_DONE, AST_AUDIOHOOK_STATUS_NEW, AST_AUDIOHOOK_STATUS_SHUTDOWN, ast_audiohook_trigger_wait(), ast_audiohook_update_status(), and ast_audiohook::status.
Referenced by channel_spy(), destroy_monitor_audiohook(), disable_jack_hook(), and speex_write().
00396 { 00397 if (audiohook->status == AST_AUDIOHOOK_STATUS_NEW || audiohook->status == AST_AUDIOHOOK_STATUS_DONE) 00398 return 0; 00399 00400 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_SHUTDOWN); 00401 00402 while (audiohook->status != AST_AUDIOHOOK_STATUS_DONE) 00403 ast_audiohook_trigger_wait(audiohook); 00404 00405 return 0; 00406 }
int ast_audiohook_detach_list | ( | struct ast_audiohook_list * | audiohook_list | ) |
Detach audiohooks from list and destroy said list.
audiohook_list | List of audiohooks |
Definition at line 412 of file audiohook.c.
References AST_AUDIOHOOK_STATUS_DONE, ast_audiohook_update_status(), ast_free, AST_LIST_REMOVE_HEAD, ast_translator_free_path(), ast_audiohook_list::in_translate, ast_audiohook::list, ast_audiohook_list::manipulate_list, ast_audiohook_list::out_translate, ast_audiohook_list::spy_list, ast_audiohook_translate::trans_pvt, and ast_audiohook_list::whisper_list.
Referenced by __ast_read(), ast_hangup(), and ast_write().
00413 { 00414 int i = 0; 00415 struct ast_audiohook *audiohook = NULL; 00416 00417 /* Drop any spies */ 00418 while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->spy_list, list))) { 00419 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE); 00420 } 00421 00422 /* Drop any whispering sources */ 00423 while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->whisper_list, list))) { 00424 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE); 00425 } 00426 00427 /* Drop any manipulaters */ 00428 while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->manipulate_list, list))) { 00429 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE); 00430 audiohook->manipulate_callback(audiohook, NULL, NULL, 0); 00431 } 00432 00433 /* Drop translation paths if present */ 00434 for (i = 0; i < 2; i++) { 00435 if (audiohook_list->in_translate[i].trans_pvt) 00436 ast_translator_free_path(audiohook_list->in_translate[i].trans_pvt); 00437 if (audiohook_list->out_translate[i].trans_pvt) 00438 ast_translator_free_path(audiohook_list->out_translate[i].trans_pvt); 00439 } 00440 00441 /* Free ourselves */ 00442 ast_free(audiohook_list); 00443 00444 return 0; 00445 }
int ast_audiohook_detach_source | ( | struct ast_channel * | chan, | |
const char * | source | |||
) |
Detach specified source audiohook from channel.
chan | Channel to detach from | |
source | Name of source to detach |
Definition at line 503 of file audiohook.c.
References AST_AUDIOHOOK_STATUS_DONE, AST_AUDIOHOOK_STATUS_SHUTDOWN, ast_audiohook_update_status(), ast_channel_lock, ast_channel_unlock, ast_channel::audiohooks, find_audiohook_by_source(), and ast_audiohook::status.
Referenced by handle_cli_mixmonitor(), and stop_mixmonitor_exec().
00504 { 00505 struct ast_audiohook *audiohook = NULL; 00506 00507 ast_channel_lock(chan); 00508 00509 /* Ensure the channel has audiohooks on it */ 00510 if (!chan->audiohooks) { 00511 ast_channel_unlock(chan); 00512 return -1; 00513 } 00514 00515 audiohook = find_audiohook_by_source(chan->audiohooks, source); 00516 00517 ast_channel_unlock(chan); 00518 00519 if (audiohook && audiohook->status != AST_AUDIOHOOK_STATUS_DONE) 00520 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_SHUTDOWN); 00521 00522 return (audiohook ? 0 : -1); 00523 }
int ast_audiohook_init | ( | struct ast_audiohook * | audiohook, | |
enum ast_audiohook_type | type, | |||
const char * | source | |||
) |
Initialize an audiohook structure.
audiohook | Audiohook structure | |
type | ||
source |
Definition at line 60 of file audiohook.c.
References AST_AUDIOHOOK_STATUS_NEW, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_audiohook_update_status(), ast_cond_init, ast_mutex_init, and ast_slinfactory_init().
Referenced by audiohook_volume_get(), channel_spy(), enable_jack_hook(), initialize_mutehook(), launch_monitor_thread(), pitchshift_helper(), speex_write(), and volume_write().
00061 { 00062 /* Need to keep the type and source */ 00063 audiohook->type = type; 00064 audiohook->source = source; 00065 00066 /* Initialize lock that protects our audiohook */ 00067 ast_mutex_init(&audiohook->lock); 00068 ast_cond_init(&audiohook->trigger, NULL); 00069 00070 /* Setup the factories that are needed for this audiohook type */ 00071 switch (type) { 00072 case AST_AUDIOHOOK_TYPE_SPY: 00073 ast_slinfactory_init(&audiohook->read_factory); 00074 case AST_AUDIOHOOK_TYPE_WHISPER: 00075 ast_slinfactory_init(&audiohook->write_factory); 00076 break; 00077 default: 00078 break; 00079 } 00080 00081 /* Since we are just starting out... this audiohook is new */ 00082 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_NEW); 00083 00084 return 0; 00085 }
void ast_audiohook_move_by_source | ( | struct ast_channel * | old_chan, | |
struct ast_channel * | new_chan, | |||
const char * | source | |||
) |
Move an audiohook from one channel to a new one.
old_chan | The source of the audiohook to move | |
new_chan | The destination to which we want the audiohook to move | |
source | The source of the audiohook we want to move |
Definition at line 474 of file audiohook.c.
References ast_audiohook_attach(), ast_audiohook_lock, ast_audiohook_remove(), ast_audiohook_unlock, ast_channel::audiohooks, find_audiohook_by_source(), and ast_audiohook::status.
Referenced by audiohook_inheritance_fixup().
00475 { 00476 struct ast_audiohook *audiohook; 00477 enum ast_audiohook_status oldstatus; 00478 00479 if (!old_chan->audiohooks || !(audiohook = find_audiohook_by_source(old_chan->audiohooks, source))) { 00480 return; 00481 } 00482 00483 /* By locking both channels and the audiohook, we can assure that 00484 * another thread will not have a chance to read the audiohook's status 00485 * as done, even though ast_audiohook_remove signals the trigger 00486 * condition. 00487 */ 00488 ast_audiohook_lock(audiohook); 00489 oldstatus = audiohook->status; 00490 00491 ast_audiohook_remove(old_chan, audiohook); 00492 ast_audiohook_attach(new_chan, audiohook); 00493 00494 audiohook->status = oldstatus; 00495 ast_audiohook_unlock(audiohook); 00496 }
struct ast_frame* ast_audiohook_read_frame | ( | struct ast_audiohook * | audiohook, | |
size_t | samples, | |||
enum ast_audiohook_direction | direction, | |||
format_t | format | |||
) |
Reads a frame in from the audiohook structure.
audiohook | Audiohook structure | |
samples | Number of samples wanted | |
direction | Direction the audio frame came from | |
format | Format of frame remote side wants back |
Definition at line 307 of file audiohook.c.
References AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR, ast_frfree, ast_translate(), ast_translator_build_path(), ast_translator_free_path(), audiohook_read_frame_both(), audiohook_read_frame_single(), and read_frame().
Referenced by mixmonitor_thread(), and spy_generate().
00308 { 00309 struct ast_frame *read_frame = NULL, *final_frame = NULL; 00310 00311 if (!(read_frame = (direction == AST_AUDIOHOOK_DIRECTION_BOTH ? audiohook_read_frame_both(audiohook, samples) : audiohook_read_frame_single(audiohook, samples, direction)))) 00312 return NULL; 00313 00314 /* If they don't want signed linear back out, we'll have to send it through the translation path */ 00315 if (format != AST_FORMAT_SLINEAR) { 00316 /* Rebuild translation path if different format then previously */ 00317 if (audiohook->format != format) { 00318 if (audiohook->trans_pvt) { 00319 ast_translator_free_path(audiohook->trans_pvt); 00320 audiohook->trans_pvt = NULL; 00321 } 00322 /* Setup new translation path for this format... if we fail we can't very well return signed linear so free the frame and return nothing */ 00323 if (!(audiohook->trans_pvt = ast_translator_build_path(format, AST_FORMAT_SLINEAR))) { 00324 ast_frfree(read_frame); 00325 return NULL; 00326 } 00327 } 00328 /* Convert to requested format, and allow the read in frame to be freed */ 00329 final_frame = ast_translate(audiohook->trans_pvt, read_frame, 1); 00330 } else { 00331 final_frame = read_frame; 00332 } 00333 00334 return final_frame; 00335 }
int ast_audiohook_remove | ( | struct ast_channel * | chan, | |
struct ast_audiohook * | audiohook | |||
) |
Remove an audiohook from a specified channel.
chan | Channel to remove from | |
audiohook | Audiohook to remove |
Definition at line 535 of file audiohook.c.
References AST_AUDIOHOOK_STATUS_DONE, AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_audiohook_update_status(), ast_channel_lock, ast_channel_unlock, AST_LIST_REMOVE, ast_channel::audiohooks, ast_audiohook::list, ast_audiohook_list::manipulate_list, ast_audiohook_list::spy_list, ast_audiohook::type, and ast_audiohook_list::whisper_list.
Referenced by ast_audiohook_move_by_source(), and speex_write().
00536 { 00537 ast_channel_lock(chan); 00538 00539 if (!chan->audiohooks) { 00540 ast_channel_unlock(chan); 00541 return -1; 00542 } 00543 00544 if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY) 00545 AST_LIST_REMOVE(&chan->audiohooks->spy_list, audiohook, list); 00546 else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER) 00547 AST_LIST_REMOVE(&chan->audiohooks->whisper_list, audiohook, list); 00548 else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) 00549 AST_LIST_REMOVE(&chan->audiohooks->manipulate_list, audiohook, list); 00550 00551 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE); 00552 00553 ast_channel_unlock(chan); 00554 00555 return 0; 00556 }
int ast_audiohook_set_mute | ( | struct ast_channel * | chan, | |
const char * | source, | |||
enum ast_audiohook_flags | flag, | |||
int | clear | |||
) |
Mute frames read from or written to a channel.
chan | Channel to muck with | |
source | Type of audiohook | |
flag | which flag to set / clear | |
clear | set or clear |
Definition at line 1055 of file audiohook.c.
References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_set_flag, ast_channel::audiohooks, and find_audiohook_by_source().
Referenced by manager_mute_mixmonitor().
01056 { 01057 struct ast_audiohook *audiohook = NULL; 01058 01059 ast_channel_lock(chan); 01060 01061 /* Ensure the channel has audiohooks on it */ 01062 if (!chan->audiohooks) { 01063 ast_channel_unlock(chan); 01064 return -1; 01065 } 01066 01067 audiohook = find_audiohook_by_source(chan->audiohooks, source); 01068 01069 if (audiohook) { 01070 if (clear) { 01071 ast_clear_flag(audiohook, flag); 01072 } else { 01073 ast_set_flag(audiohook, flag); 01074 } 01075 } 01076 01077 ast_channel_unlock(chan); 01078 01079 return (audiohook ? 0 : -1); 01080 }
void ast_audiohook_trigger_wait | ( | struct ast_audiohook * | audiohook | ) |
Wait for audiohook trigger to be triggered.
audiohook | Audiohook to wait on |
Definition at line 774 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().
00775 { 00776 struct timeval wait; 00777 struct timespec ts; 00778 00779 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000)); 00780 ts.tv_sec = wait.tv_sec; 00781 ts.tv_nsec = wait.tv_usec * 1000; 00782 00783 ast_cond_timedwait(&audiohook->trigger, &audiohook->lock, &ts); 00784 00785 return; 00786 }
void ast_audiohook_update_status | ( | struct ast_audiohook * | audiohook, | |
enum ast_audiohook_status | status | |||
) |
Update audiohook's status.
audiohook | Audiohook structure | |
status | Audiohook status enum |
Definition at line 381 of file audiohook.c.
References ast_audiohook_lock, AST_AUDIOHOOK_STATUS_DONE, ast_audiohook_unlock, ast_cond_signal, ast_audiohook::status, and ast_audiohook::trigger.
Referenced by ast_audiohook_attach(), ast_audiohook_detach(), ast_audiohook_detach_list(), ast_audiohook_detach_source(), ast_audiohook_init(), ast_audiohook_remove(), audio_audiohook_write_list(), and dtmf_audiohook_write_list().
00382 { 00383 ast_audiohook_lock(audiohook); 00384 if (audiohook->status != AST_AUDIOHOOK_STATUS_DONE) { 00385 audiohook->status = status; 00386 ast_cond_signal(&audiohook->trigger); 00387 } 00388 ast_audiohook_unlock(audiohook); 00389 }
int ast_audiohook_volume_adjust | ( | struct ast_channel * | chan, | |
enum ast_audiohook_direction | direction, | |||
int | volume | |||
) |
Adjust the volume on frames read from or written to a channel.
chan | Channel to muck with | |
direction | Direction to increase | |
volume | Value to adjust the adjustment by |
Definition at line 1028 of file audiohook.c.
References AST_AUDIOHOOK_DIRECTION_BOTH, AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, audiohook_volume_get(), audiohook_volume::read_adjustment, and audiohook_volume::write_adjustment.
Referenced by menu_callback().
01029 { 01030 struct audiohook_volume *audiohook_volume = NULL; 01031 01032 /* Attempt to find the audiohook volume information, and create an audiohook if none exists */ 01033 if (!(audiohook_volume = audiohook_volume_get(chan, 1))) { 01034 return -1; 01035 } 01036 01037 /* Based on the direction change the specific adjustment value */ 01038 if (direction == AST_AUDIOHOOK_DIRECTION_READ || direction == AST_AUDIOHOOK_DIRECTION_BOTH) { 01039 audiohook_volume->read_adjustment += volume; 01040 } 01041 if (direction == AST_AUDIOHOOK_DIRECTION_WRITE || direction == AST_AUDIOHOOK_DIRECTION_BOTH) { 01042 audiohook_volume->write_adjustment += volume; 01043 } 01044 01045 return 0; 01046 }
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.
chan | Channel to retrieve volume adjustment from | |
direction | Direction to retrieve |
Definition at line 1002 of file audiohook.c.
References AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, audiohook_volume_get(), audiohook_volume::read_adjustment, and audiohook_volume::write_adjustment.
Referenced by confbridge_exec().
01003 { 01004 struct audiohook_volume *audiohook_volume = NULL; 01005 int adjustment = 0; 01006 01007 /* Attempt to find the audiohook volume information, but do not create it as we only want to look at the values */ 01008 if (!(audiohook_volume = audiohook_volume_get(chan, 0))) { 01009 return 0; 01010 } 01011 01012 /* Grab the adjustment value based on direction given */ 01013 if (direction == AST_AUDIOHOOK_DIRECTION_READ) { 01014 adjustment = audiohook_volume->read_adjustment; 01015 } else if (direction == AST_AUDIOHOOK_DIRECTION_WRITE) { 01016 adjustment = audiohook_volume->write_adjustment; 01017 } 01018 01019 return adjustment; 01020 }
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.
chan | Channel to muck with | |
direction | Direction to set on | |
volume | Value to adjust the volume by |
Definition at line 977 of file audiohook.c.
References AST_AUDIOHOOK_DIRECTION_BOTH, AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, audiohook_volume_get(), audiohook_volume::read_adjustment, and audiohook_volume::write_adjustment.
Referenced by confbridge_exec().
00978 { 00979 struct audiohook_volume *audiohook_volume = NULL; 00980 00981 /* Attempt to find the audiohook volume information, but only create it if we are not setting the adjustment value to zero */ 00982 if (!(audiohook_volume = audiohook_volume_get(chan, (volume ? 1 : 0)))) { 00983 return -1; 00984 } 00985 00986 /* Now based on the direction set the proper value */ 00987 if (direction == AST_AUDIOHOOK_DIRECTION_READ || direction == AST_AUDIOHOOK_DIRECTION_BOTH) { 00988 audiohook_volume->read_adjustment = volume; 00989 } 00990 if (direction == AST_AUDIOHOOK_DIRECTION_WRITE || direction == AST_AUDIOHOOK_DIRECTION_BOTH) { 00991 audiohook_volume->write_adjustment = volume; 00992 } 00993 00994 return 0; 00995 }
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.
audiohook | Audiohook structure | |
direction | Direction the audio frame came from | |
frame | Frame to write in |
Definition at line 121 of file audiohook.c.
References AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, AST_AUDIOHOOK_MUTE_READ, AST_AUDIOHOOK_MUTE_WRITE, AST_AUDIOHOOK_SMALL_QUEUE, AST_AUDIOHOOK_SYNC_TOLERANCE, AST_AUDIOHOOK_TRIGGER_MODE, AST_AUDIOHOOK_TRIGGER_READ, AST_AUDIOHOOK_TRIGGER_SYNC, AST_AUDIOHOOK_TRIGGER_WRITE, ast_cond_signal, ast_frame_clear(), ast_log(), ast_slinfactory_available(), ast_slinfactory_feed(), ast_slinfactory_flush(), ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_frame::datalen, LOG_DEBUG, option_debug, ast_audiohook::read_factory, ast_audiohook::read_time, ast_audiohook::trigger, ast_audiohook::write_factory, and ast_audiohook::write_time.
Referenced by audio_audiohook_write_list(), and channel_spy().
00122 { 00123 struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory); 00124 struct ast_slinfactory *other_factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->write_factory : &audiohook->read_factory); 00125 struct timeval *rwtime = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_time : &audiohook->write_time), previous_time = *rwtime; 00126 int our_factory_samples; 00127 int our_factory_ms; 00128 int other_factory_samples; 00129 int other_factory_ms; 00130 int muteme = 0; 00131 00132 /* Update last feeding time to be current */ 00133 *rwtime = ast_tvnow(); 00134 00135 our_factory_samples = ast_slinfactory_available(factory); 00136 our_factory_ms = ast_tvdiff_ms(*rwtime, previous_time) + (our_factory_samples / 8); 00137 other_factory_samples = ast_slinfactory_available(other_factory); 00138 other_factory_ms = other_factory_samples / 8; 00139 00140 if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC) && other_factory_samples && (our_factory_ms - other_factory_ms > AST_AUDIOHOOK_SYNC_TOLERANCE)) { 00141 if (option_debug) 00142 ast_log(LOG_DEBUG, "Flushing audiohook %p so it remains in sync\n", audiohook); 00143 ast_slinfactory_flush(factory); 00144 ast_slinfactory_flush(other_factory); 00145 } 00146 00147 if (ast_test_flag(audiohook, AST_AUDIOHOOK_SMALL_QUEUE) && (our_factory_samples > 640 || other_factory_samples > 640)) { 00148 if (option_debug) { 00149 ast_log(LOG_DEBUG, "Audiohook %p has stale audio in its factories. Flushing them both\n", audiohook); 00150 } 00151 ast_slinfactory_flush(factory); 00152 ast_slinfactory_flush(other_factory); 00153 } 00154 00155 /* swap frame data for zeros if mute is required */ 00156 if ((ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_READ) && (direction == AST_AUDIOHOOK_DIRECTION_READ)) || 00157 (ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_WRITE) && (direction == AST_AUDIOHOOK_DIRECTION_WRITE)) || 00158 (ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_READ | AST_AUDIOHOOK_MUTE_WRITE) == (AST_AUDIOHOOK_MUTE_READ | AST_AUDIOHOOK_MUTE_WRITE))) { 00159 muteme = 1; 00160 } 00161 00162 if (muteme && frame->datalen > 0) { 00163 ast_frame_clear(frame); 00164 } 00165 00166 /* Write frame out to respective factory */ 00167 ast_slinfactory_feed(factory, frame); 00168 00169 /* If we need to notify the respective handler of this audiohook, do so */ 00170 if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_READ) && (direction == AST_AUDIOHOOK_DIRECTION_READ)) { 00171 ast_cond_signal(&audiohook->trigger); 00172 } else if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_WRITE) && (direction == AST_AUDIOHOOK_DIRECTION_WRITE)) { 00173 ast_cond_signal(&audiohook->trigger); 00174 } else if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC)) { 00175 ast_cond_signal(&audiohook->trigger); 00176 } 00177 00178 return 0; 00179 }
struct ast_frame* ast_audiohook_write_list | ( | struct ast_channel * | chan, | |
struct ast_audiohook_list * | audiohook_list, | |||
enum ast_audiohook_direction | direction, | |||
struct ast_frame * | frame | |||
) |
Pass a frame off to be handled by the audiohook core.
chan | Channel that the list is coming off of | |
audiohook_list | List of audiohooks | |
direction | Direction frame is coming in from | |
frame | The frame itself |
Definition at line 760 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().
00761 { 00762 /* Pass off frame to it's respective list write function */ 00763 if (frame->frametype == AST_FRAME_VOICE) 00764 return audio_audiohook_write_list(chan, audiohook_list, direction, frame); 00765 else if (frame->frametype == AST_FRAME_DTMF) 00766 return dtmf_audiohook_write_list(chan, audiohook_list, direction, frame); 00767 else 00768 return frame; 00769 }
int ast_audiohook_write_list_empty | ( | struct ast_audiohook_list * | audiohook_list | ) |
determines if a audiohook_list is empty or not.
retval 0 false, 1 true
Definition at line 742 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_write(), and audio_audiohook_write_list().
00743 { 00744 if (AST_LIST_EMPTY(&audiohook_list->spy_list) && 00745 AST_LIST_EMPTY(&audiohook_list->whisper_list) && 00746 AST_LIST_EMPTY(&audiohook_list->manipulate_list)) { 00747 00748 return 1; 00749 } 00750 return 0; 00751 }
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.
chan | The channel on which to find the spies | |
source | The audiohook's source | |
type | The type of audiohook |
Definition at line 789 of file audiohook.c.
References AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, AST_LIST_TRAVERSE, ast_log(), ast_channel::audiohooks, ast_audiohook::list, ast_audiohook_list::manipulate_list, ast_audiohook::source, ast_audiohook_list::spy_list, and ast_audiohook_list::whisper_list.
Referenced by builtin_automixmonitor().
00790 { 00791 int count = 0; 00792 struct ast_audiohook *ah = NULL; 00793 00794 if (!chan->audiohooks) 00795 return -1; 00796 00797 switch (type) { 00798 case AST_AUDIOHOOK_TYPE_SPY: 00799 AST_LIST_TRAVERSE(&chan->audiohooks->spy_list, ah, list) { 00800 if (!strcmp(ah->source, source)) { 00801 count++; 00802 } 00803 } 00804 break; 00805 case AST_AUDIOHOOK_TYPE_WHISPER: 00806 AST_LIST_TRAVERSE(&chan->audiohooks->whisper_list, ah, list) { 00807 if (!strcmp(ah->source, source)) { 00808 count++; 00809 } 00810 } 00811 break; 00812 case AST_AUDIOHOOK_TYPE_MANIPULATE: 00813 AST_LIST_TRAVERSE(&chan->audiohooks->manipulate_list, ah, list) { 00814 if (!strcmp(ah->source, source)) { 00815 count++; 00816 } 00817 } 00818 break; 00819 default: 00820 ast_log(LOG_DEBUG, "Invalid audiohook type supplied, (%d)\n", type); 00821 return -1; 00822 } 00823 00824 return count; 00825 }
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.
chan | The channel on which to find the spies | |
source | The source of the audiohook | |
type | The type of spy to look for |
Definition at line 828 of file audiohook.c.
References AST_AUDIOHOOK_STATUS_RUNNING, AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, AST_LIST_TRAVERSE, ast_log(), ast_channel::audiohooks, ast_audiohook::list, ast_audiohook_list::manipulate_list, ast_audiohook::source, ast_audiohook_list::spy_list, ast_audiohook::status, and ast_audiohook_list::whisper_list.
Referenced by builtin_automixmonitor().
00829 { 00830 int count = 0; 00831 struct ast_audiohook *ah = NULL; 00832 if (!chan->audiohooks) 00833 return -1; 00834 00835 switch (type) { 00836 case AST_AUDIOHOOK_TYPE_SPY: 00837 AST_LIST_TRAVERSE(&chan->audiohooks->spy_list, ah, list) { 00838 if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING)) 00839 count++; 00840 } 00841 break; 00842 case AST_AUDIOHOOK_TYPE_WHISPER: 00843 AST_LIST_TRAVERSE(&chan->audiohooks->whisper_list, ah, list) { 00844 if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING)) 00845 count++; 00846 } 00847 break; 00848 case AST_AUDIOHOOK_TYPE_MANIPULATE: 00849 AST_LIST_TRAVERSE(&chan->audiohooks->manipulate_list, ah, list) { 00850 if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING)) 00851 count++; 00852 } 00853 break; 00854 default: 00855 ast_log(LOG_DEBUG, "Invalid audiohook type supplied, (%d)\n", type); 00856 return -1; 00857 } 00858 return count; 00859 }