#include "asterisk/lock.h"
#include "asterisk/linkedlists.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) } |
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, int 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. | |
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_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 251 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 256 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 87 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 };
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 330 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, chan, 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(), speex_write(), start_spying(), startmon(), and volume_write().
00331 { 00332 ast_channel_lock(chan); 00333 00334 if (!chan->audiohooks) { 00335 /* Whoops... allocate a new structure */ 00336 if (!(chan->audiohooks = ast_calloc(1, sizeof(*chan->audiohooks)))) { 00337 ast_channel_unlock(chan); 00338 return -1; 00339 } 00340 AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->spy_list); 00341 AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->whisper_list); 00342 AST_LIST_HEAD_INIT_NOLOCK(&chan->audiohooks->manipulate_list); 00343 } 00344 00345 /* Drop into respective list */ 00346 if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY) 00347 AST_LIST_INSERT_TAIL(&chan->audiohooks->spy_list, audiohook, list); 00348 else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER) 00349 AST_LIST_INSERT_TAIL(&chan->audiohooks->whisper_list, audiohook, list); 00350 else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) 00351 AST_LIST_INSERT_TAIL(&chan->audiohooks->manipulate_list, audiohook, list); 00352 00353 /* Change status over to running since it is now attached */ 00354 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_RUNNING); 00355 00356 ast_channel_unlock(chan); 00357 00358 return 0; 00359 }
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 383 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().
00384 { 00385 if (audiohook->status == AST_AUDIOHOOK_STATUS_NEW || audiohook->status == AST_AUDIOHOOK_STATUS_DONE) 00386 return 0; 00387 00388 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_SHUTDOWN); 00389 00390 while (audiohook->status != AST_AUDIOHOOK_STATUS_DONE) 00391 ast_audiohook_trigger_wait(audiohook); 00392 00393 return 0; 00394 }
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 400 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_hangup().
00401 { 00402 int i = 0; 00403 struct ast_audiohook *audiohook = NULL; 00404 00405 /* Drop any spies */ 00406 while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->spy_list, list))) { 00407 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE); 00408 } 00409 00410 /* Drop any whispering sources */ 00411 while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->whisper_list, list))) { 00412 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE); 00413 } 00414 00415 /* Drop any manipulaters */ 00416 while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->manipulate_list, list))) { 00417 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE); 00418 audiohook->manipulate_callback(audiohook, NULL, NULL, 0); 00419 } 00420 00421 /* Drop translation paths if present */ 00422 for (i = 0; i < 2; i++) { 00423 if (audiohook_list->in_translate[i].trans_pvt) 00424 ast_translator_free_path(audiohook_list->in_translate[i].trans_pvt); 00425 if (audiohook_list->out_translate[i].trans_pvt) 00426 ast_translator_free_path(audiohook_list->out_translate[i].trans_pvt); 00427 } 00428 00429 /* Free ourselves */ 00430 ast_free(audiohook_list); 00431 00432 return 0; 00433 }
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 491 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, chan, find_audiohook_by_source(), and ast_audiohook::status.
Referenced by handle_cli_mixmonitor(), and stop_mixmonitor_exec().
00492 { 00493 struct ast_audiohook *audiohook = NULL; 00494 00495 ast_channel_lock(chan); 00496 00497 /* Ensure the channel has audiohooks on it */ 00498 if (!chan->audiohooks) { 00499 ast_channel_unlock(chan); 00500 return -1; 00501 } 00502 00503 audiohook = find_audiohook_by_source(chan->audiohooks, source); 00504 00505 ast_channel_unlock(chan); 00506 00507 if (audiohook && audiohook->status != AST_AUDIOHOOK_STATUS_DONE) 00508 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_SHUTDOWN); 00509 00510 return (audiohook ? 0 : -1); 00511 }
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(), launch_monitor_thread(), 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 462 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().
00463 { 00464 struct ast_audiohook *audiohook; 00465 enum ast_audiohook_status oldstatus; 00466 00467 if (!old_chan->audiohooks || !(audiohook = find_audiohook_by_source(old_chan->audiohooks, source))) { 00468 return; 00469 } 00470 00471 /* By locking both channels and the audiohook, we can assure that 00472 * another thread will not have a chance to read the audiohook's status 00473 * as done, even though ast_audiohook_remove signals the trigger 00474 * condition. 00475 */ 00476 ast_audiohook_lock(audiohook); 00477 oldstatus = audiohook->status; 00478 00479 ast_audiohook_remove(old_chan, audiohook); 00480 ast_audiohook_attach(new_chan, audiohook); 00481 00482 audiohook->status = oldstatus; 00483 ast_audiohook_unlock(audiohook); 00484 }
struct ast_frame* ast_audiohook_read_frame | ( | struct ast_audiohook * | audiohook, | |
size_t | samples, | |||
enum ast_audiohook_direction | direction, | |||
int | 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 295 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().
00296 { 00297 struct ast_frame *read_frame = NULL, *final_frame = NULL; 00298 00299 if (!(read_frame = (direction == AST_AUDIOHOOK_DIRECTION_BOTH ? audiohook_read_frame_both(audiohook, samples) : audiohook_read_frame_single(audiohook, samples, direction)))) 00300 return NULL; 00301 00302 /* If they don't want signed linear back out, we'll have to send it through the translation path */ 00303 if (format != AST_FORMAT_SLINEAR) { 00304 /* Rebuild translation path if different format then previously */ 00305 if (audiohook->format != format) { 00306 if (audiohook->trans_pvt) { 00307 ast_translator_free_path(audiohook->trans_pvt); 00308 audiohook->trans_pvt = NULL; 00309 } 00310 /* 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 */ 00311 if (!(audiohook->trans_pvt = ast_translator_build_path(format, AST_FORMAT_SLINEAR))) { 00312 ast_frfree(read_frame); 00313 return NULL; 00314 } 00315 } 00316 /* Convert to requested format, and allow the read in frame to be freed */ 00317 final_frame = ast_translate(audiohook->trans_pvt, read_frame, 1); 00318 } else { 00319 final_frame = read_frame; 00320 } 00321 00322 return final_frame; 00323 }
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 523 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, chan, 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().
00524 { 00525 ast_channel_lock(chan); 00526 00527 if (!chan->audiohooks) { 00528 ast_channel_unlock(chan); 00529 return -1; 00530 } 00531 00532 if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY) 00533 AST_LIST_REMOVE(&chan->audiohooks->spy_list, audiohook, list); 00534 else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER) 00535 AST_LIST_REMOVE(&chan->audiohooks->whisper_list, audiohook, list); 00536 else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) 00537 AST_LIST_REMOVE(&chan->audiohooks->manipulate_list, audiohook, list); 00538 00539 ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE); 00540 00541 ast_channel_unlock(chan); 00542 00543 return 0; 00544 }
void ast_audiohook_trigger_wait | ( | struct ast_audiohook * | audiohook | ) |
Wait for audiohook trigger to be triggered.
audiohook | Audiohook to wait on |
Definition at line 748 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().
00749 { 00750 struct timeval wait; 00751 struct timespec ts; 00752 00753 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000)); 00754 ts.tv_sec = wait.tv_sec; 00755 ts.tv_nsec = wait.tv_usec * 1000; 00756 00757 ast_cond_timedwait(&audiohook->trigger, &audiohook->lock, &ts); 00758 00759 return; 00760 }
void ast_audiohook_update_status | ( | struct ast_audiohook * | audiohook, | |
enum ast_audiohook_status | status | |||
) |
Update audiohook's status.
audiohook | status enum | |
audiohook | Audiohook structure |
Definition at line 369 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().
00370 { 00371 ast_audiohook_lock(audiohook); 00372 if (audiohook->status != AST_AUDIOHOOK_STATUS_DONE) { 00373 audiohook->status = status; 00374 ast_cond_signal(&audiohook->trigger); 00375 } 00376 ast_audiohook_unlock(audiohook); 00377 }
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 1008 of file audiohook.c.
References AST_AUDIOHOOK_DIRECTION_BOTH, AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, audiohook_volume_get(), chan, audiohook_volume::read_adjustment, and audiohook_volume::write_adjustment.
01009 { 01010 struct audiohook_volume *audiohook_volume = NULL; 01011 01012 /* Attempt to find the audiohook volume information, and create an audiohook if none exists */ 01013 if (!(audiohook_volume = audiohook_volume_get(chan, 1))) { 01014 return -1; 01015 } 01016 01017 /* Based on the direction change the specific adjustment value */ 01018 if (direction == AST_AUDIOHOOK_DIRECTION_READ || direction == AST_AUDIOHOOK_DIRECTION_BOTH) { 01019 audiohook_volume->read_adjustment += volume; 01020 } 01021 if (direction == AST_AUDIOHOOK_DIRECTION_WRITE || direction == AST_AUDIOHOOK_DIRECTION_BOTH) { 01022 audiohook_volume->write_adjustment += volume; 01023 } 01024 01025 return 0; 01026 }
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 982 of file audiohook.c.
References AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, audiohook_volume_get(), chan, audiohook_volume::read_adjustment, and audiohook_volume::write_adjustment.
00983 { 00984 struct audiohook_volume *audiohook_volume = NULL; 00985 int adjustment = 0; 00986 00987 /* Attempt to find the audiohook volume information, but do not create it as we only want to look at the values */ 00988 if (!(audiohook_volume = audiohook_volume_get(chan, 0))) { 00989 return 0; 00990 } 00991 00992 /* Grab the adjustment value based on direction given */ 00993 if (direction == AST_AUDIOHOOK_DIRECTION_READ) { 00994 adjustment = audiohook_volume->read_adjustment; 00995 } else if (direction == AST_AUDIOHOOK_DIRECTION_WRITE) { 00996 adjustment = audiohook_volume->write_adjustment; 00997 } 00998 00999 return adjustment; 01000 }
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 957 of file audiohook.c.
References AST_AUDIOHOOK_DIRECTION_BOTH, AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, audiohook_volume_get(), chan, audiohook_volume::read_adjustment, and audiohook_volume::write_adjustment.
00958 { 00959 struct audiohook_volume *audiohook_volume = NULL; 00960 00961 /* Attempt to find the audiohook volume information, but only create it if we are not setting the adjustment value to zero */ 00962 if (!(audiohook_volume = audiohook_volume_get(chan, (volume ? 1 : 0)))) { 00963 return -1; 00964 } 00965 00966 /* Now based on the direction set the proper value */ 00967 if (direction == AST_AUDIOHOOK_DIRECTION_READ || direction == AST_AUDIOHOOK_DIRECTION_BOTH) { 00968 audiohook_volume->read_adjustment = volume; 00969 } 00970 if (direction == AST_AUDIOHOOK_DIRECTION_WRITE || direction == AST_AUDIOHOOK_DIRECTION_BOTH) { 00971 audiohook_volume->write_adjustment = volume; 00972 } 00973 00974 return 0; 00975 }
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_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_log(), ast_slinfactory_available(), ast_slinfactory_feed(), ast_slinfactory_flush(), ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), 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 00131 /* Update last feeding time to be current */ 00132 *rwtime = ast_tvnow(); 00133 00134 our_factory_samples = ast_slinfactory_available(factory); 00135 our_factory_ms = ast_tvdiff_ms(*rwtime, previous_time) + (our_factory_samples / 8); 00136 other_factory_samples = ast_slinfactory_available(other_factory); 00137 other_factory_ms = other_factory_samples / 8; 00138 00139 if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC) && other_factory_samples && (our_factory_ms - other_factory_ms > AST_AUDIOHOOK_SYNC_TOLERANCE)) { 00140 if (option_debug) 00141 ast_log(LOG_DEBUG, "Flushing audiohook %p so it remains in sync\n", audiohook); 00142 ast_slinfactory_flush(factory); 00143 ast_slinfactory_flush(other_factory); 00144 } 00145 00146 if (ast_test_flag(audiohook, AST_AUDIOHOOK_SMALL_QUEUE) && (our_factory_samples > 640 || other_factory_samples > 640)) { 00147 if (option_debug) { 00148 ast_log(LOG_DEBUG, "Audiohook %p has stale audio in its factories. Flushing them both\n", audiohook); 00149 } 00150 ast_slinfactory_flush(factory); 00151 ast_slinfactory_flush(other_factory); 00152 } 00153 00154 /* Write frame out to respective factory */ 00155 ast_slinfactory_feed(factory, frame); 00156 00157 /* If we need to notify the respective handler of this audiohook, do so */ 00158 if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_READ) && (direction == AST_AUDIOHOOK_DIRECTION_READ)) { 00159 ast_cond_signal(&audiohook->trigger); 00160 } else if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_WRITE) && (direction == AST_AUDIOHOOK_DIRECTION_WRITE)) { 00161 ast_cond_signal(&audiohook->trigger); 00162 } else if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC)) { 00163 ast_cond_signal(&audiohook->trigger); 00164 } 00165 00166 return 0; 00167 }
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 733 of file audiohook.c.
References AST_FRAME_DTMF, AST_FRAME_VOICE, audio_audiohook_write_list(), chan, dtmf_audiohook_write_list(), and ast_frame::frametype.
Referenced by __ast_read(), and ast_write().
00734 { 00735 /* Pass off frame to it's respective list write function */ 00736 if (frame->frametype == AST_FRAME_VOICE) 00737 return audio_audiohook_write_list(chan, audiohook_list, direction, frame); 00738 else if (frame->frametype == AST_FRAME_DTMF) 00739 return dtmf_audiohook_write_list(chan, audiohook_list, direction, frame); 00740 else 00741 return frame; 00742 }
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 763 of file audiohook.c.
References AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_channel::audiohooks, chan, 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().
00764 { 00765 int count = 0; 00766 struct ast_audiohook *ah = NULL; 00767 00768 if (!chan->audiohooks) 00769 return -1; 00770 00771 switch (type) { 00772 case AST_AUDIOHOOK_TYPE_SPY: 00773 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->spy_list, ah, list) { 00774 if (!strcmp(ah->source, source)) { 00775 count++; 00776 } 00777 } 00778 AST_LIST_TRAVERSE_SAFE_END; 00779 break; 00780 case AST_AUDIOHOOK_TYPE_WHISPER: 00781 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->whisper_list, ah, list) { 00782 if (!strcmp(ah->source, source)) { 00783 count++; 00784 } 00785 } 00786 AST_LIST_TRAVERSE_SAFE_END; 00787 break; 00788 case AST_AUDIOHOOK_TYPE_MANIPULATE: 00789 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->manipulate_list, ah, list) { 00790 if (!strcmp(ah->source, source)) { 00791 count++; 00792 } 00793 } 00794 AST_LIST_TRAVERSE_SAFE_END; 00795 break; 00796 default: 00797 ast_log(LOG_DEBUG, "Invalid audiohook type supplied, (%d)\n", type); 00798 return -1; 00799 } 00800 00801 return count; 00802 }
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 805 of file audiohook.c.
References AST_AUDIOHOOK_STATUS_RUNNING, AST_AUDIOHOOK_TYPE_MANIPULATE, AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_channel::audiohooks, chan, 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().
00806 { 00807 int count = 0; 00808 struct ast_audiohook *ah = NULL; 00809 if (!chan->audiohooks) 00810 return -1; 00811 00812 switch (type) { 00813 case AST_AUDIOHOOK_TYPE_SPY: 00814 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->spy_list, ah, list) { 00815 if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING)) 00816 count++; 00817 } 00818 AST_LIST_TRAVERSE_SAFE_END; 00819 break; 00820 case AST_AUDIOHOOK_TYPE_WHISPER: 00821 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->whisper_list, ah, list) { 00822 if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING)) 00823 count++; 00824 } 00825 AST_LIST_TRAVERSE_SAFE_END; 00826 break; 00827 case AST_AUDIOHOOK_TYPE_MANIPULATE: 00828 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->audiohooks->manipulate_list, ah, list) { 00829 if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING)) 00830 count++; 00831 } 00832 AST_LIST_TRAVERSE_SAFE_END; 00833 break; 00834 default: 00835 ast_log(LOG_DEBUG, "Invalid audiohook type supplied, (%d)\n", type); 00836 return -1; 00837 } 00838 return count; 00839 }