Index: include/asterisk/audiohook.h =================================================================== --- include/asterisk/audiohook.h (revision 115587) +++ include/asterisk/audiohook.h (working copy) @@ -44,6 +44,7 @@ AST_AUDIOHOOK_STATUS_RUNNING, /*!< Audiohook is running on a channel */ AST_AUDIOHOOK_STATUS_SHUTDOWN, /*!< Audiohook is being shutdown */ AST_AUDIOHOOK_STATUS_DONE, /*!< Audiohook has shutdown and is not running on a channel any longer */ + AST_AUDIOHOOK_STATUS_INACTIVE, /*!< Audiohook is attached to a channel but we want to ignore its presence */ }; enum ast_audiohook_direction { @@ -136,6 +137,18 @@ */ int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook); +/*! \brief Deactivate an attached audiohook + * \param audiohook Audiohook structure + * \return Returns 0 on success, -1 on failure + */ +int ast_audiohook_deactivate(struct ast_audiohook *audiohook); + +/*! \brief Reactivate a deactivated attached audiohook + * \param audiohook Audiohook structure + * \return Returns 0 on success, -1 on failure + */ +int ast_audiohook_reactivate(struct ast_audiohook *audiohook); + /*! \brief Detach audiohook from channel * \param audiohook Audiohook structure * \return Returns 0 on success, -1 on failure Index: main/audiohook.c =================================================================== --- main/audiohook.c (revision 115587) +++ main/audiohook.c (working copy) @@ -455,6 +455,24 @@ return (audiohook ? 0 : -1); } +int ast_audiohook_deactivate(struct ast_audiohook *audiohook) +{ + if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) + return -1; + + audiohook->status = AST_AUDIOHOOK_STATUS_INACTIVE; + return 0; +} + +int ast_audiohook_reactivate(struct ast_audiohook *audiohook) +{ + if (audiohook->status != AST_AUDIOHOOK_STATUS_INACTIVE) + return -1; + + audiohook->status = AST_AUDIOHOOK_STATUS_RUNNING; + return 0; +} + /*! * \brief Remove an audiohook from a specified channel * @@ -504,7 +522,8 @@ AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) { ast_audiohook_lock(audiohook); - if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) { + if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING && + audiohook->status != AST_AUDIOHOOK_STATUS_INACTIVE) { AST_LIST_REMOVE_CURRENT(list); audiohook->status = AST_AUDIOHOOK_STATUS_DONE; ast_audiohook_unlock(audiohook); @@ -551,14 +570,16 @@ /* Queue up signed linear frame to each spy */ AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) { ast_audiohook_lock(audiohook); - if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) { + if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING && + audiohook->status != AST_AUDIOHOOK_STATUS_INACTIVE) { AST_LIST_REMOVE_CURRENT(list); audiohook->status = AST_AUDIOHOOK_STATUS_DONE; ast_cond_signal(&audiohook->trigger); ast_audiohook_unlock(audiohook); continue; } - ast_audiohook_write_frame(audiohook, direction, middle_frame); + if (audiohook->status == AST_AUDIOHOOK_STATUS_RUNNING) + ast_audiohook_write_frame(audiohook, direction, middle_frame); ast_audiohook_unlock(audiohook); } AST_LIST_TRAVERSE_SAFE_END @@ -570,14 +591,15 @@ memset(&combine_buf, 0, sizeof(combine_buf)); AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->whisper_list, audiohook, list) { ast_audiohook_lock(audiohook); - if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) { + if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING && + audiohook->status != AST_AUDIOHOOK_STATUS_INACTIVE) { AST_LIST_REMOVE_CURRENT(list); audiohook->status = AST_AUDIOHOOK_STATUS_DONE; ast_cond_signal(&audiohook->trigger); ast_audiohook_unlock(audiohook); continue; } - if (ast_slinfactory_available(&audiohook->write_factory) >= samples && ast_slinfactory_read(&audiohook->write_factory, read_buf, samples)) { + if (audiohook->status == AST_AUDIOHOOK_STATUS_RUNNING && ast_slinfactory_available(&audiohook->write_factory) >= samples && ast_slinfactory_read(&audiohook->write_factory, read_buf, samples)) { /* Take audio from this whisper source and combine it into our main buffer */ for (i = 0, data1 = combine_buf, data2 = read_buf; i < samples; i++, data1++, data2++) ast_slinear_saturated_add(data1, data2); @@ -595,7 +617,8 @@ if (!AST_LIST_EMPTY(&audiohook_list->manipulate_list)) { AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) { ast_audiohook_lock(audiohook); - if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) { + if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING && + audiohook->status != AST_AUDIOHOOK_STATUS_INACTIVE) { AST_LIST_REMOVE_CURRENT(list); audiohook->status = AST_AUDIOHOOK_STATUS_DONE; ast_audiohook_unlock(audiohook); @@ -604,7 +627,8 @@ continue; } /* Feed in frame to manipulation */ - audiohook->manipulate_callback(audiohook, chan, middle_frame, direction); + if (audiohook->status == AST_AUDIOHOOK_STATUS_RUNNING) + audiohook->manipulate_callback(audiohook, chan, middle_frame, direction); ast_audiohook_unlock(audiohook); } AST_LIST_TRAVERSE_SAFE_END