#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 = ((1 << 6) | (1 << 0)), AST_AUDIOHOOK_TRIGGER_READ = (1 << 0), AST_AUDIOHOOK_TRIGGER_WRITE = (1 << 6), 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 267 of file audiohook.h.
Referenced by ast_audiohook_move_by_source(), ast_audiohook_update_status(), audio_audiohook_write_list(), channel_spy(), destroy_callback(), 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 272 of file audiohook.h.
Referenced by ast_audiohook_move_by_source(), ast_audiohook_update_status(), audio_audiohook_write_list(), channel_spy(), destroy_callback(), 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 96 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 60 of file audiohook.h.
00060 { 00061 AST_AUDIOHOOK_TRIGGER_MODE = ((1 << 6) | (1 << 0)), /*!< When audiohook should be triggered to do something */ 00062 AST_AUDIOHOOK_TRIGGER_READ = (1 << 0), /*!< Audiohook wants to be triggered when reading audio in */ 00063 AST_AUDIOHOOK_TRIGGER_WRITE = (1 << 6), /*!< Audiohook wants to be triggered when writing audio out */ 00064 AST_AUDIOHOOK_WANTS_DTMF = (1 << 1), /*!< Audiohook also wants to receive DTMF frames */ 00065 AST_AUDIOHOOK_TRIGGER_SYNC = (1 << 2), /*!< Audiohook wants to be triggered when both sides have combined audio available */ 00066 /*! Audiohooks with this flag set will not allow for a large amount of samples to build up on its 00067 * slinfactories. We will flush the factories if they contain too many samples. 00068 */ 00069 AST_AUDIOHOOK_SMALL_QUEUE = (1 << 3), 00070 AST_AUDIOHOOK_MUTE_READ = (1 << 4), /*!< audiohook should be mute frames read */ 00071 AST_AUDIOHOOK_MUTE_WRITE = (1 << 5), /*!< audiohook should be mute frames written */ 00072 00073 /* IMPORTANT: When adding new flags, start with (1 << 7) */ 00074 };
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 348 of file audiohook.c.
References AST_AUDIOHOOK_STATUS_RUNNING, AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_audiohook_update_status(), ast_calloc, ast_channel_lock, ast_channel_unlock, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_TAIL, ast_channel::audiohooks, ast_audiohook_list::manipulate_list, ast_audiohook_list::spy_list, ast_audiohook::type, and ast_audiohook_list::whisper_list.
Referenced by ast_audiohook_move_by_source(), audiohook_volume_get(), enable_jack_hook(), mute_add_audiohook(), pitchshift_helper(), speex_write(), start_spying(), startmon(), and volume_write().
00349 { 00350 ast_channel_lock(chan); 00351 00352 if (!chan->audiohooks) { 00353 /* Whoops... allocate a new structure */ 00354 if (!(chan->audiohooks = ast_calloc(1, sizeof(*chan->audiohooks)))) { 00355 ast_channel_unlock(chan); 00356 return -1; 00357 } 00358 AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->spy_list); 00359 AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->whisper_list); 00360 AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->manipulate_list); 00361 } 00362 00363 /* Drop into respective list */ 00364 if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY) 00365 AST_LIST_INSERT_TAIL(&chan->audiohooks->spy_list, audiohook, list); 00366 else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER) 00367 AST_LIST_INSERT_TAIL(&chan->audiohooks->whisper_list, audiohook, list); 00368 else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) 00369 AST_LIST_INSERT_TAIL(&chan->audiohooks->manipulate_list, audiohook, list); 00370 00371 /* Change status over to running since it is now attached */ 00372 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_RUNNING); 00373 00374 ast_channel_unlock(chan); 00375 00376 return 0; 00377 }
int ast_audiohook_destroy | ( | struct ast_audiohook * | audiohook | ) |
Destroys an audiohook structure.
audiohook | Audiohook structure |
Definition at line 96 of file audiohook.c.
References AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_cond_destroy, ast_mutex_destroy, ast_slinfactory_destroy(), ast_translator_free_path(), ast_audiohook::lock, ast_audiohook::read_factory, ast_audiohook::trans_pvt, ast_audiohook::trigger, ast_audiohook::type, and ast_audiohook::write_factory.
Referenced by audiohook_volume_destroy(), channel_spy(), destroy_callback(), destroy_jack_data(), destroy_monitor_audiohook(), and launch_monitor_thread().
00097 { 00098 /* Drop the factories used by this audiohook type */ 00099 switch (audiohook->type) { 00100 case AST_AUDIOHOOK_TYPE_SPY: 00101 ast_slinfactory_destroy(&audiohook->read_factory); 00102 /* Fall through intentionally */ 00103 case AST_AUDIOHOOK_TYPE_WHISPER: 00104 ast_slinfactory_destroy(&audiohook->write_factory); 00105 break; 00106 default: 00107 break; 00108 } 00109 00110 /* Destroy translation path if present */ 00111 if (audiohook->trans_pvt) 00112 ast_translator_free_path(audiohook->trans_pvt); 00113 00114 /* Lock and trigger be gone! */ 00115 ast_cond_destroy(&audiohook->trigger); 00116 ast_mutex_destroy(&audiohook->lock); 00117 00118 return 0; 00119 }
int ast_audiohook_detach | ( | struct ast_audiohook * | audiohook | ) |
Detach audiohook from channel.
audiohook | Audiohook structure |
Definition at line 401 of file audiohook.c.
References AST_AUDIOHOOK_STATUS_DONE, AST_AUDIOHOOK_STATUS_NEW, AST_AUDIOHOOK_STATUS_SHUTDOWN, ast_audiohook_trigger_wait(), ast_audiohook_update_status(), and ast_audiohook::status.
Referenced by channel_spy(), destroy_callback(), destroy_monitor_audiohook(), disable_jack_hook(), and speex_write().
00402 { 00403 if (audiohook->status == AST_AUDIOHOOK_STATUS_NEW || audiohook->status == AST_AUDIOHOOK_STATUS_DONE) 00404 return 0; 00405 00406 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_SHUTDOWN); 00407 00408 while (audiohook->status != AST_AUDIOHOOK_STATUS_DONE) 00409 ast_audiohook_trigger_wait(audiohook); 00410 00411 return 0; 00412 }
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 418 of file audiohook.c.
References AST_AUDIOHOOK_STATUS_DONE, ast_audiohook_update_status(), ast_free, AST_LIST_REMOVE_HEAD, ast_translator_free_path(), ast_audiohook_list::in_translate, ast_audiohook::list, ast_audiohook_list::manipulate_list, ast_audiohook_list::out_translate, ast_audiohook_list::spy_list, ast_audiohook_translate::trans_pvt, and ast_audiohook_list::whisper_list.
Referenced by __ast_read(), ast_write(), and destroy_hooks().
00419 { 00420 int i = 0; 00421 struct ast_audiohook *audiohook = NULL; 00422 00423 /* Drop any spies */ 00424 while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->spy_list, list))) { 00425 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE); 00426 } 00427 00428 /* Drop any whispering sources */ 00429 while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->whisper_list, list))) { 00430 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE); 00431 } 00432 00433 /* Drop any manipulaters */ 00434 while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->manipulate_list, list))) { 00435 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE); 00436 audiohook->manipulate_callback(audiohook, NULL, NULL, 0); 00437 } 00438 00439 /* Drop translation paths if present */ 00440 for (i = 0; i < 2; i++) { 00441 if (audiohook_list->in_translate[i].trans_pvt) 00442 ast_translator_free_path(audiohook_list->in_translate[i].trans_pvt); 00443 if (audiohook_list->out_translate[i].trans_pvt) 00444 ast_translator_free_path(audiohook_list->out_translate[i].trans_pvt); 00445 } 00446 00447 /* Free ourselves */ 00448 ast_free(audiohook_list); 00449 00450 return 0; 00451 }
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 509 of file audiohook.c.
References AST_AUDIOHOOK_STATUS_DONE, AST_AUDIOHOOK_STATUS_SHUTDOWN, ast_audiohook_update_status(), ast_channel_lock, ast_channel_unlock, ast_channel::audiohooks, find_audiohook_by_source(), and ast_audiohook::status.
Referenced by handle_cli_mixmonitor(), and stop_mixmonitor_exec().
00510 { 00511 struct ast_audiohook *audiohook = NULL; 00512 00513 ast_channel_lock(chan); 00514 00515 /* Ensure the channel has audiohooks on it */ 00516 if (!chan->audiohooks) { 00517 ast_channel_unlock(chan); 00518 return -1; 00519 } 00520 00521 audiohook = find_audiohook_by_source(chan->audiohooks, source); 00522 00523 ast_channel_unlock(chan); 00524 00525 if (audiohook && audiohook->status != AST_AUDIOHOOK_STATUS_DONE) 00526 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_SHUTDOWN); 00527 00528 return (audiohook ? 0 : -1); 00529 }
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 64 of file audiohook.c.
References AST_AUDIOHOOK_STATUS_NEW, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_audiohook_update_status(), ast_cond_init, ast_mutex_init, 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().
00065 { 00066 /* Need to keep the type and source */ 00067 audiohook->type = type; 00068 audiohook->source = source; 00069 00070 /* Initialize lock that protects our audiohook */ 00071 ast_mutex_init(&audiohook->lock); 00072 ast_cond_init(&audiohook->trigger, NULL); 00073 00074 /* Setup the factories that are needed for this audiohook type */ 00075 switch (type) { 00076 case AST_AUDIOHOOK_TYPE_SPY: 00077 ast_slinfactory_init(&audiohook->read_factory); 00078 /* Fall through intentionally */ 00079 case AST_AUDIOHOOK_TYPE_WHISPER: 00080 ast_slinfactory_init(&audiohook->write_factory); 00081 break; 00082 default: 00083 break; 00084 } 00085 00086 /* Since we are just starting out... this audiohook is new */ 00087 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_NEW); 00088 00089 return 0; 00090 }
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 480 of file audiohook.c.
References ast_audiohook_attach(), ast_audiohook_lock, ast_audiohook_remove(), ast_audiohook_unlock, ast_channel::audiohooks, find_audiohook_by_source(), and ast_audiohook::status.
Referenced by audiohook_inheritance_fixup().
00481 { 00482 struct ast_audiohook *audiohook; 00483 enum ast_audiohook_status oldstatus; 00484 00485 if (!old_chan->audiohooks || !(audiohook = find_audiohook_by_source(old_chan->audiohooks, source))) { 00486 return; 00487 } 00488 00489 /* By locking both channels and the audiohook, we can assure that 00490 * another thread will not have a chance to read the audiohook's status 00491 * as done, even though ast_audiohook_remove signals the trigger 00492 * condition. 00493 */ 00494 ast_audiohook_lock(audiohook); 00495 oldstatus = audiohook->status; 00496 00497 ast_audiohook_remove(old_chan, audiohook); 00498 ast_audiohook_attach(new_chan, audiohook); 00499 00500 audiohook->status = oldstatus; 00501 ast_audiohook_unlock(audiohook); 00502 }
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 313 of file audiohook.c.
References AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR, ast_frfree, ast_translate(), ast_translator_build_path(), ast_translator_free_path(), audiohook_read_frame_both(), audiohook_read_frame_single(), and read_frame().
Referenced by mixmonitor_thread(), and spy_generate().
00314 { 00315 struct ast_frame *read_frame = NULL, *final_frame = NULL; 00316 00317 if (!(read_frame = (direction == AST_AUDIOHOOK_DIRECTION_BOTH ? audiohook_read_frame_both(audiohook, samples) : audiohook_read_frame_single(audiohook, samples, direction)))) 00318 return NULL; 00319 00320 /* If they don't want signed linear back out, we'll have to send it through the translation path */ 00321 if (format != AST_FORMAT_SLINEAR) { 00322 /* Rebuild translation path if different format then previously */ 00323 if (audiohook->format != format) { 00324 if (audiohook->trans_pvt) { 00325 ast_translator_free_path(audiohook->trans_pvt); 00326 audiohook->trans_pvt = NULL; 00327 } 00328 /* 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 */ 00329 if (!(audiohook->trans_pvt = ast_translator_build_path(format, AST_FORMAT_SLINEAR))) { 00330 ast_frfree(read_frame); 00331 return NULL; 00332 } 00333 } 00334 /* Convert to requested format, and allow the read in frame to be freed */ 00335 final_frame = ast_translate(audiohook->trans_pvt, read_frame, 1); 00336 } else { 00337 final_frame = read_frame; 00338 } 00339 00340 return final_frame; 00341 }
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 541 of file audiohook.c.
References AST_AUDIOHOOK_STATUS_DONE, AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_audiohook_update_status(), ast_channel_lock, ast_channel_unlock, AST_LIST_REMOVE, ast_channel::audiohooks, ast_audiohook::list, ast_audiohook_list::manipulate_list, ast_audiohook_list::spy_list, ast_audiohook::type, and ast_audiohook_list::whisper_list.
Referenced by ast_audiohook_move_by_source(), and speex_write().
00542 { 00543 ast_channel_lock(chan); 00544 00545 if (!chan->audiohooks) { 00546 ast_channel_unlock(chan); 00547 return -1; 00548 } 00549 00550 if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY) 00551 AST_LIST_REMOVE(&chan->audiohooks->spy_list, audiohook, list); 00552 else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER) 00553 AST_LIST_REMOVE(&chan->audiohooks->whisper_list, audiohook, list); 00554 else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) 00555 AST_LIST_REMOVE(&chan->audiohooks->manipulate_list, audiohook, list); 00556 00557 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE); 00558 00559 ast_channel_unlock(chan); 00560 00561 return 0; 00562 }
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 1057 of file audiohook.c.
References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_set_flag, ast_channel::audiohooks, and find_audiohook_by_source().
Referenced by manager_mute_mixmonitor().
01058 { 01059 struct ast_audiohook *audiohook = NULL; 01060 01061 ast_channel_lock(chan); 01062 01063 /* Ensure the channel has audiohooks on it */ 01064 if (!chan->audiohooks) { 01065 ast_channel_unlock(chan); 01066 return -1; 01067 } 01068 01069 audiohook = find_audiohook_by_source(chan->audiohooks, source); 01070 01071 if (audiohook) { 01072 if (clear) { 01073 ast_clear_flag(audiohook, flag); 01074 } else { 01075 ast_set_flag(audiohook, flag); 01076 } 01077 } 01078 01079 ast_channel_unlock(chan); 01080 01081 return (audiohook ? 0 : -1); 01082 }
void ast_audiohook_trigger_wait | ( | struct ast_audiohook * | audiohook | ) |
Wait for audiohook trigger to be triggered.
audiohook | Audiohook to wait on |
Definition at line 776 of file audiohook.c.
References ast_cond_timedwait, ast_samp2tv(), ast_tvadd(), ast_tvnow(), ast_audiohook::lock, and ast_audiohook::trigger.
Referenced by ast_audiohook_detach(), and mixmonitor_thread().
00777 { 00778 struct timeval wait; 00779 struct timespec ts; 00780 00781 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000)); 00782 ts.tv_sec = wait.tv_sec; 00783 ts.tv_nsec = wait.tv_usec * 1000; 00784 00785 ast_cond_timedwait(&audiohook->trigger, &audiohook->lock, &ts); 00786 00787 return; 00788 }
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 387 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().
00388 { 00389 ast_audiohook_lock(audiohook); 00390 if (audiohook->status != AST_AUDIOHOOK_STATUS_DONE) { 00391 audiohook->status = status; 00392 ast_cond_signal(&audiohook->trigger); 00393 } 00394 ast_audiohook_unlock(audiohook); 00395 }
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 1030 of file audiohook.c.
References AST_AUDIOHOOK_DIRECTION_BOTH, AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, audiohook_volume_get(), audiohook_volume::read_adjustment, and audiohook_volume::write_adjustment.
Referenced by menu_callback().
01031 { 01032 struct audiohook_volume *audiohook_volume = NULL; 01033 01034 /* Attempt to find the audiohook volume information, and create an audiohook if none exists */ 01035 if (!(audiohook_volume = audiohook_volume_get(chan, 1))) { 01036 return -1; 01037 } 01038 01039 /* Based on the direction change the specific adjustment value */ 01040 if (direction == AST_AUDIOHOOK_DIRECTION_READ || direction == AST_AUDIOHOOK_DIRECTION_BOTH) { 01041 audiohook_volume->read_adjustment += volume; 01042 } 01043 if (direction == AST_AUDIOHOOK_DIRECTION_WRITE || direction == AST_AUDIOHOOK_DIRECTION_BOTH) { 01044 audiohook_volume->write_adjustment += volume; 01045 } 01046 01047 return 0; 01048 }
int ast_audiohook_volume_get | ( | struct ast_channel * | chan, | |
enum ast_audiohook_direction | direction | |||
) |
Retrieve the volume adjustment value on frames read from or written to a channel.
chan | Channel to retrieve volume adjustment from | |
direction | Direction to retrieve |
Definition at line 1004 of file audiohook.c.
References AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, audiohook_volume_get(), audiohook_volume::read_adjustment, and audiohook_volume::write_adjustment.
Referenced by confbridge_exec().
01005 { 01006 struct audiohook_volume *audiohook_volume = NULL; 01007 int adjustment = 0; 01008 01009 /* Attempt to find the audiohook volume information, but do not create it as we only want to look at the values */ 01010 if (!(audiohook_volume = audiohook_volume_get(chan, 0))) { 01011 return 0; 01012 } 01013 01014 /* Grab the adjustment value based on direction given */ 01015 if (direction == AST_AUDIOHOOK_DIRECTION_READ) { 01016 adjustment = audiohook_volume->read_adjustment; 01017 } else if (direction == AST_AUDIOHOOK_DIRECTION_WRITE) { 01018 adjustment = audiohook_volume->write_adjustment; 01019 } 01020 01021 return adjustment; 01022 }
int ast_audiohook_volume_set | ( | struct ast_channel * | chan, | |
enum ast_audiohook_direction | direction, | |||
int | volume | |||
) |
Adjust the volume on frames read from or written to a channel.
chan | Channel to muck with | |
direction | Direction to set on | |
volume | Value to adjust the volume by |
Definition at line 979 of file audiohook.c.
References AST_AUDIOHOOK_DIRECTION_BOTH, AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, audiohook_volume_get(), audiohook_volume::read_adjustment, and audiohook_volume::write_adjustment.
Referenced by confbridge_exec().
00980 { 00981 struct audiohook_volume *audiohook_volume = NULL; 00982 00983 /* Attempt to find the audiohook volume information, but only create it if we are not setting the adjustment value to zero */ 00984 if (!(audiohook_volume = audiohook_volume_get(chan, (volume ? 1 : 0)))) { 00985 return -1; 00986 } 00987 00988 /* Now based on the direction set the proper value */ 00989 if (direction == AST_AUDIOHOOK_DIRECTION_READ || direction == AST_AUDIOHOOK_DIRECTION_BOTH) { 00990 audiohook_volume->read_adjustment = volume; 00991 } 00992 if (direction == AST_AUDIOHOOK_DIRECTION_WRITE || direction == AST_AUDIOHOOK_DIRECTION_BOTH) { 00993 audiohook_volume->write_adjustment = volume; 00994 } 00995 00996 return 0; 00997 }
int ast_audiohook_write_frame | ( | struct ast_audiohook * | audiohook, | |
enum ast_audiohook_direction | direction, | |||
struct ast_frame * | frame | |||
) |
Writes a frame into the audiohook structure.
audiohook | Audiohook structure | |
direction | Direction the audio frame came from | |
frame | Frame to write in |
Definition at line 127 of file audiohook.c.
References AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, AST_AUDIOHOOK_MUTE_READ, AST_AUDIOHOOK_MUTE_WRITE, AST_AUDIOHOOK_SMALL_QUEUE, AST_AUDIOHOOK_SYNC_TOLERANCE, AST_AUDIOHOOK_TRIGGER_MODE, AST_AUDIOHOOK_TRIGGER_READ, AST_AUDIOHOOK_TRIGGER_SYNC, AST_AUDIOHOOK_TRIGGER_WRITE, ast_cond_signal, ast_frame_clear(), ast_log(), ast_slinfactory_available(), ast_slinfactory_feed(), ast_slinfactory_flush(), ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_frame::datalen, LOG_DEBUG, option_debug, ast_audiohook::read_factory, ast_audiohook::read_time, ast_audiohook::trigger, ast_audiohook::write_factory, and ast_audiohook::write_time.
Referenced by audio_audiohook_write_list(), and channel_spy().
00128 { 00129 struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory); 00130 struct ast_slinfactory *other_factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->write_factory : &audiohook->read_factory); 00131 struct timeval *rwtime = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_time : &audiohook->write_time), previous_time = *rwtime; 00132 int our_factory_samples; 00133 int our_factory_ms; 00134 int other_factory_samples; 00135 int other_factory_ms; 00136 int muteme = 0; 00137 00138 /* Update last feeding time to be current */ 00139 *rwtime = ast_tvnow(); 00140 00141 our_factory_samples = ast_slinfactory_available(factory); 00142 our_factory_ms = ast_tvdiff_ms(*rwtime, previous_time) + (our_factory_samples / 8); 00143 other_factory_samples = ast_slinfactory_available(other_factory); 00144 other_factory_ms = other_factory_samples / 8; 00145 00146 if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC) && other_factory_samples && (our_factory_ms - other_factory_ms > AST_AUDIOHOOK_SYNC_TOLERANCE)) { 00147 if (option_debug) 00148 ast_log(LOG_DEBUG, "Flushing audiohook %p so it remains in sync\n", audiohook); 00149 ast_slinfactory_flush(factory); 00150 ast_slinfactory_flush(other_factory); 00151 } 00152 00153 if (ast_test_flag(audiohook, AST_AUDIOHOOK_SMALL_QUEUE) && (our_factory_samples > 640 || other_factory_samples > 640)) { 00154 if (option_debug) { 00155 ast_log(LOG_DEBUG, "Audiohook %p has stale audio in its factories. Flushing them both\n", audiohook); 00156 } 00157 ast_slinfactory_flush(factory); 00158 ast_slinfactory_flush(other_factory); 00159 } 00160 00161 /* swap frame data for zeros if mute is required */ 00162 if ((ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_READ) && (direction == AST_AUDIOHOOK_DIRECTION_READ)) || 00163 (ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_WRITE) && (direction == AST_AUDIOHOOK_DIRECTION_WRITE)) || 00164 (ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_READ | AST_AUDIOHOOK_MUTE_WRITE) == (AST_AUDIOHOOK_MUTE_READ | AST_AUDIOHOOK_MUTE_WRITE))) { 00165 muteme = 1; 00166 } 00167 00168 if (muteme && frame->datalen > 0) { 00169 ast_frame_clear(frame); 00170 } 00171 00172 /* Write frame out to respective factory */ 00173 ast_slinfactory_feed(factory, frame); 00174 00175 /* If we need to notify the respective handler of this audiohook, do so */ 00176 if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_READ) && (direction == AST_AUDIOHOOK_DIRECTION_READ)) { 00177 ast_cond_signal(&audiohook->trigger); 00178 } else if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_WRITE) && (direction == AST_AUDIOHOOK_DIRECTION_WRITE)) { 00179 ast_cond_signal(&audiohook->trigger); 00180 } else if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC)) { 00181 ast_cond_signal(&audiohook->trigger); 00182 } 00183 00184 return 0; 00185 }
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 762 of file audiohook.c.
References AST_FRAME_DTMF, AST_FRAME_VOICE, audio_audiohook_write_list(), dtmf_audiohook_write_list(), and ast_frame::frametype.
Referenced by __ast_read(), and ast_write().
00763 { 00764 /* Pass off frame to it's respective list write function */ 00765 if (frame->frametype == AST_FRAME_VOICE) 00766 return audio_audiohook_write_list(chan, audiohook_list, direction, frame); 00767 else if (frame->frametype == AST_FRAME_DTMF) 00768 return dtmf_audiohook_write_list(chan, audiohook_list, direction, frame); 00769 else 00770 return frame; 00771 }
int ast_audiohook_write_list_empty | ( | struct ast_audiohook_list * | audiohook_list | ) |
determines if a audiohook_list is empty or not.
retval 0 false, 1 true
Definition at line 744 of file audiohook.c.
References AST_LIST_EMPTY, ast_audiohook_list::manipulate_list, ast_audiohook_list::spy_list, and ast_audiohook_list::whisper_list.
Referenced by __ast_read(), and ast_write().
00745 { 00746 if (AST_LIST_EMPTY(&audiohook_list->spy_list) && 00747 AST_LIST_EMPTY(&audiohook_list->whisper_list) && 00748 AST_LIST_EMPTY(&audiohook_list->manipulate_list)) { 00749 00750 return 1; 00751 } 00752 return 0; 00753 }
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 791 of file audiohook.c.
References AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, AST_LIST_TRAVERSE, ast_log(), ast_channel::audiohooks, ast_audiohook::list, ast_audiohook_list::manipulate_list, ast_audiohook::source, ast_audiohook_list::spy_list, and ast_audiohook_list::whisper_list.
Referenced by builtin_automixmonitor().
00792 { 00793 int count = 0; 00794 struct ast_audiohook *ah = NULL; 00795 00796 if (!chan->audiohooks) 00797 return -1; 00798 00799 switch (type) { 00800 case AST_AUDIOHOOK_TYPE_SPY: 00801 AST_LIST_TRAVERSE(&chan->audiohooks->spy_list, ah, list) { 00802 if (!strcmp(ah->source, source)) { 00803 count++; 00804 } 00805 } 00806 break; 00807 case AST_AUDIOHOOK_TYPE_WHISPER: 00808 AST_LIST_TRAVERSE(&chan->audiohooks->whisper_list, ah, list) { 00809 if (!strcmp(ah->source, source)) { 00810 count++; 00811 } 00812 } 00813 break; 00814 case AST_AUDIOHOOK_TYPE_MANIPULATE: 00815 AST_LIST_TRAVERSE(&chan->audiohooks->manipulate_list, ah, list) { 00816 if (!strcmp(ah->source, source)) { 00817 count++; 00818 } 00819 } 00820 break; 00821 default: 00822 ast_log(LOG_DEBUG, "Invalid audiohook type supplied, (%d)\n", type); 00823 return -1; 00824 } 00825 00826 return count; 00827 }
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 830 of file audiohook.c.
References AST_AUDIOHOOK_STATUS_RUNNING, AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, AST_LIST_TRAVERSE, ast_log(), ast_channel::audiohooks, ast_audiohook::list, 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().
00831 { 00832 int count = 0; 00833 struct ast_audiohook *ah = NULL; 00834 if (!chan->audiohooks) 00835 return -1; 00836 00837 switch (type) { 00838 case AST_AUDIOHOOK_TYPE_SPY: 00839 AST_LIST_TRAVERSE(&chan->audiohooks->spy_list, ah, list) { 00840 if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING)) 00841 count++; 00842 } 00843 break; 00844 case AST_AUDIOHOOK_TYPE_WHISPER: 00845 AST_LIST_TRAVERSE(&chan->audiohooks->whisper_list, ah, list) { 00846 if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING)) 00847 count++; 00848 } 00849 break; 00850 case AST_AUDIOHOOK_TYPE_MANIPULATE: 00851 AST_LIST_TRAVERSE(&chan->audiohooks->manipulate_list, ah, list) { 00852 if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING)) 00853 count++; 00854 } 00855 break; 00856 default: 00857 ast_log(LOG_DEBUG, "Invalid audiohook type supplied, (%d)\n", type); 00858 return -1; 00859 } 00860 return count; 00861 }