audio_session.cpp 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "audio_session.h"
  4. #include <memutil.h>
  5. #include <rtp.h>
  6. #include <rtpsession.h>
  7. #include "audioframework.h"
  8. #include "libaudioqueue.h"
  9. #include "rvc_media_common.h"
  10. #include <string>
  11. #include "iaudionsinterface.h"
  12. #include "cJSON.h"
  13. #ifdef RVC_OS_WIN
  14. #include <portaudio.h>
  15. #endif
  16. #ifndef AUDIO_CLOCK
  17. #define AUDIO_CLOCK 8000
  18. #endif
  19. #ifndef AUDIO_SHM_FRAME_TIME
  20. #define AUDIO_SHM_FRAME_TIME 20 // 20ms
  21. #endif
  22. #ifndef RVC_MAX_BUFFER_LEN
  23. #define RVC_MAX_BUFFER_LEN 512
  24. #endif
  25. #ifndef RVC_AUDIO_FRAME_LEN
  26. #define RVC_AUDIO_FRAME_LEN 320
  27. #endif
  28. #ifndef RVC_MIN_AUDIO_SERIESNUMBER
  29. #define RVC_MIN_AUDIO_SERIESNUMBER 10000
  30. #endif // !RVC_MIN_AUDIO_SERIESNUMBER
  31. char straudiodata[RVC_MAX_BUFFER_LEN] = {0};
  32. int iaudiolen = 0;
  33. int iIndex = 0;
  34. int iLastLeft = 0;
  35. static int g_nAudioRecvNum = 0;
  36. static int g_nAudioSendNum = 0;
  37. enum e_media_dir
  38. {
  39. DIR_NONE = 0,
  40. DIR_TX = 1,
  41. DIR_RX = 2,
  42. DIR_BOTH = 3,
  43. };
  44. typedef struct audio_recorder_t audio_recorder_t;
  45. typedef struct audio_phonemedia_t audio_phonemedia_t;
  46. struct audio_session_t
  47. {
  48. audio_session_conf_t conf;
  49. audio_session_phonemedia_conf_t phonemedia_conf;
  50. audio_session_t *owner;
  51. apr_pool_t *pool;
  52. audioengine_t *engine;
  53. audiocontext_t *context;
  54. audiobridge_t *bridge;
  55. apr_pool_t *micspk_pool;
  56. #ifdef RVC_OS_WIN
  57. audiomicspk2_t* micspkstream;
  58. #else
  59. audiomicspkpulse_t* micspkstream;
  60. #endif // RVC_OS_WIN
  61. audiodsp_t *dspstream;
  62. audioresize_t *resizestream;
  63. audiortp_t *rtpstream;
  64. audiocodec_t *codecstream;
  65. rtp_session_t *rtpsess;
  66. Clibaudioqueue*remoteaudioqueue;
  67. bool baudiorecved;
  68. int iaudio_seriesnumber;
  69. #ifdef RVC_OS_LINUX
  70. //audio noise suppression
  71. IAudioNs* audionsobj;
  72. IAudioNs* audioplaynsobj;
  73. #endif
  74. };
  75. #ifdef RVC_OS_WIN
  76. #else
  77. static int tx_audio_callback(void* audiodata, void* userdata)
  78. {
  79. audio_session_t* session = (audio_session_t*)userdata;
  80. int used = 0;
  81. return used;
  82. }
  83. static int rvc_audio_ns(void* pdst, size_t udstlen, void* psrc, size_t usrclen, void* user_data)
  84. {
  85. int iret = -1;
  86. audio_session_t* session = (audio_session_t*)user_data;
  87. if (NULL != pdst && NULL != psrc) {
  88. if (NULL != session && NULL != session->audionsobj) {
  89. session->audionsobj->NsProcess((char*)pdst, udstlen, (char*)psrc, usrclen);
  90. //memcpy(pdst, psrc, usrclen);
  91. iret = 0;
  92. }
  93. }
  94. return iret;
  95. }
  96. static int rvc_audio_play_ns(void* pdst, size_t udstlen, void* psrc, size_t usrclen, void* user_data)
  97. {
  98. int iret = -1;
  99. audio_session_t* session = (audio_session_t*)user_data;
  100. if (NULL != pdst && NULL != psrc) {
  101. if (NULL != session->audioplaynsobj) {
  102. session->audioplaynsobj->NsProcess((char*)pdst, udstlen, (char*)psrc, usrclen);
  103. //memcpy(pdst, psrc, usrclen);
  104. iret = 0;
  105. }
  106. }
  107. return iret;
  108. }
  109. #endif
  110. static int rvc_audio_playing_data(void* pdata, size_t ulen, void* user_data)
  111. {
  112. int iret = -1;
  113. audio_session_t* session = (audio_session_t*)user_data;
  114. if (DOUBLERECORD_CALLTYPE == session->phonemedia_conf.eCalltype) {
  115. if (iaudiolen + ulen <= RVC_MAX_BUFFER_LEN) {
  116. memcpy(straudiodata + iaudiolen, pdata, ulen);
  117. iaudiolen += ulen;
  118. if (iaudiolen >= RVC_AUDIO_FRAME_LEN) {
  119. audio_frame frm;
  120. char straudio[RVC_AUDIO_FRAME_LEN] = { 0 };
  121. memcpy(straudio, straudiodata, RVC_AUDIO_FRAME_LEN);
  122. frm.bitspersample = 16;
  123. frm.format = 1;
  124. frm.data = straudio;
  125. frm.framesize = RVC_AUDIO_FRAME_LEN;
  126. frm.nchannels = 1;
  127. frm.samplespersec = 8000;
  128. frm.iseriesnumber = session->iaudio_seriesnumber++;
  129. if (!session->remoteaudioqueue->InsertAudio(&frm)) {
  130. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("InsertAudio failed! frameCount:%d.", frm.framesize);
  131. }
  132. //else {
  133. // if (NULL != session->pFile) {
  134. // fwrite(frm.data, RVC_AUDIO_FRAME_LEN, 1, session->pFile);
  135. // }
  136. // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s:%d insert audio(seriesnumber = %d) success! frame count:%d.", __FUNCTION__, __LINE__, frm.iseriesnumber, frm.framesize);
  137. //}
  138. memset(straudiodata, 0, RVC_MAX_BUFFER_LEN);
  139. iaudiolen = 0;
  140. }
  141. }
  142. iret = 0;
  143. }
  144. return iret;
  145. }
  146. static void send_hook_callback(const char *buf, int size, void *arg)
  147. {
  148. g_nAudioSendNum++;
  149. }
  150. static void recv_hook_callback(const char *buf, int size, void *arg)
  151. {
  152. rtp_hdr *hdr = (rtp_hdr*)buf;
  153. audio_session_t* psession = (audio_session_t*)arg;
  154. if (false == psession->baudiorecved){
  155. LogWarn(Severity_Low, Error_Debug, EVENT_MOD_SIP_AUDIO_STREAM_RECEIVED, CSimpleStringA::Format("received first audio packet, and packet size is %d.", size).GetData());
  156. psession->baudiorecved = true;
  157. }
  158. }
  159. static void audio_device_event(bool bopen, int iret, bool bmicro, int idev, const char* strmessage, void* user_data)
  160. {
  161. char strinfo[MAX_PATH] = { 0 };
  162. DWORD errorcode = 0;
  163. if (bopen){
  164. if (DEV_PICKUP == idev) {
  165. char strpickup[] = "[pickup]";
  166. _snprintf(strinfo, MAX_PATH, "%s%s", strmessage, strpickup);
  167. if (0 == iret) {
  168. if (bmicro) {
  169. errorcode = EVENT_MOD_SIP_PICKUP_IN_AUDIO_DEVICE_OPEN_SUCCESS;
  170. }
  171. else {
  172. errorcode = EVENT_MOD_SIP_PICKUP_OUT_AUDIO_DEVICE_OPEN_SUCCESS;
  173. }
  174. }
  175. else {
  176. if (bmicro) {
  177. errorcode = EVENT_MOD_SIP_PICKUP_IN_AUDIO_DEVICE_OPEN_FAILED;
  178. }
  179. else {
  180. errorcode = EVENT_MOD_SIP_PICKUP_OUT_AUDIO_DEVICE_OPEN_FAILED;
  181. }
  182. }
  183. }
  184. else {
  185. char strhandfree[] = "[hand free]";
  186. _snprintf(strinfo, MAX_PATH, "%s%s", strmessage, strhandfree);
  187. if (0 == iret) {
  188. if (bmicro) {
  189. errorcode = EVENT_MOD_SIP_HANDFREE_IN_AUDIO_DEVICE_OPEN_SUCCESS;
  190. }
  191. else {
  192. errorcode = EVENT_MOD_SIP_HANDFREE_OUT_AUDIO_DEVICE_OPEN_SUCCESS;
  193. }
  194. }
  195. else {
  196. if (bmicro) {
  197. errorcode = EVENT_MOD_SIP_HANDFREE_IN_AUDIO_DEVICE_OPEN_FAILED;
  198. }
  199. else {
  200. errorcode = EVENT_MOD_SIP_HANDFREE_OUT_AUDIO_DEVICE_OPEN_FAILED;
  201. }
  202. }
  203. }
  204. }
  205. else {
  206. if (DEV_PICKUP == idev) {
  207. char strpickup[] = "[pickup]";
  208. _snprintf(strinfo, MAX_PATH, "%s%s", strmessage, strpickup);
  209. if (bmicro) {
  210. errorcode = EVENT_MOD_SIP_PICKUP_IN_AUDIO_DEVICE_CLOSE;
  211. }
  212. else {
  213. errorcode = EVENT_MOD_SIP_PICKUP_OUT_AUDIO_DEVICE_CLOSE;
  214. }
  215. }
  216. else {
  217. char strhandfree[] = "[hand free]";
  218. _snprintf(strinfo, MAX_PATH, "%s%s", strmessage, strhandfree);
  219. if (bmicro) {
  220. errorcode = EVENT_MOD_SIP_HANDFREE_IN_AUDIO_DEVICE_CLOSE;
  221. }
  222. else {
  223. errorcode = EVENT_MOD_SIP_HANDFREE_OUT_AUDIO_DEVICE_CLOSE;
  224. }
  225. }
  226. }
  227. LogWarn(Severity_Low, Error_Debug, errorcode, strinfo);
  228. }
  229. static int phonemedia_stop(audio_session_t *session);
  230. static void phonemedia_reconfig(audio_session_t *media, const audio_session_phonemedia_conf_t *conf)
  231. {
  232. memcpy(&media->phonemedia_conf, conf, sizeof(audio_session_phonemedia_conf_t));
  233. }
  234. static int phonemedia_start(audio_session_t *session)
  235. {
  236. audio_session_t *media = session;
  237. audio_session_phonemedia_conf_t *conf = &media->phonemedia_conf;
  238. apr_status_t status;
  239. int rc;
  240. int opt_micspk;
  241. const char *in_dev;
  242. const char *out_dev;
  243. int in_agc;
  244. int out_agc;
  245. int in_ns;
  246. int out_ns;
  247. int aec;
  248. const char *codec;
  249. in_dev = &session->conf.in_dev[conf->dev_type][0];
  250. out_dev = &session->conf.out_dev[conf->dev_type][0];
  251. opt_micspk = AMS_OPT_AS_STREAM;
  252. if (conf->dir & DIR_TX) {
  253. opt_micspk |= AMS_OPT_PLAY;
  254. }
  255. if (conf->dir &DIR_RX) {
  256. opt_micspk |= AMS_OPT_RECORD;
  257. }
  258. in_agc = media->conf.agc_in[conf->dev_type];
  259. out_agc = media->conf.agc_out[conf->dev_type];
  260. in_ns = media->conf.ns_in[conf->dev_type];
  261. out_ns = media->conf.ns_out[conf->dev_type];
  262. aec = media->conf.aec[conf->dev_type];
  263. switch (conf->local_pt) {
  264. case 0:
  265. codec = "PCMU";
  266. if (conf->local_ptime == 0)
  267. conf->local_ptime = 20;
  268. if (conf->remote_ptime == 0)
  269. conf->remote_ptime = 20;
  270. break;
  271. case 8:
  272. codec = "PCMA";
  273. if (conf->local_ptime == 0)
  274. conf->local_ptime = 20;
  275. if (conf->remote_ptime == 0)
  276. conf->remote_ptime = 20;
  277. break;
  278. case 18:
  279. codec = "G729";
  280. if (conf->local_ptime == 0)
  281. conf->local_ptime = 20;
  282. if (conf->remote_ptime == 0)
  283. conf->remote_ptime = 20;
  284. break;
  285. default:
  286. codec = NULL;
  287. break;
  288. }
  289. if (codec == NULL)
  290. goto on_error;
  291. //assert(conf->local_ptime == conf->remote_ptime);
  292. if (conf->local_ptime != conf->remote_ptime) {
  293. conf->local_ptime = conf->remote_ptime;
  294. }
  295. status = apr_pool_create(&media->pool, NULL);
  296. if (status != APR_SUCCESS) {
  297. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_APR_POOL_CREATE_FAILED, "create media pool failed!");
  298. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR0402301A5").setResultCode("RTA310C")("创建音频引擎内存分配失败");
  299. return Error_Resource;
  300. }
  301. status = audioengine_create(media->pool, &media->engine);
  302. if (status != APR_SUCCESS) {
  303. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_AUDIO_ENGINE_CREATE_FAILED, "create audio engine failed!");
  304. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR0402301A5").setResultCode("RTA310D")("创建音频引擎失败");
  305. goto on_error;
  306. }
  307. status = audioengine_start(media->engine);
  308. if (status != APR_SUCCESS) {
  309. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_AUDIO_ENGINE_START_FAILED, "audio engine start failed!");
  310. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR0402301A5").setResultCode("RTA310E")("启动音频引擎失败");
  311. goto on_error;
  312. }
  313. rc = rtp_session_create2(conf->local_rtp_ip, conf->local_rtp_port, 2, &media->rtpsess);
  314. if (rc != 0) {
  315. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_AUDIO_RTP_SESSION_CREATE_FAILED, CSimpleStringA::Format("audio rtp session create2 failed and local port is %d, rc=%d", conf->local_rtp_port, rc).GetData());
  316. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR0402301A5").setResultCode("RTA310F")("创建音频流通道失败");
  317. goto on_error;
  318. }
  319. rc = rtp_session_reset2(media->rtpsess, conf->dir, conf->remote_rtp_ip, conf->remote_rtp_port, conf->remote_rtp_port + 1);
  320. if (rc != 0) {
  321. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_AUDIO_RTP_SESSION_RESET_FAILED, "audio rtp session reset failed!");
  322. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR0402301A5").setResultCode("RTA3110")("重置音频流通道失败");
  323. goto on_error;
  324. }
  325. status = audiobridge_create(media->pool, media->engine, &media->bridge);
  326. if (status != APR_SUCCESS){
  327. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_AUDIO_BRIDGE_CREATE_FAILED, "audio bridge create failed!");
  328. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR0402301A5").setResultCode("RTA3111")("音频通道桥接失败");
  329. goto on_error;
  330. }
  331. status = apr_pool_create(&media->micspk_pool, media->pool);
  332. if (status != APR_SUCCESS){
  333. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_APR_POOL_CREATE_FAILED, "create media micspk_pool failed!");
  334. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR0402301A5").setResultCode("RTA3112")("创建音频设备管理内存分配失败");
  335. goto on_error;
  336. }
  337. if (in_agc)
  338. opt_micspk |= AMS2_OPT_AGC;
  339. if (in_ns)
  340. opt_micspk |= AMS2_OPT_NS;
  341. if (aec)
  342. opt_micspk |= AMS2_OPT_AEC;
  343. #ifdef RVC_OS_WIN
  344. //create Spk
  345. status = audiomicspk2_create(media->micspk_pool, media->engine, opt_micspk, AUDIO_CLOCK, in_dev, out_dev, conf->dev_type, &audio_device_event, &media->micspkstream);
  346. #else
  347. status = audiomicspkpulse_create(media->micspk_pool, media->engine, opt_micspk, AUDIO_CLOCK, in_dev, out_dev, conf->dev_type, &audio_device_event, &media->micspkstream);
  348. #endif
  349. if (status != APR_SUCCESS){
  350. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_AUDIO_MICSPK_CREATE_FAILED, "create audio audio micspk create failed!");
  351. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR0402301A5").setResultCode("RTA3113")("创建音频设备管理失败");
  352. goto on_error;
  353. }
  354. //音频回调
  355. media->micspkstream->user_data = media;
  356. media->micspkstream->on_audio_playing = &rvc_audio_playing_data;
  357. #ifdef RVC_OS_LINUX
  358. media->micspkstream->on_tx_audio = &tx_audio_callback;
  359. media->micspkstream->on_audio_ns = &rvc_audio_ns;
  360. media->micspkstream->on_audio_play_ns = &rvc_audio_play_ns;
  361. #endif
  362. if (out_agc || out_ns) {
  363. int read_opt = AUDIO_DSP_NONE;
  364. int write_opt = AUDIO_DSP_NONE;
  365. if (out_agc)
  366. write_opt |= AUDIO_DSP_AGC;
  367. if (out_ns)
  368. write_opt |= AUDIO_DSP_DENOISE;
  369. status = audiodsp_create(media->micspk_pool, media->engine, read_opt, write_opt, AUDIO_CLOCK, &media->dspstream);
  370. if (status != APR_SUCCESS){
  371. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_AUDIO_DSP_CREATE_FAILED, "create audio dsp failed!");
  372. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR0402301A5").setResultCode("RTA3114")("创建音频信号处理器失败");
  373. goto on_error;
  374. }
  375. }
  376. #if 0
  377. status = audioaec_create(media->pool, media->engine, AUDIO_CLOCK, FRAME_TIME,
  378. AUDIO_AEC_OPT_READ_AS_CAPTURE, &media->aecstream);
  379. if (status != APR_SUCCESS)
  380. goto on_error;
  381. #endif
  382. status = audioresize_create(media->pool, media->engine, FRAME_TIME*2*AUDIO_CLOCK/1000,
  383. conf->remote_ptime*2*AUDIO_CLOCK/1000, FRAME_TIME*2*AUDIO_CLOCK/1000,
  384. conf->local_ptime*2*AUDIO_CLOCK/1000, &media->resizestream);
  385. if (status != APR_SUCCESS){
  386. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_AUDIO_RESIZE_CREATE_FAILED, "create audio resize failed!");
  387. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR0402301A5").setResultCode("RTA3115")("创建音频重采样失败");
  388. goto on_error;
  389. }
  390. status = audiocodec_create(media->pool, media->engine, codec, AUDIO_CLOCK, FRAME_TIME,
  391. AUDIO_CODEC_OPT_ENCODE_WRITE, &media->codecstream);
  392. if (status != APR_SUCCESS){
  393. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_AUDIO_CODEC_CREATE_FAILED, "create audio codec failed!");
  394. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR0402301A5").setResultCode("RTA3116")("创建音频编解码器失败");
  395. goto on_error;
  396. }
  397. status = audiortp_create(media->pool, media->engine, media->rtpsess, &media->rtpstream);
  398. if (status != APR_SUCCESS){
  399. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_AUDIO_RTP_CREATE_FAILED, "create audio rtp failed!");
  400. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR0402301A5").setResultCode("RTA3117")("创建音频rtp失败");
  401. goto on_error;
  402. }
  403. g_nAudioRecvNum = 0;
  404. g_nAudioSendNum = 0;
  405. {
  406. int param;
  407. param = AUDIO_CLOCK;
  408. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_SEND_CLOCK, &param);
  409. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_RECV_CLOCK, &param);
  410. param = conf->local_pt;
  411. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_SEND_PT, &param);
  412. param = conf->remote_pt;
  413. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_RECV_PT, &param);
  414. param = conf->local_dtmf_pt;
  415. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_SEND_DTMF, &param);
  416. param = conf->remote_dtmf_pt;
  417. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_RECV_DTMF, &param);
  418. param = conf->local_ptime;
  419. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_SEND_PTIME, &param);
  420. param = conf->remote_ptime;
  421. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_RECV_PTIME, &param);
  422. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_HOOK_ARG, media);
  423. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_RECV_HOOK, (const void*)&recv_hook_callback);
  424. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_SEND_HOOK, (const void*)&send_hook_callback);
  425. audiortp_init(media->rtpstream);
  426. }
  427. if (conf->dir == DIR_TX)
  428. {
  429. if (media->dspstream)
  430. {
  431. audiostream_connect_pipeline(STREAM_DIR_READ, &media->micspkstream->base, &media->dspstream->base, NULL);
  432. }
  433. else
  434. {
  435. audiostream_connect_pipeline(STREAM_DIR_READ, &media->micspkstream->base, NULL);
  436. }
  437. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_LEFT, &media->micspkstream->base);
  438. audiostream_connect_pipeline(STREAM_DIR_WRITE, &media->resizestream->base, &media->codecstream->base, &media->rtpstream->base, NULL);
  439. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_RIGHT, &media->resizestream->base);
  440. }
  441. else if (conf->dir == DIR_RX)
  442. {
  443. if (media->dspstream)
  444. {
  445. audiostream_connect_pipeline(STREAM_DIR_WRITE, &media->micspkstream->base, &media->dspstream->base, NULL);
  446. }
  447. else
  448. {
  449. audiostream_connect_pipeline(STREAM_DIR_WRITE, &media->micspkstream->base, NULL);
  450. }
  451. audiostream_connect_pipeline(STREAM_DIR_READ, &media->resizestream->base, &media->codecstream->base, &media->rtpstream->base, NULL);
  452. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_LEFT, &media->micspkstream->base);
  453. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_RIGHT, &media->resizestream->base);
  454. }
  455. else
  456. {
  457. if (media->dspstream)
  458. {
  459. audiostream_connect_pipeline(STREAM_DIR_BOTH, &media->micspkstream->base, &media->dspstream->base, NULL);
  460. }
  461. else
  462. {
  463. audiostream_connect_pipeline(STREAM_DIR_BOTH, &media->micspkstream->base, NULL);
  464. }
  465. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_LEFT, &media->micspkstream->base);
  466. audiostream_connect_pipeline(STREAM_DIR_BOTH, &media->resizestream->base, &media->codecstream->base, &media->rtpstream->base, NULL);
  467. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_RIGHT, &media->resizestream->base);
  468. }
  469. status = audiocontext_create(media->pool, media->engine, &media->context);
  470. if (status != APR_SUCCESS){
  471. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_AUDIO_CONTEXT_CREATE_FAILED, "create audio context failed!");
  472. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR0402301A5").setResultCode("RTA3118")("创建音频流水线管理器失败");
  473. goto on_error;
  474. }
  475. audiocontext_add_driver(media->context, &media->bridge->base);
  476. audioengine_start_context(media->engine, media->context);
  477. return 0;
  478. on_error:
  479. phonemedia_stop(media);
  480. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("phonemedia_stop error!!!");
  481. return Error_Resource;
  482. }
  483. static int phonemedia_stop(audio_session_t *session)
  484. {
  485. audio_session_t *media = session;
  486. if (media->context) {
  487. audioengine_stop_context(media->engine, media->context);
  488. audiocontext_remove_driver(media->context, &media->bridge->base);
  489. audiocontext_destroy(media->context);
  490. media->context = NULL;
  491. }
  492. if (media->engine) {
  493. audioengine_stop(media->engine);
  494. audioengine_destroy(media->engine);
  495. media->engine = NULL;
  496. }
  497. if (media->bridge) {
  498. audiobridge_destroy(media->bridge);
  499. media->bridge = NULL;
  500. }
  501. if (media->resizestream) {
  502. audioresize_destroy(media->resizestream);
  503. media->resizestream = NULL;
  504. }
  505. if (media->codecstream) {
  506. audiocodec_destroy(media->codecstream);
  507. media->codecstream = NULL;
  508. }
  509. if (media->rtpstream) {
  510. audiortp_destroy(media->rtpstream);
  511. media->rtpstream = NULL;
  512. }
  513. if (media->rtpsess) {
  514. unsigned short ilocal_port = 0;
  515. rtp_session_get_local_rtp_port(media->rtpsess, &ilocal_port);
  516. rtp_session_destroy(media->rtpsess);
  517. {
  518. LogWarn(Severity_Low, Error_Debug, EVENT_MOD_SIP_AUDIO_RTP_DESTROY, CSimpleStringA::Format("audio rtp(media->rtpsess) destroy and local port is %u.", ilocal_port).GetData());
  519. }
  520. media->rtpsess = NULL;
  521. }
  522. if (media->dspstream) {
  523. audiodsp_destroy(media->dspstream);
  524. media->dspstream = NULL;
  525. }
  526. if (media->micspkstream) {
  527. #ifdef _WIN32
  528. audiomicspk2_destroy(media->micspkstream);
  529. #else
  530. audiomicspkpulse_destroy(media->micspkstream);
  531. #endif
  532. media->micspkstream = NULL;
  533. apr_pool_destroy(media->micspk_pool);
  534. media->micspk_pool = NULL;
  535. }
  536. if (media->pool) {
  537. apr_pool_destroy(media->pool);
  538. media->pool = NULL;
  539. }
  540. return 0;
  541. }
  542. static int phonemedia_chang_dev(audio_session_t *session, e_dev_type t)
  543. {
  544. audio_session_t *media = session;
  545. audio_session_phonemedia_conf_t *conf = &media->phonemedia_conf;
  546. int opt_micspk;
  547. const char *in_dev;
  548. const char *out_dev;
  549. int in_agc;
  550. int out_agc;
  551. int in_ns;
  552. int out_ns;
  553. int aec;
  554. in_dev = &session->conf.in_dev[t][0];
  555. out_dev = &session->conf.out_dev[t][0];
  556. in_agc = media->conf.agc_in[t];
  557. out_agc = media->conf.agc_out[t];
  558. in_ns = media->conf.ns_in[t];
  559. out_ns = media->conf.ns_out[t];
  560. aec = media->conf.aec[t];
  561. opt_micspk = AMS_OPT_AS_STREAM;
  562. if (conf->dir & DIR_TX) {
  563. opt_micspk |= AMS_OPT_PLAY;
  564. }
  565. if (conf->dir & DIR_RX) {
  566. opt_micspk |= AMS_OPT_RECORD;
  567. }
  568. if (media->pool) {
  569. //apr_status_t status;
  570. audiocontext_remove_driver(media->context, &media->bridge->base);
  571. if (media->micspkstream) {
  572. #ifdef _WIN32
  573. audiomicspk2_destroy(media->micspkstream);
  574. #else
  575. audiomicspkpulse_destroy(media->micspkstream);
  576. #endif
  577. media->micspkstream = NULL;
  578. }
  579. if (media->dspstream) {
  580. audiodsp_destroy(media->dspstream);
  581. media->dspstream = NULL;
  582. }
  583. apr_pool_destroy(media->micspk_pool);
  584. apr_pool_create(&media->micspk_pool, media->pool);
  585. if (in_agc)
  586. opt_micspk |= AMS2_OPT_AGC;
  587. if (in_ns)
  588. opt_micspk |= AMS2_OPT_NS;
  589. if (aec)
  590. opt_micspk |= AMS2_OPT_AEC;
  591. #ifdef RVC_OS_WIN
  592. audiomicspk2_create(media->micspk_pool, media->engine, opt_micspk, AUDIO_CLOCK, in_dev, out_dev, t, &audio_device_event, &media->micspkstream);
  593. #else
  594. audiomicspkpulse_create(media->micspk_pool, media->engine, opt_micspk, AUDIO_CLOCK, in_dev, out_dev, t, &audio_device_event, &media->micspkstream);
  595. media->micspkstream->on_tx_audio = &tx_audio_callback;
  596. media->micspkstream->on_audio_ns = &rvc_audio_ns;
  597. media->micspkstream->on_audio_play_ns = &rvc_audio_play_ns;
  598. #endif
  599. media->micspkstream->on_audio_playing = &rvc_audio_playing_data;
  600. media->micspkstream->user_data = media;
  601. media->phonemedia_conf.dev_type = t;
  602. if (out_agc || out_ns) {
  603. int read_opt = AUDIO_DSP_NONE;
  604. int write_opt = AUDIO_DSP_NONE;
  605. if (out_agc)
  606. write_opt |= AUDIO_DSP_AGC;
  607. if (out_ns)
  608. write_opt |= AUDIO_DSP_DENOISE;
  609. audiodsp_create(media->micspk_pool, media->engine, read_opt, write_opt, AUDIO_CLOCK, &media->dspstream);
  610. }
  611. if (conf->dir == DIR_TX) {
  612. if (media->dspstream) {
  613. audiostream_connect_pipeline(STREAM_DIR_READ, &media->micspkstream->base, &media->dspstream->base, NULL);
  614. } else {
  615. audiostream_connect_pipeline(STREAM_DIR_READ, &media->micspkstream->base, NULL);
  616. }
  617. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_LEFT, &media->micspkstream->base);
  618. audiostream_connect_pipeline(STREAM_DIR_WRITE, &media->resizestream->base, &media->codecstream->base, &media->rtpstream->base, NULL);
  619. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_RIGHT, &media->resizestream->base);
  620. }
  621. else if (conf->dir == DIR_RX) {
  622. if (media->dspstream) {
  623. audiostream_connect_pipeline(STREAM_DIR_WRITE, &media->micspkstream->base, &media->dspstream->base, NULL);
  624. } else {
  625. audiostream_connect_pipeline(STREAM_DIR_WRITE, &media->micspkstream->base, NULL);
  626. }
  627. audiostream_connect_pipeline(STREAM_DIR_READ, &media->resizestream->base, &media->codecstream->base, &media->rtpstream->base, NULL);
  628. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_LEFT, &media->micspkstream->base);
  629. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_RIGHT, &media->resizestream->base);
  630. }
  631. else {
  632. if (media->dspstream) {
  633. audiostream_connect_pipeline(STREAM_DIR_BOTH, &media->micspkstream->base, &media->dspstream->base, NULL);
  634. } else {
  635. audiostream_connect_pipeline(STREAM_DIR_BOTH, &media->micspkstream->base, NULL);
  636. }
  637. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_LEFT, &media->micspkstream->base);
  638. audiostream_connect_pipeline(STREAM_DIR_BOTH, &media->resizestream->base, &media->codecstream->base, &media->rtpstream->base, NULL);
  639. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_RIGHT, &media->resizestream->base);
  640. }
  641. audiortp_reset_jitter(media->rtpstream);
  642. audiocontext_add_driver(media->context, &media->bridge->base);
  643. return 0;
  644. }
  645. else {
  646. return Error_NotInit;
  647. }
  648. return Error_Unexpect;
  649. }
  650. #ifdef RVC_OS_WIN
  651. #else
  652. static void __audionslog(void* user_data, const char* fmt, va_list arg)
  653. {
  654. int n = vsnprintf(NULL, 0, fmt, arg);
  655. if (n >= MAX_PATH) {
  656. char* buf = (char*)malloc((size_t)(n + 1));
  657. vsnprintf(buf, n + 1, fmt, arg);
  658. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("%s", buf);
  659. free(buf);
  660. }
  661. else {
  662. char strlog[MAX_PATH] = { 0 };
  663. vsnprintf(strlog, MAX_PATH, fmt, arg);
  664. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("%s", strlog);
  665. }
  666. }
  667. #endif
  668. int audio_session_create(const audio_session_conf_t *conf, audio_session_t **p_session)
  669. {
  670. audio_session_t *session = ZALLOC_T(audio_session_t);
  671. session->remoteaudioqueue = new Clibaudioqueue(REC_COMMON_REMOTEAUDIO_SHM_QUEUE);
  672. session->baudiorecved = false;
  673. session->iaudio_seriesnumber = RVC_MIN_AUDIO_SERIESNUMBER;
  674. #ifdef RVC_OS_WIN
  675. #else
  676. audions_callback_t t_callback = { 0 };
  677. t_callback.debug = &__audionslog;
  678. session->audionsobj = CreateIAudioNsObj(&t_callback);
  679. if (NULL != session->audionsobj){
  680. session->audionsobj->SetNsParams(8000, 10, 2);
  681. }
  682. session->audioplaynsobj = CreateIAudioNsObj(&t_callback);
  683. if (NULL != session->audioplaynsobj) {
  684. session->audioplaynsobj->SetNsParams(8000, 10, 2);
  685. }
  686. #endif
  687. if (session) {
  688. memcpy(&session->conf, conf, sizeof(audio_session_conf_t));
  689. *p_session = session;
  690. return 0;
  691. }
  692. else {
  693. return Error_Resource;
  694. }
  695. }
  696. int audio_session_start_phonemedia(audio_session_t *session, const audio_session_phonemedia_conf_t *conf)
  697. {
  698. int rc;
  699. if (!session) {
  700. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR0402301A5").setResultCode("RTA3119")("音频通道参数未初始化");
  701. return Error_NotInit;
  702. }
  703. if (session->pool) { // already started
  704. phonemedia_stop(session);
  705. }
  706. phonemedia_reconfig(session, conf);
  707. rc = phonemedia_start(session);
  708. return rc;
  709. }
  710. int audio_session_change_dev(audio_session_t *session, e_dev_type t)
  711. {
  712. return phonemedia_chang_dev(session, t);
  713. }
  714. int audio_session_stop(audio_session_t *session)
  715. {
  716. return phonemedia_stop(session);
  717. }
  718. void audio_session_destroy(audio_session_t *session)
  719. {
  720. if (session->remoteaudioqueue){
  721. delete session->remoteaudioqueue;
  722. }
  723. #ifdef RVC_OS_LINUX
  724. if (NULL != session->audionsobj) {
  725. DestroyIAudioNsObj(session->audionsobj);
  726. session->audionsobj = NULL;
  727. }
  728. if (NULL != session->audioplaynsobj) {
  729. DestroyIAudioNsObj(session->audioplaynsobj);
  730. session->audioplaynsobj = NULL;
  731. }
  732. #endif
  733. assert(session->pool == NULL);
  734. FREE(session);
  735. }
  736. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  737. static void __stdcall __audio_log_func(int level, const char *s)
  738. {
  739. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)(s);
  740. }
  741. int audio_lib_init()
  742. {
  743. audio_log_set_func(&__audio_log_func);
  744. int rc = audioframework_init();
  745. if (rc != 0) {
  746. return Error_Resource;
  747. }
  748. else {
  749. #ifdef RVC_OS_WIN
  750. int icnt, ocnt;
  751. audio_log_set_func(NULL);
  752. rc = audio_get_dev_count(&icnt, &ocnt);
  753. if (rc == 0) {
  754. int i;
  755. CSimpleStringA strJsonIn("");
  756. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audio input devices(%d):", icnt);
  757. for (i = 0; i < icnt; ++i) {
  758. CSimpleStringA str = audio_get_dev_name(true, i);
  759. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%d = %s", i, str.GetData());
  760. strJsonIn += CSimpleStringA::Format("\"%d\":\"%s\",", i, str.GetData());
  761. }
  762. if (strJsonIn.GetLength() > 0) {
  763. strJsonIn[strJsonIn.GetLength() - 1] = '\0';
  764. }
  765. CSimpleStringA strJsonInData = CSimpleStringA::Format("audio in devices [{%s}]", strJsonIn.GetData());
  766. LogWarn(Severity_Low, Error_Debug, LOG_EVT_SIPPHONE_GET_AUDIO_IN_INFOS, strJsonInData.GetData());
  767. CSimpleStringA strJsonOut("");
  768. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audio output devices(%d):", ocnt);
  769. for (i = 0; i < ocnt; ++i) {
  770. CSimpleStringA str = audio_get_dev_name(false, i);
  771. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%d = %s", i, str.GetData());
  772. strJsonOut += CSimpleStringA::Format("\"%d\":\"%s\",", i, str.GetData());
  773. }
  774. if (strJsonOut.GetLength() > 0) {
  775. strJsonOut[strJsonOut.GetLength() - 1] = '\0';
  776. }
  777. CSimpleStringA strJsonOutData = CSimpleStringA::Format("audio out devices [{%s}]", strJsonOut.GetData());
  778. LogWarn(Severity_Low, Error_Debug, LOG_EVT_SIPPHONE_GET_AUDIO_OUT_INFOS, strJsonOutData.GetData());
  779. }
  780. #endif
  781. audio_log_set_func(&__audio_log_func);
  782. }
  783. return 0;
  784. }
  785. void audio_lib_deinit()
  786. {
  787. audioframework_term();
  788. }
  789. #ifdef RVC_OS_WIN
  790. int audio_get_dev_count(int *in_cnt, int *out_cnt)
  791. {
  792. int icnt = 0, ocnt = 0;
  793. int cnt = Pa_GetDeviceCount();
  794. for (int i = 0; i < cnt; ++i) {
  795. const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
  796. if (info->maxInputChannels) {
  797. icnt++;
  798. }
  799. if (info->maxOutputChannels) {
  800. ocnt++;
  801. }
  802. }
  803. if (in_cnt) {
  804. *in_cnt = icnt;
  805. }
  806. if (out_cnt) {
  807. *out_cnt = ocnt;
  808. }
  809. return 0;
  810. }
  811. CSimpleStringA audio_get_dev_name(bool in_direction, int idx)
  812. {
  813. audio_log_set_func(NULL);
  814. int cnt = Pa_GetDeviceCount();
  815. int ii, i;
  816. for (i = 0, ii = 0; i < cnt; ++i) {
  817. const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
  818. if (in_direction) {
  819. if (info->maxInputChannels) {
  820. if (idx == ii) {
  821. CSimpleStringA strInDevice = CSimpleStringA(info->name);
  822. return strInDevice;
  823. }
  824. ii++;
  825. }
  826. } else {
  827. if (info->maxOutputChannels) {
  828. if (idx == ii) {
  829. CSimpleStringA strOutDevice = CSimpleStringA(info->name);
  830. return strOutDevice;
  831. }
  832. ii++;
  833. }
  834. }
  835. }
  836. return CSimpleStringA();
  837. }
  838. CSimpleStringA audio_get_dev_infos(bool in_direction)
  839. {
  840. int cnt = Pa_GetDeviceCount();
  841. CSimpleStringA strAudioJson("");
  842. cJSON* array = cJSON_CreateArray();
  843. cJSON* root = cJSON_CreateObject();
  844. char* strkey = NULL;
  845. if (in_direction) {
  846. strkey = "MicrophoneInfo";
  847. }
  848. else {
  849. strkey = "SpeakerInfo";
  850. }
  851. for (int i = 0; i < cnt; ++i) {
  852. const PaDeviceInfo* pinfo = Pa_GetDeviceInfo(i);
  853. if (in_direction) {
  854. if (pinfo->maxInputChannels > 0) {
  855. cJSON* pobject = cJSON_CreateObject();
  856. cJSON_AddItemToObject(pobject, "name", cJSON_CreateString(pinfo->name));
  857. cJSON_AddItemToObject(pobject, "samprate", cJSON_CreateString(CSimpleStringA::Format("%d", (int)pinfo->defaultSampleRate).GetData()));
  858. cJSON_AddItemToObject(pobject, "channels", cJSON_CreateString(CSimpleStringA::Format("%d", pinfo->maxInputChannels).GetData()));
  859. cJSON_AddItemToObject(pobject, "low_latency", cJSON_CreateString(CSimpleStringA::Format("%.2f", pinfo->defaultLowInputLatency).GetData()));
  860. cJSON_AddItemToObject(pobject, "high_latency", cJSON_CreateString(CSimpleStringA::Format("%.2f", pinfo->defaultHighInputLatency).GetData()));
  861. cJSON_AddItemToArray(array, pobject);
  862. }
  863. else {
  864. continue;
  865. }
  866. }
  867. else {
  868. if (pinfo->maxOutputChannels > 0) {
  869. cJSON* pobject = cJSON_CreateObject();
  870. cJSON_AddItemToObject(pobject, "name", cJSON_CreateString(pinfo->name));
  871. cJSON_AddItemToObject(pobject, "samprate", cJSON_CreateString(CSimpleStringA::Format("%d", (int)pinfo->defaultSampleRate).GetData()));
  872. cJSON_AddItemToObject(pobject, "channels", cJSON_CreateString(CSimpleStringA::Format("%d", pinfo->maxOutputChannels).GetData()));
  873. cJSON_AddItemToObject(pobject, "low_latency", cJSON_CreateString(CSimpleStringA::Format("%.2f", pinfo->defaultLowOutputLatency).GetData()));
  874. cJSON_AddItemToObject(pobject, "high_latency", cJSON_CreateString(CSimpleStringA::Format("%.2f", pinfo->defaultHighOutputLatency).GetData()));
  875. cJSON_AddItemToArray(array, pobject);
  876. }
  877. else {
  878. continue;
  879. }
  880. }
  881. }
  882. cJSON_AddItemToObject(root, strkey, array);
  883. char* pjsonstr = cJSON_PrintUnformatted(root);
  884. strAudioJson = pjsonstr;
  885. cJSON_free(pjsonstr);
  886. cJSON_Delete(root);
  887. return strAudioJson;
  888. }
  889. int capture_get_audio_device_id(bool in_direction, const char *dev_name)
  890. {
  891. if (NULL == dev_name || 0 == strlen(dev_name)) {
  892. return -1;
  893. }
  894. int cnt = Pa_GetDeviceCount();
  895. int ii, i;
  896. for (i = 0, ii = 0; i < cnt; ++i) {
  897. const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
  898. if (in_direction) {
  899. if (info->maxInputChannels) {
  900. if (strstr(info->name, dev_name) != NULL) {
  901. return ii;
  902. }
  903. ii++;
  904. }
  905. }
  906. else {
  907. if (info->maxOutputChannels) {
  908. if (strstr(info->name, dev_name) != NULL) {
  909. return ii;
  910. }
  911. ii++;
  912. }
  913. }
  914. }
  915. return -1;
  916. }
  917. #endif