audiohook.c 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2007, Digium, Inc.
  5. *
  6. * Joshua Colp <jcolp@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*! \file
  19. *
  20. * \brief Audiohooks Architecture
  21. *
  22. * \author Joshua Colp <jcolp@digium.com>
  23. */
  24. /*** MODULEINFO
  25. <support_level>core</support_level>
  26. ***/
  27. #include "asterisk.h"
  28. #include <signal.h>
  29. #include "asterisk/channel.h"
  30. #include "asterisk/utils.h"
  31. #include "asterisk/lock.h"
  32. #include "asterisk/audiohook.h"
  33. #include "asterisk/slinfactory.h"
  34. #include "asterisk/frame.h"
  35. #include "asterisk/translate.h"
  36. #include "asterisk/format_cache.h"
  37. #include "asterisk/test.h"
  38. #define AST_AUDIOHOOK_SYNC_TOLERANCE 100 /*!< Tolerance in milliseconds for audiohooks synchronization */
  39. #define AST_AUDIOHOOK_SMALL_QUEUE_TOLERANCE 100 /*!< When small queue is enabled, this is the maximum amount of audio that can remain queued at a time. */
  40. #define AST_AUDIOHOOK_LONG_QUEUE_TOLERANCE 500 /*!< Otheriwise we still don't want the queue to grow indefinitely */
  41. #define DEFAULT_INTERNAL_SAMPLE_RATE 8000
  42. struct ast_audiohook_translate {
  43. struct ast_trans_pvt *trans_pvt;
  44. struct ast_format *format;
  45. };
  46. struct ast_audiohook_list {
  47. /* If all the audiohooks in this list are capable
  48. * of processing slinear at any sample rate, this
  49. * variable will be set and the sample rate will
  50. * be preserved during ast_audiohook_write_list()*/
  51. int native_slin_compatible;
  52. int list_internal_samp_rate;/*!< Internal sample rate used when writing to the audiohook list */
  53. struct ast_audiohook_translate in_translate[2];
  54. struct ast_audiohook_translate out_translate[2];
  55. AST_LIST_HEAD_NOLOCK(, ast_audiohook) spy_list;
  56. AST_LIST_HEAD_NOLOCK(, ast_audiohook) whisper_list;
  57. AST_LIST_HEAD_NOLOCK(, ast_audiohook) manipulate_list;
  58. };
  59. static int audiohook_set_internal_rate(struct ast_audiohook *audiohook, int rate, int reset)
  60. {
  61. struct ast_format *slin;
  62. if (audiohook->hook_internal_samp_rate == rate) {
  63. return 0;
  64. }
  65. audiohook->hook_internal_samp_rate = rate;
  66. slin = ast_format_cache_get_slin_by_rate(rate);
  67. /* Setup the factories that are needed for this audiohook type */
  68. switch (audiohook->type) {
  69. case AST_AUDIOHOOK_TYPE_SPY:
  70. case AST_AUDIOHOOK_TYPE_WHISPER:
  71. if (reset) {
  72. ast_slinfactory_destroy(&audiohook->read_factory);
  73. ast_slinfactory_destroy(&audiohook->write_factory);
  74. }
  75. ast_slinfactory_init_with_format(&audiohook->read_factory, slin);
  76. ast_slinfactory_init_with_format(&audiohook->write_factory, slin);
  77. break;
  78. default:
  79. break;
  80. }
  81. return 0;
  82. }
  83. int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source, enum ast_audiohook_init_flags init_flags)
  84. {
  85. /* Need to keep the type and source */
  86. audiohook->type = type;
  87. audiohook->source = source;
  88. /* Initialize lock that protects our audiohook */
  89. ast_mutex_init(&audiohook->lock);
  90. ast_cond_init(&audiohook->trigger, NULL);
  91. audiohook->init_flags = init_flags;
  92. /* Set direction to BOTH so that we feed frames in both directions */
  93. audiohook->direction = AST_AUDIOHOOK_DIRECTION_BOTH;
  94. /* initialize internal rate at 8khz, this will adjust if necessary */
  95. audiohook_set_internal_rate(audiohook, DEFAULT_INTERNAL_SAMPLE_RATE, 0);
  96. /* Since we are just starting out... this audiohook is new */
  97. ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_NEW);
  98. return 0;
  99. }
  100. int ast_audiohook_destroy(struct ast_audiohook *audiohook)
  101. {
  102. /* Drop the factories used by this audiohook type */
  103. switch (audiohook->type) {
  104. case AST_AUDIOHOOK_TYPE_SPY:
  105. case AST_AUDIOHOOK_TYPE_WHISPER:
  106. ast_slinfactory_destroy(&audiohook->read_factory);
  107. ast_slinfactory_destroy(&audiohook->write_factory);
  108. break;
  109. default:
  110. break;
  111. }
  112. /* Destroy translation path if present */
  113. if (audiohook->trans_pvt)
  114. ast_translator_free_path(audiohook->trans_pvt);
  115. ao2_cleanup(audiohook->format);
  116. /* Lock and trigger be gone! */
  117. ast_cond_destroy(&audiohook->trigger);
  118. ast_mutex_destroy(&audiohook->lock);
  119. return 0;
  120. }
  121. int ast_audiohook_set_frame_feed_direction(struct ast_audiohook *audiohook, enum ast_audiohook_direction direction)
  122. {
  123. /* Only set the direction on new audiohooks */
  124. if (audiohook->status != AST_AUDIOHOOK_STATUS_NEW) {
  125. ast_debug(3, "Can not set direction on attached Audiohook %p\n", audiohook);
  126. return -1;
  127. }
  128. audiohook->direction = direction;
  129. return 0;
  130. }
  131. #define SHOULD_MUTE(hook, dir) \
  132. ((ast_test_flag(hook, AST_AUDIOHOOK_MUTE_READ) && (dir == AST_AUDIOHOOK_DIRECTION_READ)) || \
  133. (ast_test_flag(hook, AST_AUDIOHOOK_MUTE_WRITE) && (dir == AST_AUDIOHOOK_DIRECTION_WRITE)) || \
  134. (ast_test_flag(hook, AST_AUDIOHOOK_MUTE_READ | AST_AUDIOHOOK_MUTE_WRITE) == (AST_AUDIOHOOK_MUTE_READ | AST_AUDIOHOOK_MUTE_WRITE)))
  135. int ast_audiohook_write_frame(struct ast_audiohook *audiohook, enum ast_audiohook_direction direction, struct ast_frame *frame)
  136. {
  137. struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
  138. struct ast_slinfactory *other_factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->write_factory : &audiohook->read_factory);
  139. struct timeval *rwtime = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_time : &audiohook->write_time), previous_time = *rwtime;
  140. int our_factory_samples;
  141. int our_factory_ms;
  142. int other_factory_samples;
  143. int other_factory_ms;
  144. /* Don't feed the frame if we are set to read and this is a write frame or if set to
  145. write and this is a read frame as we don't want it. Plus, it can cause mis-resampling
  146. if the READ and WRITE frames have different bitrates */
  147. if (audiohook->direction != AST_AUDIOHOOK_DIRECTION_BOTH && audiohook->direction != direction) {
  148. return 0;
  149. }
  150. /* Update last feeding time to be current */
  151. *rwtime = ast_tvnow();
  152. our_factory_samples = ast_slinfactory_available(factory);
  153. our_factory_ms = ast_tvdiff_ms(*rwtime, previous_time) + (our_factory_samples / (audiohook->hook_internal_samp_rate / 1000));
  154. other_factory_samples = ast_slinfactory_available(other_factory);
  155. other_factory_ms = other_factory_samples / (audiohook->hook_internal_samp_rate / 1000);
  156. if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC) && (our_factory_ms - other_factory_ms > AST_AUDIOHOOK_SYNC_TOLERANCE)) {
  157. ast_debug(4, "Flushing audiohook %p so it remains in sync\n", audiohook);
  158. ast_slinfactory_flush(factory);
  159. ast_slinfactory_flush(other_factory);
  160. }
  161. if (ast_test_flag(audiohook, AST_AUDIOHOOK_SMALL_QUEUE) && ((our_factory_ms > AST_AUDIOHOOK_SMALL_QUEUE_TOLERANCE) || (other_factory_ms > AST_AUDIOHOOK_SMALL_QUEUE_TOLERANCE))) {
  162. ast_debug(4, "Audiohook %p has stale audio in its factories. Flushing them both\n", audiohook);
  163. ast_slinfactory_flush(factory);
  164. ast_slinfactory_flush(other_factory);
  165. } else if ((our_factory_ms > AST_AUDIOHOOK_LONG_QUEUE_TOLERANCE) || (other_factory_ms > AST_AUDIOHOOK_LONG_QUEUE_TOLERANCE)) {
  166. ast_debug(4, "Audiohook %p has stale audio in its factories. Flushing them both\n", audiohook);
  167. ast_slinfactory_flush(factory);
  168. ast_slinfactory_flush(other_factory);
  169. }
  170. /* Write frame out to respective factory */
  171. ast_slinfactory_feed(factory, frame);
  172. /* If we need to notify the respective handler of this audiohook, do so */
  173. if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_READ) && (direction == AST_AUDIOHOOK_DIRECTION_READ)) {
  174. ast_cond_signal(&audiohook->trigger);
  175. } else if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_WRITE) && (direction == AST_AUDIOHOOK_DIRECTION_WRITE)) {
  176. ast_cond_signal(&audiohook->trigger);
  177. } else if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC)) {
  178. ast_cond_signal(&audiohook->trigger);
  179. }
  180. return 0;
  181. }
  182. static struct ast_frame *audiohook_read_frame_single(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction)
  183. {
  184. struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
  185. int vol = (direction == AST_AUDIOHOOK_DIRECTION_READ ? audiohook->options.read_volume : audiohook->options.write_volume);
  186. short buf[samples];
  187. struct ast_frame frame = {
  188. .frametype = AST_FRAME_VOICE,
  189. .subclass.format = ast_format_cache_get_slin_by_rate(audiohook->hook_internal_samp_rate),
  190. .data.ptr = buf,
  191. .datalen = sizeof(buf),
  192. .samples = samples,
  193. };
  194. /* Ensure the factory is able to give us the samples we want */
  195. if (samples > ast_slinfactory_available(factory)) {
  196. return NULL;
  197. }
  198. /* Read data in from factory */
  199. if (!ast_slinfactory_read(factory, buf, samples)) {
  200. return NULL;
  201. }
  202. if (SHOULD_MUTE(audiohook, direction)) {
  203. /* Swap frame data for zeros if mute is required */
  204. ast_frame_clear(&frame);
  205. } else if (vol) {
  206. /* If a volume adjustment needs to be applied apply it */
  207. ast_frame_adjust_volume(&frame, vol);
  208. }
  209. return ast_frdup(&frame);
  210. }
  211. static struct ast_frame *audiohook_read_frame_both(struct ast_audiohook *audiohook, size_t samples, struct ast_frame **read_reference, struct ast_frame **write_reference)
  212. {
  213. int count;
  214. int usable_read;
  215. int usable_write;
  216. short adjust_value;
  217. short buf1[samples];
  218. short buf2[samples];
  219. short *read_buf = NULL;
  220. short *write_buf = NULL;
  221. struct ast_frame frame = {
  222. .frametype = AST_FRAME_VOICE,
  223. .datalen = sizeof(buf1),
  224. .samples = samples,
  225. };
  226. /* Make sure both factories have the required samples */
  227. usable_read = (ast_slinfactory_available(&audiohook->read_factory) >= samples ? 1 : 0);
  228. usable_write = (ast_slinfactory_available(&audiohook->write_factory) >= samples ? 1 : 0);
  229. if (!usable_read && !usable_write) {
  230. /* If both factories are unusable bail out */
  231. ast_debug(3, "Read factory %p and write factory %p both fail to provide %zu samples\n", &audiohook->read_factory, &audiohook->write_factory, samples);
  232. return NULL;
  233. }
  234. /* If we want to provide only a read factory make sure we aren't waiting for other audio */
  235. if (usable_read && !usable_write && (ast_tvdiff_ms(ast_tvnow(), audiohook->write_time) < (samples/8)*2)) {
  236. ast_debug(3, "Write factory %p was pretty quick last time, waiting for them.\n", &audiohook->write_factory);
  237. return NULL;
  238. }
  239. /* If we want to provide only a write factory make sure we aren't waiting for other audio */
  240. if (usable_write && !usable_read && (ast_tvdiff_ms(ast_tvnow(), audiohook->read_time) < (samples/8)*2)) {
  241. ast_debug(3, "Read factory %p was pretty quick last time, waiting for them.\n", &audiohook->read_factory);
  242. return NULL;
  243. }
  244. /* Start with the read factory... if there are enough samples, read them in */
  245. if (usable_read) {
  246. if (ast_slinfactory_read(&audiohook->read_factory, buf1, samples)) {
  247. read_buf = buf1;
  248. if ((ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_READ))) {
  249. /* Clear the frame data if we are muting */
  250. memset(buf1, 0, sizeof(buf1));
  251. } else if (audiohook->options.read_volume) {
  252. /* Adjust read volume if need be */
  253. adjust_value = abs(audiohook->options.read_volume);
  254. for (count = 0; count < samples; count++) {
  255. if (audiohook->options.read_volume > 0) {
  256. ast_slinear_saturated_multiply(&buf1[count], &adjust_value);
  257. } else if (audiohook->options.read_volume < 0) {
  258. ast_slinear_saturated_divide(&buf1[count], &adjust_value);
  259. }
  260. }
  261. }
  262. }
  263. } else {
  264. ast_debug(1, "Failed to get %d samples from read factory %p\n", (int)samples, &audiohook->read_factory);
  265. }
  266. /* Move on to the write factory... if there are enough samples, read them in */
  267. if (usable_write) {
  268. if (ast_slinfactory_read(&audiohook->write_factory, buf2, samples)) {
  269. write_buf = buf2;
  270. if ((ast_test_flag(audiohook, AST_AUDIOHOOK_MUTE_WRITE))) {
  271. /* Clear the frame data if we are muting */
  272. memset(buf2, 0, sizeof(buf2));
  273. } else if (audiohook->options.write_volume) {
  274. /* Adjust write volume if need be */
  275. adjust_value = abs(audiohook->options.write_volume);
  276. for (count = 0; count < samples; count++) {
  277. if (audiohook->options.write_volume > 0) {
  278. ast_slinear_saturated_multiply(&buf2[count], &adjust_value);
  279. } else if (audiohook->options.write_volume < 0) {
  280. ast_slinear_saturated_divide(&buf2[count], &adjust_value);
  281. }
  282. }
  283. }
  284. }
  285. } else {
  286. ast_debug(3, "Failed to get %d samples from write factory %p\n", (int)samples, &audiohook->write_factory);
  287. }
  288. frame.subclass.format = ast_format_cache_get_slin_by_rate(audiohook->hook_internal_samp_rate);
  289. /* Should we substitute silence if one side lacks audio? */
  290. if ((ast_test_flag(audiohook, AST_AUDIOHOOK_SUBSTITUTE_SILENCE))) {
  291. if (read_reference && !read_buf && write_buf) {
  292. read_buf = buf1;
  293. memset(buf1, 0, sizeof(buf1));
  294. } else if (write_reference && read_buf && !write_buf) {
  295. write_buf = buf2;
  296. memset(buf2, 0, sizeof(buf2));
  297. }
  298. }
  299. /* Basically we figure out which buffer to use... and if mixing can be done here */
  300. if (read_buf && read_reference) {
  301. frame.data.ptr = read_buf;
  302. *read_reference = ast_frdup(&frame);
  303. }
  304. if (write_buf && write_reference) {
  305. frame.data.ptr = write_buf;
  306. *write_reference = ast_frdup(&frame);
  307. }
  308. /* Make the correct buffer part of the built frame, so it gets duplicated. */
  309. if (read_buf) {
  310. frame.data.ptr = read_buf;
  311. if (write_buf) {
  312. for (count = 0; count < samples; count++) {
  313. ast_slinear_saturated_add(read_buf++, write_buf++);
  314. }
  315. }
  316. } else if (write_buf) {
  317. frame.data.ptr = write_buf;
  318. } else {
  319. return NULL;
  320. }
  321. /* Yahoo, a combined copy of the audio! */
  322. return ast_frdup(&frame);
  323. }
  324. static struct ast_frame *audiohook_read_frame_helper(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, struct ast_format *format, struct ast_frame **read_reference, struct ast_frame **write_reference)
  325. {
  326. struct ast_frame *read_frame = NULL, *final_frame = NULL;
  327. struct ast_format *slin;
  328. /*
  329. * Update the rate if compatibility mode is turned off or if it is
  330. * turned on and the format rate is higher than the current rate.
  331. *
  332. * This makes it so any unnecessary rate switching/resetting does
  333. * not take place and also any associated audiohook_list's internal
  334. * sample rate maintains the highest sample rate between hooks.
  335. */
  336. if (!ast_test_flag(audiohook, AST_AUDIOHOOK_COMPATIBLE) ||
  337. (ast_test_flag(audiohook, AST_AUDIOHOOK_COMPATIBLE) &&
  338. ast_format_get_sample_rate(format) > audiohook->hook_internal_samp_rate)) {
  339. audiohook_set_internal_rate(audiohook, ast_format_get_sample_rate(format), 1);
  340. }
  341. /* If the sample rate of the requested format differs from that of the underlying audiohook
  342. * sample rate determine how many samples we actually need to get from the audiohook. This
  343. * needs to occur as the signed linear factory stores them at the rate of the audiohook.
  344. * We do this by determining the duration of audio they've requested and then determining
  345. * how many samples that would be in the audiohook format.
  346. */
  347. if (ast_format_get_sample_rate(format) != audiohook->hook_internal_samp_rate) {
  348. samples = (audiohook->hook_internal_samp_rate / 1000) * (samples / (ast_format_get_sample_rate(format) / 1000));
  349. }
  350. if (!(read_frame = (direction == AST_AUDIOHOOK_DIRECTION_BOTH ?
  351. audiohook_read_frame_both(audiohook, samples, read_reference, write_reference) :
  352. audiohook_read_frame_single(audiohook, samples, direction)))) {
  353. return NULL;
  354. }
  355. slin = ast_format_cache_get_slin_by_rate(audiohook->hook_internal_samp_rate);
  356. /* If they don't want signed linear back out, we'll have to send it through the translation path */
  357. if (ast_format_cmp(format, slin) != AST_FORMAT_CMP_EQUAL) {
  358. /* Rebuild translation path if different format then previously */
  359. if (ast_format_cmp(format, audiohook->format) == AST_FORMAT_CMP_NOT_EQUAL) {
  360. if (audiohook->trans_pvt) {
  361. ast_translator_free_path(audiohook->trans_pvt);
  362. audiohook->trans_pvt = NULL;
  363. }
  364. /* 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 */
  365. if (!(audiohook->trans_pvt = ast_translator_build_path(format, slin))) {
  366. ast_frfree(read_frame);
  367. return NULL;
  368. }
  369. ao2_replace(audiohook->format, format);
  370. }
  371. /* Convert to requested format, and allow the read in frame to be freed */
  372. final_frame = ast_translate(audiohook->trans_pvt, read_frame, 1);
  373. } else {
  374. final_frame = read_frame;
  375. }
  376. return final_frame;
  377. }
  378. struct ast_frame *ast_audiohook_read_frame(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, struct ast_format *format)
  379. {
  380. return audiohook_read_frame_helper(audiohook, samples, direction, format, NULL, NULL);
  381. }
  382. struct ast_frame *ast_audiohook_read_frame_all(struct ast_audiohook *audiohook, size_t samples, struct ast_format *format, struct ast_frame **read_frame, struct ast_frame **write_frame)
  383. {
  384. return audiohook_read_frame_helper(audiohook, samples, AST_AUDIOHOOK_DIRECTION_BOTH, format, read_frame, write_frame);
  385. }
  386. static void audiohook_list_set_samplerate_compatibility(struct ast_audiohook_list *audiohook_list)
  387. {
  388. struct ast_audiohook *ah = NULL;
  389. /*
  390. * Anytime the samplerate compatibility is set (attach/remove an audiohook) the
  391. * list's internal sample rate needs to be reset so that the next time processing
  392. * through write_list, if needed, it will get updated to the correct rate.
  393. *
  394. * A list's internal rate always chooses the higher between its own rate and a
  395. * given rate. If the current rate is being driven by an audiohook that wanted a
  396. * higher rate then when this audiohook is removed the list's rate would remain
  397. * at that level when it should be lower, and with no way to lower it since any
  398. * rate compared against it would be lower.
  399. *
  400. * By setting it back to the lowest rate it can recalulate the new highest rate.
  401. */
  402. audiohook_list->list_internal_samp_rate = DEFAULT_INTERNAL_SAMPLE_RATE;
  403. audiohook_list->native_slin_compatible = 1;
  404. AST_LIST_TRAVERSE(&audiohook_list->manipulate_list, ah, list) {
  405. if (!(ah->init_flags & AST_AUDIOHOOK_MANIPULATE_ALL_RATES)) {
  406. audiohook_list->native_slin_compatible = 0;
  407. return;
  408. }
  409. }
  410. }
  411. int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook)
  412. {
  413. ast_channel_lock(chan);
  414. /* Don't allow an audiohook to be attached to a channel that is already hung up.
  415. * The hang up process is what actually notifies the audiohook that it should
  416. * stop.
  417. */
  418. if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)) {
  419. ast_channel_unlock(chan);
  420. return -1;
  421. }
  422. if (!ast_channel_audiohooks(chan)) {
  423. struct ast_audiohook_list *ahlist;
  424. /* Whoops... allocate a new structure */
  425. if (!(ahlist = ast_calloc(1, sizeof(*ahlist)))) {
  426. ast_channel_unlock(chan);
  427. return -1;
  428. }
  429. ast_channel_audiohooks_set(chan, ahlist);
  430. AST_LIST_HEAD_INIT_NOLOCK(&ast_channel_audiohooks(chan)->spy_list);
  431. AST_LIST_HEAD_INIT_NOLOCK(&ast_channel_audiohooks(chan)->whisper_list);
  432. AST_LIST_HEAD_INIT_NOLOCK(&ast_channel_audiohooks(chan)->manipulate_list);
  433. /* This sample rate will adjust as necessary when writing to the list. */
  434. ast_channel_audiohooks(chan)->list_internal_samp_rate = DEFAULT_INTERNAL_SAMPLE_RATE;
  435. }
  436. /* Drop into respective list */
  437. if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY) {
  438. AST_LIST_INSERT_TAIL(&ast_channel_audiohooks(chan)->spy_list, audiohook, list);
  439. } else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER) {
  440. AST_LIST_INSERT_TAIL(&ast_channel_audiohooks(chan)->whisper_list, audiohook, list);
  441. } else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) {
  442. AST_LIST_INSERT_TAIL(&ast_channel_audiohooks(chan)->manipulate_list, audiohook, list);
  443. }
  444. /*
  445. * Initialize the audiohook's rate to the default. If it needs to be,
  446. * it will get updated later.
  447. */
  448. audiohook_set_internal_rate(audiohook, DEFAULT_INTERNAL_SAMPLE_RATE, 1);
  449. audiohook_list_set_samplerate_compatibility(ast_channel_audiohooks(chan));
  450. /* Change status over to running since it is now attached */
  451. ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_RUNNING);
  452. if (ast_channel_is_bridged(chan)) {
  453. ast_channel_set_unbridged_nolock(chan, 1);
  454. }
  455. ast_channel_unlock(chan);
  456. return 0;
  457. }
  458. void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
  459. {
  460. ast_audiohook_lock(audiohook);
  461. if (audiohook->status != AST_AUDIOHOOK_STATUS_DONE) {
  462. audiohook->status = status;
  463. ast_cond_signal(&audiohook->trigger);
  464. }
  465. ast_audiohook_unlock(audiohook);
  466. }
  467. int ast_audiohook_detach(struct ast_audiohook *audiohook)
  468. {
  469. if (audiohook->status == AST_AUDIOHOOK_STATUS_NEW || audiohook->status == AST_AUDIOHOOK_STATUS_DONE) {
  470. return 0;
  471. }
  472. ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_SHUTDOWN);
  473. while (audiohook->status != AST_AUDIOHOOK_STATUS_DONE) {
  474. ast_audiohook_trigger_wait(audiohook);
  475. }
  476. return 0;
  477. }
  478. void ast_audiohook_detach_list(struct ast_audiohook_list *audiohook_list)
  479. {
  480. int i;
  481. struct ast_audiohook *audiohook;
  482. if (!audiohook_list) {
  483. return;
  484. }
  485. /* Drop any spies */
  486. while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->spy_list, list))) {
  487. ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
  488. }
  489. /* Drop any whispering sources */
  490. while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->whisper_list, list))) {
  491. ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
  492. }
  493. /* Drop any manipulators */
  494. while ((audiohook = AST_LIST_REMOVE_HEAD(&audiohook_list->manipulate_list, list))) {
  495. ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
  496. audiohook->manipulate_callback(audiohook, NULL, NULL, 0);
  497. }
  498. /* Drop translation paths if present */
  499. for (i = 0; i < 2; i++) {
  500. if (audiohook_list->in_translate[i].trans_pvt) {
  501. ast_translator_free_path(audiohook_list->in_translate[i].trans_pvt);
  502. ao2_cleanup(audiohook_list->in_translate[i].format);
  503. }
  504. if (audiohook_list->out_translate[i].trans_pvt) {
  505. ast_translator_free_path(audiohook_list->out_translate[i].trans_pvt);
  506. ao2_cleanup(audiohook_list->in_translate[i].format);
  507. }
  508. }
  509. /* Free ourselves */
  510. ast_free(audiohook_list);
  511. }
  512. /*! \brief find an audiohook based on its source
  513. * \param audiohook_list The list of audiohooks to search in
  514. * \param source The source of the audiohook we wish to find
  515. * \return corresponding audiohook
  516. * \retval NULL if it cannot be found
  517. */
  518. static struct ast_audiohook *find_audiohook_by_source(struct ast_audiohook_list *audiohook_list, const char *source)
  519. {
  520. struct ast_audiohook *audiohook = NULL;
  521. AST_LIST_TRAVERSE(&audiohook_list->spy_list, audiohook, list) {
  522. if (!strcasecmp(audiohook->source, source)) {
  523. return audiohook;
  524. }
  525. }
  526. AST_LIST_TRAVERSE(&audiohook_list->whisper_list, audiohook, list) {
  527. if (!strcasecmp(audiohook->source, source)) {
  528. return audiohook;
  529. }
  530. }
  531. AST_LIST_TRAVERSE(&audiohook_list->manipulate_list, audiohook, list) {
  532. if (!strcasecmp(audiohook->source, source)) {
  533. return audiohook;
  534. }
  535. }
  536. return NULL;
  537. }
  538. static void audiohook_move(struct ast_channel *old_chan, struct ast_channel *new_chan, struct ast_audiohook *audiohook)
  539. {
  540. enum ast_audiohook_status oldstatus;
  541. /* By locking both channels and the audiohook, we can assure that
  542. * another thread will not have a chance to read the audiohook's status
  543. * as done, even though ast_audiohook_remove signals the trigger
  544. * condition.
  545. */
  546. ast_audiohook_lock(audiohook);
  547. oldstatus = audiohook->status;
  548. ast_audiohook_remove(old_chan, audiohook);
  549. ast_audiohook_attach(new_chan, audiohook);
  550. audiohook->status = oldstatus;
  551. ast_audiohook_unlock(audiohook);
  552. }
  553. void ast_audiohook_move_by_source(struct ast_channel *old_chan, struct ast_channel *new_chan, const char *source)
  554. {
  555. struct ast_audiohook *audiohook;
  556. if (!ast_channel_audiohooks(old_chan)) {
  557. return;
  558. }
  559. audiohook = find_audiohook_by_source(ast_channel_audiohooks(old_chan), source);
  560. if (!audiohook) {
  561. return;
  562. }
  563. audiohook_move(old_chan, new_chan, audiohook);
  564. }
  565. void ast_audiohook_move_all(struct ast_channel *old_chan, struct ast_channel *new_chan)
  566. {
  567. struct ast_audiohook *audiohook;
  568. struct ast_audiohook_list *audiohook_list;
  569. audiohook_list = ast_channel_audiohooks(old_chan);
  570. if (!audiohook_list) {
  571. return;
  572. }
  573. AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
  574. audiohook_move(old_chan, new_chan, audiohook);
  575. }
  576. AST_LIST_TRAVERSE_SAFE_END;
  577. AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->whisper_list, audiohook, list) {
  578. audiohook_move(old_chan, new_chan, audiohook);
  579. }
  580. AST_LIST_TRAVERSE_SAFE_END;
  581. AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
  582. audiohook_move(old_chan, new_chan, audiohook);
  583. }
  584. AST_LIST_TRAVERSE_SAFE_END;
  585. }
  586. int ast_audiohook_detach_source(struct ast_channel *chan, const char *source)
  587. {
  588. struct ast_audiohook *audiohook = NULL;
  589. ast_channel_lock(chan);
  590. /* Ensure the channel has audiohooks on it */
  591. if (!ast_channel_audiohooks(chan)) {
  592. ast_channel_unlock(chan);
  593. return -1;
  594. }
  595. audiohook = find_audiohook_by_source(ast_channel_audiohooks(chan), source);
  596. ast_channel_unlock(chan);
  597. if (audiohook && audiohook->status != AST_AUDIOHOOK_STATUS_DONE) {
  598. ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_SHUTDOWN);
  599. }
  600. return (audiohook ? 0 : -1);
  601. }
  602. int ast_audiohook_remove(struct ast_channel *chan, struct ast_audiohook *audiohook)
  603. {
  604. ast_channel_lock(chan);
  605. if (!ast_channel_audiohooks(chan)) {
  606. ast_channel_unlock(chan);
  607. return -1;
  608. }
  609. if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY) {
  610. AST_LIST_REMOVE(&ast_channel_audiohooks(chan)->spy_list, audiohook, list);
  611. } else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER) {
  612. AST_LIST_REMOVE(&ast_channel_audiohooks(chan)->whisper_list, audiohook, list);
  613. } else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE) {
  614. AST_LIST_REMOVE(&ast_channel_audiohooks(chan)->manipulate_list, audiohook, list);
  615. }
  616. audiohook_list_set_samplerate_compatibility(ast_channel_audiohooks(chan));
  617. ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
  618. if (ast_channel_is_bridged(chan)) {
  619. ast_channel_set_unbridged_nolock(chan, 1);
  620. }
  621. ast_channel_unlock(chan);
  622. return 0;
  623. }
  624. /*! \brief Pass a DTMF frame off to be handled by the audiohook core
  625. * \param chan Channel that the list is coming off of
  626. * \param audiohook_list List of audiohooks
  627. * \param direction Direction frame is coming in from
  628. * \param frame The frame itself
  629. * \return frame on success
  630. * \retval NULL on failure
  631. */
  632. static struct ast_frame *dtmf_audiohook_write_list(struct ast_channel *chan, struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame)
  633. {
  634. struct ast_audiohook *audiohook = NULL;
  635. int removed = 0;
  636. AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
  637. ast_audiohook_lock(audiohook);
  638. if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
  639. AST_LIST_REMOVE_CURRENT(list);
  640. removed = 1;
  641. ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
  642. ast_audiohook_unlock(audiohook);
  643. audiohook->manipulate_callback(audiohook, NULL, NULL, 0);
  644. if (ast_channel_is_bridged(chan)) {
  645. ast_channel_set_unbridged_nolock(chan, 1);
  646. }
  647. continue;
  648. }
  649. if (ast_test_flag(audiohook, AST_AUDIOHOOK_WANTS_DTMF)) {
  650. audiohook->manipulate_callback(audiohook, chan, frame, direction);
  651. }
  652. ast_audiohook_unlock(audiohook);
  653. }
  654. AST_LIST_TRAVERSE_SAFE_END;
  655. /* if an audiohook got removed, reset samplerate compatibility */
  656. if (removed) {
  657. audiohook_list_set_samplerate_compatibility(audiohook_list);
  658. }
  659. return frame;
  660. }
  661. static struct ast_frame *audiohook_list_translate_to_slin(struct ast_audiohook_list *audiohook_list,
  662. enum ast_audiohook_direction direction, struct ast_frame *frame)
  663. {
  664. struct ast_audiohook_translate *in_translate = (direction == AST_AUDIOHOOK_DIRECTION_READ ?
  665. &audiohook_list->in_translate[0] : &audiohook_list->in_translate[1]);
  666. struct ast_frame *new_frame = frame;
  667. struct ast_format *slin;
  668. /*
  669. * If we are capable of sample rates other that 8khz, update the internal
  670. * audiohook_list's rate and higher sample rate audio arrives. If native
  671. * slin compatibility is turned on all audiohooks in the list will be
  672. * updated as well during read/write processing.
  673. */
  674. audiohook_list->list_internal_samp_rate =
  675. MAX(ast_format_get_sample_rate(frame->subclass.format), audiohook_list->list_internal_samp_rate);
  676. slin = ast_format_cache_get_slin_by_rate(audiohook_list->list_internal_samp_rate);
  677. if (ast_format_cmp(frame->subclass.format, slin) == AST_FORMAT_CMP_EQUAL) {
  678. return new_frame;
  679. }
  680. if (!in_translate->format ||
  681. ast_format_cmp(frame->subclass.format, in_translate->format) != AST_FORMAT_CMP_EQUAL) {
  682. struct ast_trans_pvt *new_trans;
  683. new_trans = ast_translator_build_path(slin, frame->subclass.format);
  684. if (!new_trans) {
  685. return NULL;
  686. }
  687. if (in_translate->trans_pvt) {
  688. ast_translator_free_path(in_translate->trans_pvt);
  689. }
  690. in_translate->trans_pvt = new_trans;
  691. ao2_replace(in_translate->format, frame->subclass.format);
  692. }
  693. if (!(new_frame = ast_translate(in_translate->trans_pvt, frame, 0))) {
  694. return NULL;
  695. }
  696. return new_frame;
  697. }
  698. static struct ast_frame *audiohook_list_translate_to_native(struct ast_audiohook_list *audiohook_list,
  699. enum ast_audiohook_direction direction, struct ast_frame *slin_frame, struct ast_format *outformat)
  700. {
  701. struct ast_audiohook_translate *out_translate = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook_list->out_translate[0] : &audiohook_list->out_translate[1]);
  702. struct ast_frame *outframe = NULL;
  703. if (ast_format_cmp(slin_frame->subclass.format, outformat) == AST_FORMAT_CMP_NOT_EQUAL) {
  704. /* rebuild translators if necessary */
  705. if (ast_format_cmp(out_translate->format, outformat) == AST_FORMAT_CMP_NOT_EQUAL) {
  706. if (out_translate->trans_pvt) {
  707. ast_translator_free_path(out_translate->trans_pvt);
  708. }
  709. if (!(out_translate->trans_pvt = ast_translator_build_path(outformat, slin_frame->subclass.format))) {
  710. return NULL;
  711. }
  712. ao2_replace(out_translate->format, outformat);
  713. }
  714. /* translate back to the format the frame came in as. */
  715. if (!(outframe = ast_translate(out_translate->trans_pvt, slin_frame, 0))) {
  716. return NULL;
  717. }
  718. }
  719. return outframe;
  720. }
  721. /*!
  722. *\brief Set the audiohook's internal sample rate to the audiohook_list's rate,
  723. * but only when native slin compatibility is turned on.
  724. *
  725. * \param audiohook_list audiohook_list data object
  726. * \param audiohook the audiohook to update
  727. * \param rate the current max internal sample rate
  728. */
  729. static void audiohook_list_set_hook_rate(struct ast_audiohook_list *audiohook_list,
  730. struct ast_audiohook *audiohook, int *rate)
  731. {
  732. /* The rate should always be the max between itself and the hook */
  733. if (audiohook->hook_internal_samp_rate > *rate) {
  734. *rate = audiohook->hook_internal_samp_rate;
  735. }
  736. /*
  737. * If native slin compatibility is turned on then update the audiohook
  738. * with the audiohook_list's current rate. Note, the audiohook's rate is
  739. * set to the audiohook_list's rate and not the given rate. If there is
  740. * a change in rate the hook's rate is changed on its next check.
  741. */
  742. if (audiohook_list->native_slin_compatible) {
  743. ast_set_flag(audiohook, AST_AUDIOHOOK_COMPATIBLE);
  744. audiohook_set_internal_rate(audiohook, audiohook_list->list_internal_samp_rate, 1);
  745. } else {
  746. ast_clear_flag(audiohook, AST_AUDIOHOOK_COMPATIBLE);
  747. }
  748. }
  749. /*!
  750. * \brief Pass an AUDIO frame off to be handled by the audiohook core
  751. *
  752. * \details
  753. * This function has 3 ast_frames and 3 parts to handle each. At the beginning of this
  754. * function all 3 frames, start_frame, middle_frame, and end_frame point to the initial
  755. * input frame.
  756. *
  757. * Part_1: Translate the start_frame into SLINEAR audio if it is not already in that
  758. * format. The result of this part is middle_frame is guaranteed to be in
  759. * SLINEAR format for Part_2.
  760. * Part_2: Send middle_frame off to spies and manipulators. At this point middle_frame is
  761. * either a new frame as result of the translation, or points directly to the start_frame
  762. * because no translation to SLINEAR audio was required.
  763. * Part_3: Translate end_frame's audio back into the format of start frame if necessary. This
  764. * is only necessary if manipulation of middle_frame occurred.
  765. *
  766. * \param chan Channel that the list is coming off of
  767. * \param audiohook_list List of audiohooks
  768. * \param direction Direction frame is coming in from
  769. * \param frame The frame itself
  770. * \return frame on success
  771. * \retval NULL on failure
  772. */
  773. static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame)
  774. {
  775. struct ast_frame *start_frame = frame, *middle_frame = frame, *end_frame = frame;
  776. struct ast_audiohook *audiohook = NULL;
  777. int samples;
  778. int middle_frame_manipulated = 0;
  779. int removed = 0;
  780. int internal_sample_rate;
  781. /* ---Part_1. translate start_frame to SLINEAR if necessary. */
  782. if (!(middle_frame = audiohook_list_translate_to_slin(audiohook_list, direction, start_frame))) {
  783. return frame;
  784. }
  785. /* If the translation resulted in an interpolated frame then immediately return as audiohooks
  786. * rely on actual media being present to do things.
  787. */
  788. if (!middle_frame->data.ptr) {
  789. if (middle_frame != start_frame) {
  790. ast_frfree(middle_frame);
  791. }
  792. return start_frame;
  793. }
  794. samples = middle_frame->samples;
  795. /*
  796. * While processing each audiohook check to see if the internal sample rate needs
  797. * to be adjusted (it should be the highest rate specified between formats and
  798. * hooks). The given audiohook_list's internal sample rate is then set to the
  799. * updated value before returning.
  800. *
  801. * If slin compatibility mode is turned on then an audiohook's internal sample
  802. * rate is set to its audiohook_list's rate. If an audiohook_list's rate is
  803. * adjusted during this pass then the change is picked up by the audiohooks
  804. * on the next pass.
  805. */
  806. internal_sample_rate = audiohook_list->list_internal_samp_rate;
  807. /* ---Part_2: Send middle_frame to spy and manipulator lists. middle_frame is guaranteed to be SLINEAR here.*/
  808. /* Queue up signed linear frame to each spy */
  809. AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
  810. ast_audiohook_lock(audiohook);
  811. if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
  812. AST_LIST_REMOVE_CURRENT(list);
  813. removed = 1;
  814. ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
  815. ast_audiohook_unlock(audiohook);
  816. if (ast_channel_is_bridged(chan)) {
  817. ast_channel_set_unbridged_nolock(chan, 1);
  818. }
  819. continue;
  820. }
  821. audiohook_list_set_hook_rate(audiohook_list, audiohook, &internal_sample_rate);
  822. ast_audiohook_write_frame(audiohook, direction, middle_frame);
  823. ast_audiohook_unlock(audiohook);
  824. }
  825. AST_LIST_TRAVERSE_SAFE_END;
  826. /* If this frame is being written out to the channel then we need to use whisper sources */
  827. if (!AST_LIST_EMPTY(&audiohook_list->whisper_list)) {
  828. int i = 0;
  829. short read_buf[samples], combine_buf[samples], *data1 = NULL, *data2 = NULL;
  830. memset(&combine_buf, 0, sizeof(combine_buf));
  831. AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->whisper_list, audiohook, list) {
  832. struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
  833. ast_audiohook_lock(audiohook);
  834. if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
  835. AST_LIST_REMOVE_CURRENT(list);
  836. removed = 1;
  837. ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
  838. ast_audiohook_unlock(audiohook);
  839. if (ast_channel_is_bridged(chan)) {
  840. ast_channel_set_unbridged_nolock(chan, 1);
  841. }
  842. continue;
  843. }
  844. audiohook_list_set_hook_rate(audiohook_list, audiohook, &internal_sample_rate);
  845. if (ast_slinfactory_available(factory) >= samples && ast_slinfactory_read(factory, read_buf, samples)) {
  846. /* Take audio from this whisper source and combine it into our main buffer */
  847. for (i = 0, data1 = combine_buf, data2 = read_buf; i < samples; i++, data1++, data2++) {
  848. ast_slinear_saturated_add(data1, data2);
  849. }
  850. }
  851. ast_audiohook_unlock(audiohook);
  852. }
  853. AST_LIST_TRAVERSE_SAFE_END;
  854. /* We take all of the combined whisper sources and combine them into the audio being written out */
  855. for (i = 0, data1 = middle_frame->data.ptr, data2 = combine_buf; i < samples; i++, data1++, data2++) {
  856. ast_slinear_saturated_add(data1, data2);
  857. }
  858. middle_frame_manipulated = 1;
  859. }
  860. /* Pass off frame to manipulate audiohooks */
  861. if (!AST_LIST_EMPTY(&audiohook_list->manipulate_list)) {
  862. AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->manipulate_list, audiohook, list) {
  863. ast_audiohook_lock(audiohook);
  864. if (audiohook->status != AST_AUDIOHOOK_STATUS_RUNNING) {
  865. AST_LIST_REMOVE_CURRENT(list);
  866. removed = 1;
  867. ast_audiohook_update_status(audiohook, AST_AUDIOHOOK_STATUS_DONE);
  868. ast_audiohook_unlock(audiohook);
  869. /* We basically drop all of our links to the manipulate audiohook and prod it to do it's own destructive things */
  870. audiohook->manipulate_callback(audiohook, chan, NULL, direction);
  871. if (ast_channel_is_bridged(chan)) {
  872. ast_channel_set_unbridged_nolock(chan, 1);
  873. }
  874. continue;
  875. }
  876. audiohook_list_set_hook_rate(audiohook_list, audiohook, &internal_sample_rate);
  877. /*
  878. * Feed in frame to manipulation.
  879. */
  880. if (!audiohook->manipulate_callback(audiohook, chan, middle_frame, direction)) {
  881. /*
  882. * XXX FAILURES ARE IGNORED XXX
  883. * If the manipulation fails then the frame will be returned in its original state.
  884. * Since there are potentially more manipulator callbacks in the list, no action should
  885. * be taken here to exit early.
  886. */
  887. middle_frame_manipulated = 1;
  888. }
  889. ast_audiohook_unlock(audiohook);
  890. }
  891. AST_LIST_TRAVERSE_SAFE_END;
  892. }
  893. /* ---Part_3: Decide what to do with the end_frame (whether to transcode or not) */
  894. if (middle_frame_manipulated) {
  895. if (!(end_frame = audiohook_list_translate_to_native(audiohook_list, direction, middle_frame, start_frame->subclass.format))) {
  896. /* translation failed, so just pass back the input frame */
  897. end_frame = start_frame;
  898. }
  899. } else {
  900. end_frame = start_frame;
  901. }
  902. /* clean up our middle_frame if required */
  903. if (middle_frame != end_frame) {
  904. ast_frfree(middle_frame);
  905. middle_frame = NULL;
  906. }
  907. /* Before returning, if an audiohook got removed, reset samplerate compatibility */
  908. if (removed) {
  909. audiohook_list_set_samplerate_compatibility(audiohook_list);
  910. } else {
  911. /*
  912. * Set the audiohook_list's rate to the updated rate. Note that if a hook
  913. * was removed then the list's internal rate is reset to the default.
  914. */
  915. audiohook_list->list_internal_samp_rate = internal_sample_rate;
  916. }
  917. return end_frame;
  918. }
  919. int ast_audiohook_write_list_empty(struct ast_audiohook_list *audiohook_list)
  920. {
  921. return !audiohook_list
  922. || (AST_LIST_EMPTY(&audiohook_list->spy_list)
  923. && AST_LIST_EMPTY(&audiohook_list->whisper_list)
  924. && AST_LIST_EMPTY(&audiohook_list->manipulate_list));
  925. }
  926. 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)
  927. {
  928. /* Pass off frame to it's respective list write function */
  929. if (frame->frametype == AST_FRAME_VOICE) {
  930. return audio_audiohook_write_list(chan, audiohook_list, direction, frame);
  931. } else if (frame->frametype == AST_FRAME_DTMF) {
  932. return dtmf_audiohook_write_list(chan, audiohook_list, direction, frame);
  933. } else {
  934. return frame;
  935. }
  936. }
  937. /*! \brief Wait for audiohook trigger to be triggered
  938. * \param audiohook Audiohook to wait on
  939. */
  940. void ast_audiohook_trigger_wait(struct ast_audiohook *audiohook)
  941. {
  942. struct timeval wait;
  943. struct timespec ts;
  944. wait = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000));
  945. ts.tv_sec = wait.tv_sec;
  946. ts.tv_nsec = wait.tv_usec * 1000;
  947. ast_cond_timedwait(&audiohook->trigger, &audiohook->lock, &ts);
  948. return;
  949. }
  950. /* Count number of channel audiohooks by type, regardless of type */
  951. int ast_channel_audiohook_count_by_source(struct ast_channel *chan, const char *source, enum ast_audiohook_type type)
  952. {
  953. int count = 0;
  954. struct ast_audiohook *ah = NULL;
  955. if (!ast_channel_audiohooks(chan)) {
  956. return -1;
  957. }
  958. switch (type) {
  959. case AST_AUDIOHOOK_TYPE_SPY:
  960. AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->spy_list, ah, list) {
  961. if (!strcmp(ah->source, source)) {
  962. count++;
  963. }
  964. }
  965. break;
  966. case AST_AUDIOHOOK_TYPE_WHISPER:
  967. AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->whisper_list, ah, list) {
  968. if (!strcmp(ah->source, source)) {
  969. count++;
  970. }
  971. }
  972. break;
  973. case AST_AUDIOHOOK_TYPE_MANIPULATE:
  974. AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->manipulate_list, ah, list) {
  975. if (!strcmp(ah->source, source)) {
  976. count++;
  977. }
  978. }
  979. break;
  980. default:
  981. ast_debug(1, "Invalid audiohook type supplied, (%u)\n", type);
  982. return -1;
  983. }
  984. return count;
  985. }
  986. /* Count number of channel audiohooks by type that are running */
  987. int ast_channel_audiohook_count_by_source_running(struct ast_channel *chan, const char *source, enum ast_audiohook_type type)
  988. {
  989. int count = 0;
  990. struct ast_audiohook *ah = NULL;
  991. if (!ast_channel_audiohooks(chan))
  992. return -1;
  993. switch (type) {
  994. case AST_AUDIOHOOK_TYPE_SPY:
  995. AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->spy_list, ah, list) {
  996. if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
  997. count++;
  998. }
  999. break;
  1000. case AST_AUDIOHOOK_TYPE_WHISPER:
  1001. AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->whisper_list, ah, list) {
  1002. if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
  1003. count++;
  1004. }
  1005. break;
  1006. case AST_AUDIOHOOK_TYPE_MANIPULATE:
  1007. AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->manipulate_list, ah, list) {
  1008. if ((!strcmp(ah->source, source)) && (ah->status == AST_AUDIOHOOK_STATUS_RUNNING))
  1009. count++;
  1010. }
  1011. break;
  1012. default:
  1013. ast_debug(1, "Invalid audiohook type supplied, (%u)\n", type);
  1014. return -1;
  1015. }
  1016. return count;
  1017. }
  1018. /*! \brief Audiohook volume adjustment structure */
  1019. struct audiohook_volume {
  1020. struct ast_audiohook audiohook; /*!< Audiohook attached to the channel */
  1021. int read_adjustment; /*!< Value to adjust frames read from the channel by */
  1022. int write_adjustment; /*!< Value to adjust frames written to the channel by */
  1023. };
  1024. /*! \brief Callback used to destroy the audiohook volume datastore
  1025. * \param data Volume information structure
  1026. */
  1027. static void audiohook_volume_destroy(void *data)
  1028. {
  1029. struct audiohook_volume *audiohook_volume = data;
  1030. /* Destroy the audiohook as it is no longer in use */
  1031. ast_audiohook_destroy(&audiohook_volume->audiohook);
  1032. /* Finally free ourselves, we are of no more use */
  1033. ast_free(audiohook_volume);
  1034. return;
  1035. }
  1036. /*! \brief Datastore used to store audiohook volume information */
  1037. static const struct ast_datastore_info audiohook_volume_datastore = {
  1038. .type = "Volume",
  1039. .destroy = audiohook_volume_destroy,
  1040. };
  1041. /*! \brief Helper function which actually gets called by audiohooks to perform the adjustment
  1042. * \param audiohook Audiohook attached to the channel
  1043. * \param chan Channel we are attached to
  1044. * \param frame Frame of audio we want to manipulate
  1045. * \param direction Direction the audio came in from
  1046. * \retval 0 on success
  1047. * \retval -1 on failure
  1048. */
  1049. static int audiohook_volume_callback(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction)
  1050. {
  1051. struct ast_datastore *datastore = NULL;
  1052. struct audiohook_volume *audiohook_volume = NULL;
  1053. int *gain = NULL;
  1054. /* If the audiohook is shutting down don't even bother */
  1055. if (audiohook->status == AST_AUDIOHOOK_STATUS_DONE) {
  1056. return 0;
  1057. }
  1058. /* Try to find the datastore containg adjustment information, if we can't just bail out */
  1059. if (!(datastore = ast_channel_datastore_find(chan, &audiohook_volume_datastore, NULL))) {
  1060. return 0;
  1061. }
  1062. audiohook_volume = datastore->data;
  1063. /* Based on direction grab the appropriate adjustment value */
  1064. if (direction == AST_AUDIOHOOK_DIRECTION_READ) {
  1065. gain = &audiohook_volume->read_adjustment;
  1066. } else if (direction == AST_AUDIOHOOK_DIRECTION_WRITE) {
  1067. gain = &audiohook_volume->write_adjustment;
  1068. }
  1069. /* If an adjustment value is present modify the frame */
  1070. if (gain && *gain) {
  1071. ast_frame_adjust_volume(frame, *gain);
  1072. }
  1073. return 0;
  1074. }
  1075. /*! \brief Helper function which finds and optionally creates an audiohook_volume_datastore datastore on a channel
  1076. * \param chan Channel to look on
  1077. * \param create Whether to create the datastore if not found
  1078. * \return audiohook_volume structure on success
  1079. * \retval NULL on failure
  1080. */
  1081. static struct audiohook_volume *audiohook_volume_get(struct ast_channel *chan, int create)
  1082. {
  1083. struct ast_datastore *datastore = NULL;
  1084. struct audiohook_volume *audiohook_volume = NULL;
  1085. /* If we are able to find the datastore return the contents (which is actually an audiohook_volume structure) */
  1086. if ((datastore = ast_channel_datastore_find(chan, &audiohook_volume_datastore, NULL))) {
  1087. return datastore->data;
  1088. }
  1089. /* If we are not allowed to create a datastore or if we fail to create a datastore, bail out now as we have nothing for them */
  1090. if (!create || !(datastore = ast_datastore_alloc(&audiohook_volume_datastore, NULL))) {
  1091. return NULL;
  1092. }
  1093. /* Create a new audiohook_volume structure to contain our adjustments and audiohook */
  1094. if (!(audiohook_volume = ast_calloc(1, sizeof(*audiohook_volume)))) {
  1095. ast_datastore_free(datastore);
  1096. return NULL;
  1097. }
  1098. /* Setup our audiohook structure so we can manipulate the audio */
  1099. ast_audiohook_init(&audiohook_volume->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "Volume", AST_AUDIOHOOK_MANIPULATE_ALL_RATES);
  1100. audiohook_volume->audiohook.manipulate_callback = audiohook_volume_callback;
  1101. /* Attach the audiohook_volume blob to the datastore and attach to the channel */
  1102. datastore->data = audiohook_volume;
  1103. ast_channel_datastore_add(chan, datastore);
  1104. /* All is well... put the audiohook into motion */
  1105. ast_audiohook_attach(chan, &audiohook_volume->audiohook);
  1106. return audiohook_volume;
  1107. }
  1108. int ast_audiohook_volume_set(struct ast_channel *chan, enum ast_audiohook_direction direction, int volume)
  1109. {
  1110. struct audiohook_volume *audiohook_volume = NULL;
  1111. /* Attempt to find the audiohook volume information, but only create it if we are not setting the adjustment value to zero */
  1112. if (!(audiohook_volume = audiohook_volume_get(chan, (volume ? 1 : 0)))) {
  1113. return -1;
  1114. }
  1115. /* Now based on the direction set the proper value */
  1116. if (direction == AST_AUDIOHOOK_DIRECTION_READ || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
  1117. audiohook_volume->read_adjustment = volume;
  1118. }
  1119. if (direction == AST_AUDIOHOOK_DIRECTION_WRITE || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
  1120. audiohook_volume->write_adjustment = volume;
  1121. }
  1122. return 0;
  1123. }
  1124. int ast_audiohook_volume_get(struct ast_channel *chan, enum ast_audiohook_direction direction)
  1125. {
  1126. struct audiohook_volume *audiohook_volume = NULL;
  1127. int adjustment = 0;
  1128. /* Attempt to find the audiohook volume information, but do not create it as we only want to look at the values */
  1129. if (!(audiohook_volume = audiohook_volume_get(chan, 0))) {
  1130. return 0;
  1131. }
  1132. /* Grab the adjustment value based on direction given */
  1133. if (direction == AST_AUDIOHOOK_DIRECTION_READ) {
  1134. adjustment = audiohook_volume->read_adjustment;
  1135. } else if (direction == AST_AUDIOHOOK_DIRECTION_WRITE) {
  1136. adjustment = audiohook_volume->write_adjustment;
  1137. }
  1138. return adjustment;
  1139. }
  1140. int ast_audiohook_volume_adjust(struct ast_channel *chan, enum ast_audiohook_direction direction, int volume)
  1141. {
  1142. struct audiohook_volume *audiohook_volume = NULL;
  1143. /* Attempt to find the audiohook volume information, and create an audiohook if none exists */
  1144. if (!(audiohook_volume = audiohook_volume_get(chan, 1))) {
  1145. return -1;
  1146. }
  1147. /* Based on the direction change the specific adjustment value */
  1148. if (direction == AST_AUDIOHOOK_DIRECTION_READ || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
  1149. audiohook_volume->read_adjustment += volume;
  1150. }
  1151. if (direction == AST_AUDIOHOOK_DIRECTION_WRITE || direction == AST_AUDIOHOOK_DIRECTION_BOTH) {
  1152. audiohook_volume->write_adjustment += volume;
  1153. }
  1154. return 0;
  1155. }
  1156. int ast_audiohook_set_mute(struct ast_channel *chan, const char *source, enum ast_audiohook_flags flag, int clear)
  1157. {
  1158. struct ast_audiohook *audiohook = NULL;
  1159. ast_channel_lock(chan);
  1160. /* Ensure the channel has audiohooks on it */
  1161. if (!ast_channel_audiohooks(chan)) {
  1162. ast_channel_unlock(chan);
  1163. return -1;
  1164. }
  1165. audiohook = find_audiohook_by_source(ast_channel_audiohooks(chan), source);
  1166. if (audiohook) {
  1167. if (clear) {
  1168. ast_clear_flag(audiohook, flag);
  1169. } else {
  1170. ast_set_flag(audiohook, flag);
  1171. }
  1172. }
  1173. ast_channel_unlock(chan);
  1174. return (audiohook ? 0 : -1);
  1175. }
  1176. int ast_audiohook_set_mute_all(struct ast_channel *chan, const char *source, enum ast_audiohook_flags flag, int clearmute)
  1177. {
  1178. struct ast_audiohook *audiohook = NULL;
  1179. int count = 0;
  1180. ast_channel_lock(chan);
  1181. if (!ast_channel_audiohooks(chan)) {
  1182. ast_channel_unlock(chan);
  1183. return -1;
  1184. }
  1185. AST_LIST_TRAVERSE(&ast_channel_audiohooks(chan)->spy_list, audiohook, list) {
  1186. if (!strcasecmp(audiohook->source, source)) {
  1187. count++;
  1188. if (clearmute) {
  1189. ast_clear_flag(audiohook, flag);
  1190. } else {
  1191. ast_set_flag(audiohook, flag);
  1192. }
  1193. }
  1194. }
  1195. ast_test_suite_event_notify("AUDIOHOOK_GROUP_MUTE_TOGGLE", "Channel: %s\r\nSource: %s\r\nCount: %d\r\n",
  1196. ast_channel_name(chan), source, count);
  1197. ast_channel_unlock(chan);
  1198. return count;
  1199. }