audio_session.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "audio_session.h"
  4. #include "Event.h"
  5. #include <memutil.h>
  6. #include <rtp.h>
  7. #include <rtpsession.h>
  8. #include "audioframework.h"
  9. #include "libaudioqueue.h"
  10. #include "rvc_media_common.h"
  11. #include <string.h>
  12. #include "iaudionsinterface.h"
  13. #ifdef RVC_OS_WIN
  14. #include <portaudio.h>
  15. #endif
  16. #define AUDIO_CLOCK 8000
  17. #define AUDIO_SHM_FRAME_TIME 20 // 20ms
  18. #ifndef RVC_MAX_BUFFER_LEN
  19. #define RVC_MAX_BUFFER_LEN 512
  20. #endif
  21. #ifndef RVC_AUDIO_FRAME_LEN
  22. #define RVC_AUDIO_FRAME_LEN 320
  23. #endif
  24. #ifndef RVC_MIN_AUDIO_SERIESNUMBER
  25. #define RVC_MIN_AUDIO_SERIESNUMBER 10000
  26. #endif // !RVC_MIN_AUDIO_SERIESNUMBER
  27. char straudiodata[RVC_MAX_BUFFER_LEN] = {0};
  28. int iaudiolen = 0;
  29. int iIndex = 0;
  30. int iLastLeft = 0;
  31. static int g_nAudioRecvNum = 0;
  32. static int g_nAudioSendNum = 0;
  33. enum e_media_dir
  34. {
  35. DIR_NONE = 0,
  36. DIR_TX = 1,
  37. DIR_RX = 2,
  38. DIR_BOTH = 3,
  39. };
  40. typedef struct audio_recorder_t audio_recorder_t;
  41. typedef struct audio_phonemedia_t audio_phonemedia_t;
  42. struct audio_session_t
  43. {
  44. audio_session_conf_t conf;
  45. audio_session_phonemedia_conf_t phonemedia_conf;
  46. audio_session_t *owner;
  47. apr_pool_t *pool;
  48. audioengine_t *engine;
  49. audiocontext_t *context;
  50. audiobridge_t *bridge;
  51. apr_pool_t *micspk_pool;
  52. #ifdef RVC_OS_WIN
  53. audiomicspk2_t* micspkstream;
  54. #else
  55. audiomicspkpulse_t* micspkstream;
  56. #endif // _WIN32
  57. audiodsp_t *dspstream;
  58. audioresize_t *resizestream;
  59. audiortp_t *rtpstream;
  60. audiocodec_t *codecstream;
  61. rtp_session_t *rtpsess;
  62. //struct
  63. //{
  64. // audioresize_t *resizestream;
  65. // audiortp_t *rtpstream;
  66. // audiocodec_t *codecstream;
  67. // rtp_session_t *rtpsess;
  68. // int state;
  69. // audio_session_remote_recording_conf_t conf;
  70. //}record;
  71. Clibaudioqueue* remoteaudioqueue;
  72. //bool brtpinsertqueue;
  73. //audio noise suppression
  74. IAudioNs* audionsobj;
  75. IAudioNs* audioplaynsobj;
  76. bool baudiorecved;
  77. //FILE* pFile;
  78. int iaudio_seriesnumber;
  79. };
  80. static int rx_audio_callback(char *frame,void*userdata)
  81. {
  82. audio_session_t*session = (audio_session_t*)userdata;
  83. int used = 0;
  84. if (DOUBLERECORD_CALLTYPE != session->phonemedia_conf.eCalltype)
  85. {
  86. if (frame)
  87. {
  88. audio_frame frm;
  89. frm.bitspersample = 16;
  90. frm.format = 1;
  91. frm.data = frame;
  92. frm.framesize = 160; //注意此参数可能不准确,网络传输的包大小可能是不定长的,取音频数据时慎用此参数
  93. //写入实际的单个包大小
  94. //frm.framesize = strlen(frame); //不能使用此方法,网络传输的包大小可能是不定长的
  95. frm.nchannels = 1;
  96. frm.samplespersec = 8000;
  97. frm.iseriesnumber = g_nAudioRecvNum;
  98. if (!session->remoteaudioqueue->InsertAudio(&frm))
  99. {
  100. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("InsertAudio failed! frameCount:%d", frm.framesize);
  101. used = -1;
  102. }
  103. }
  104. }
  105. return used;
  106. }
  107. static int rvc_audio_ns(void* pdst, size_t udstlen, void* psrc, size_t usrclen, void* user_data)
  108. {
  109. int iret = -1;
  110. audio_session_t* session = (audio_session_t*)user_data;
  111. if (NULL != pdst && NULL != psrc){
  112. if (NULL != session && NULL != session->audionsobj){
  113. session->audionsobj->NsProcess((char*)pdst, udstlen, (char*)psrc, usrclen);
  114. //memcpy(pdst, psrc, usrclen);
  115. iret = 0;
  116. }
  117. }
  118. return iret;
  119. }
  120. static int rvc_audio_play_ns(void* pdst, size_t udstlen, void* psrc, size_t usrclen, void* user_data)
  121. {
  122. int iret = -1;
  123. audio_session_t* session = (audio_session_t*)user_data;
  124. if (NULL != pdst && NULL != psrc) {
  125. if (NULL != session->audioplaynsobj) {
  126. session->audioplaynsobj->NsProcess((char*)pdst, udstlen, (char*)psrc, usrclen);
  127. //memcpy(pdst, psrc, usrclen);
  128. iret = 0;
  129. }
  130. }
  131. return iret;
  132. }
  133. static int rvc_audio_playing_data(void* pdata, size_t ulen, void* user_data)
  134. {
  135. int iret = -1;
  136. audio_session_t* session = (audio_session_t*)user_data;
  137. if (DOUBLERECORD_CALLTYPE == session->phonemedia_conf.eCalltype) {
  138. if (iaudiolen + ulen <= RVC_MAX_BUFFER_LEN) {
  139. memcpy(straudiodata + iaudiolen, pdata, ulen);
  140. iaudiolen += ulen;
  141. if (iaudiolen >= RVC_AUDIO_FRAME_LEN) {
  142. audio_frame frm;
  143. char straudio[RVC_AUDIO_FRAME_LEN] = { 0 };
  144. memcpy(straudio, straudiodata, RVC_AUDIO_FRAME_LEN);
  145. frm.bitspersample = 16;
  146. frm.format = 1;
  147. frm.data = straudio;
  148. frm.framesize = RVC_AUDIO_FRAME_LEN;
  149. frm.nchannels = 1;
  150. frm.samplespersec = 8000;
  151. frm.iseriesnumber = session->iaudio_seriesnumber++;
  152. if (!session->remoteaudioqueue->InsertAudio(&frm)) {
  153. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("InsertAudio failed! frameCount:%d.", frm.framesize);
  154. }
  155. //else {
  156. // if (NULL != session->pFile) {
  157. // fwrite(frm.data, RVC_AUDIO_FRAME_LEN, 1, session->pFile);
  158. // }
  159. // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s:%d insert audio(seriesnumber = %d) success! frame count:%d.", __FUNCTION__, __LINE__, frm.iseriesnumber, frm.framesize);
  160. //}
  161. memset(straudiodata, 0, RVC_MAX_BUFFER_LEN);
  162. iaudiolen = 0;
  163. }
  164. }
  165. iret = 0;
  166. }
  167. return iret;
  168. }
  169. static int tx_audio_callback(void* audiodata, void* userdata)
  170. {
  171. audio_session_t* session = (audio_session_t*)userdata;
  172. int used = 0;
  173. return used;
  174. }
  175. static void send_hook_callback(const char *buf, int size, void *arg)
  176. {
  177. //LOG_FUNCTION();
  178. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("send audio pkt");
  179. if ((g_nAudioSendNum%60) ==0)
  180. {
  181. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("send audio pkt num %d,single size %d",g_nAudioSendNum,size);
  182. }
  183. g_nAudioSendNum++;
  184. }
  185. //static bool phonemedia_rtp_record(audio_session_t* pseesion)
  186. //{
  187. // bool bret = false;
  188. // if (NULL == pseesion){
  189. // return bret;
  190. // }
  191. //
  192. // if (true == pseesion->brtpinsertqueue){
  193. // if (DOUBLERECORD_CALLTYPE == pseesion->phonemedia_conf.eCalltype){
  194. // if (eStand2sType == pseesion->phonemedia_conf.eDeviceType){
  195. // if (DEV_PICKUP == pseesion->phonemedia_conf.dev_type){
  196. // bret = true;
  197. // }
  198. // }
  199. // }
  200. // }
  201. //
  202. // return bret;
  203. //}
  204. static void recv_hook_callback(const char *buf, int size, void *arg)
  205. {
  206. //LOG_FUNCTION();
  207. rtp_hdr *hdr = (rtp_hdr*)buf;
  208. audio_session_t* psession = (audio_session_t*)arg;
  209. if (false == psession->baudiorecved){
  210. char strmsg[MAX_PATH] = { 0 };
  211. snprintf(strmsg, MAX_PATH, "received first audio packet, and packet size is %d.", size);
  212. LogWarn(Severity_Low, Error_Debug, EVENT_MOD_SIP_AUDIO_STREAM_RECEIVED, strmsg);
  213. psession->baudiorecved = true;
  214. }
  215. //if ((g_nAudioRecvNum%100) == 0)
  216. //{
  217. // //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("recv audio pkt num %d,single size %d",g_nAudioRecvNum,size);
  218. // static int icount = 0;
  219. // if (psession->phonemedia_conf.eDeviceType == eStand2sType && icount == 0){
  220. // icount++;
  221. // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("current hand free flag is %d, call type = %d, pt = %d,arg addr is 0x%08x.",(int)psession->phonemedia_conf.dev_type, psession->phonemedia_conf.eCalltype, hdr->pt, arg);
  222. // }
  223. //}
  224. //
  225. //if (0 == psession->phonemedia_conf.dev_type && DOUBLERECORD_CALLTYPE == psession->phonemedia_conf.eCalltype){
  226. // if (false == psession->brtpinsertqueue){
  227. // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("rtp stream insert to audio queue flag is set to true.");
  228. // }
  229. // psession->brtpinsertqueue = true;
  230. //}
  231. //g_nAudioRecvNum++;
  232. //if (true == phonemedia_rtp_record(psession)){
  233. // char strbuffer[RVC_MAX_BUFFER_LEN]={0};
  234. // int outsize = RVC_MAX_BUFFER_LEN;
  235. // switch(hdr->pt)
  236. // {
  237. // case RTP_PT_PCMA:
  238. // audiocodec_pcma_decode(buf+sizeof(rtp_hdr), size-sizeof(rtp_hdr), strbuffer, &outsize);
  239. // break;
  240. // case RTP_PT_PCMU:
  241. // audiocodec_pcmu_decode(buf+sizeof(rtp_hdr), size-sizeof(rtp_hdr), strbuffer, &outsize);
  242. // break;
  243. // case RTP_PT_G729:
  244. // audiocodec_g729a_decode(buf+sizeof(rtp_hdr), size-sizeof(rtp_hdr), strbuffer, &outsize);
  245. // break;
  246. // default:
  247. // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audiocodec_decode not support audio pt(%d).", hdr->pt);
  248. // break;
  249. // }
  250. // if (psession && psession->remoteaudioqueue){
  251. // int iCount = (outsize+iLastLeft)/RVC_AUDIO_FRAME_LEN;
  252. // memcpy(straudiodata+iLastLeft, strbuffer, iCount*RVC_AUDIO_FRAME_LEN-iLastLeft);
  253. // for(int i = 0; i < iCount; i++)
  254. // {
  255. // audio_frame frm;
  256. // char straudio[RVC_AUDIO_FRAME_LEN]={0};
  257. // memcpy(straudio, straudiodata+i*RVC_AUDIO_FRAME_LEN, RVC_AUDIO_FRAME_LEN);
  258. // frm.bitspersample = 16;
  259. // frm.format = 1;
  260. // frm.data = straudio;
  261. // frm.framesize = RVC_AUDIO_FRAME_LEN; //注意此参数可能不准确,网络传输的包大小可能是不定长的,取音频数据时慎用此参数
  262. // frm.nchannels = 1;
  263. // frm.samplespersec = 8000;
  264. // if (!psession->remoteaudioqueue->InsertAudio(&frm))
  265. // {
  266. // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("InsertAudio failed! frameCount:%d", frm.framesize);
  267. // }
  268. // }
  269. // memset(straudiodata, 0, RVC_MAX_BUFFER_LEN); //清空缓存
  270. // iLastLeft = (outsize + iLastLeft) % RVC_AUDIO_FRAME_LEN; //上次剩余不足RVC_AUDIO_FRAME_LEN的buffer
  271. // if ((0 != iLastLeft) && (iCount*RVC_AUDIO_FRAME_LEN < outsize)){
  272. // memcpy(straudiodata, strbuffer+iCount*RVC_AUDIO_FRAME_LEN, iLastLeft); //暂存上一次的未入队列的音频数据
  273. // }
  274. // }
  275. // else{
  276. // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("pseesion->remoteaudioqueue is null.");
  277. // }
  278. //}
  279. }
  280. static void audio_device_event(bool bopen, int iret, bool bmicro, int idev, const char* strmessage, void* user_data)
  281. {
  282. char strinfo[MAX_PATH] = { 0 };
  283. DWORD errorcode = 0;
  284. if (bopen){
  285. if (DEV_PICKUP == idev) {
  286. char strpickup[] = "[pickup]";
  287. snprintf(strinfo, MAX_PATH, "%s%s", strmessage, strpickup);
  288. if (0 == iret) {
  289. if (bmicro) {
  290. errorcode = EVENT_MOD_SIP_PICKUP_IN_AUDIO_DEVICE_OPEN_SUCCESS;
  291. }
  292. else {
  293. errorcode = EVENT_MOD_SIP_PICKUP_OUT_AUDIO_DEVICE_OPEN_SUCCESS;
  294. }
  295. }
  296. else {
  297. if (bmicro) {
  298. errorcode = EVENT_MOD_SIP_PICKUP_IN_AUDIO_DEVICE_OPEN_FAILED;
  299. }
  300. else {
  301. errorcode = EVENT_MOD_SIP_PICKUP_OUT_AUDIO_DEVICE_OPEN_FAILED;
  302. }
  303. }
  304. }
  305. else {
  306. char strhandfree[] = "[hand free]";
  307. snprintf(strinfo, MAX_PATH, "%s%s", strmessage, strhandfree);
  308. if (0 == iret) {
  309. if (bmicro) {
  310. errorcode = EVENT_MOD_SIP_HANDFREE_IN_AUDIO_DEVICE_OPEN_SUCCESS;
  311. }
  312. else {
  313. errorcode = EVENT_MOD_SIP_HANDFREE_OUT_AUDIO_DEVICE_OPEN_SUCCESS;
  314. }
  315. }
  316. else {
  317. if (bmicro) {
  318. errorcode = EVENT_MOD_SIP_HANDFREE_IN_AUDIO_DEVICE_OPEN_FAILED;
  319. }
  320. else {
  321. errorcode = EVENT_MOD_SIP_HANDFREE_OUT_AUDIO_DEVICE_OPEN_FAILED;
  322. }
  323. }
  324. }
  325. }
  326. else {
  327. if (DEV_PICKUP == idev) {
  328. char strpickup[] = "[pickup]";
  329. snprintf(strinfo, MAX_PATH, "%s%s", strmessage, strpickup);
  330. if (bmicro) {
  331. errorcode = EVENT_MOD_SIP_PICKUP_IN_AUDIO_DEVICE_CLOSE;
  332. }
  333. else {
  334. errorcode = EVENT_MOD_SIP_PICKUP_OUT_AUDIO_DEVICE_CLOSE;
  335. }
  336. }
  337. else {
  338. char strhandfree[] = "[hand free]";
  339. snprintf(strinfo, MAX_PATH, "%s%s", strmessage, strhandfree);
  340. if (bmicro) {
  341. errorcode = EVENT_MOD_SIP_HANDFREE_IN_AUDIO_DEVICE_CLOSE;
  342. }
  343. else {
  344. errorcode = EVENT_MOD_SIP_HANDFREE_OUT_AUDIO_DEVICE_CLOSE;
  345. }
  346. }
  347. }
  348. LogWarn(Severity_Low, Error_Debug, errorcode, strinfo);
  349. }
  350. static int phonemedia_stop(audio_session_t *session, int b_record_turn_off);
  351. static void phonemedia_reconfig(audio_session_t *media, const audio_session_phonemedia_conf_t *conf)
  352. {
  353. memcpy(&media->phonemedia_conf, conf, sizeof(audio_session_phonemedia_conf_t));
  354. }
  355. #if defined(RVC_OS_LINUX)
  356. static int execute_cmd_return_result(const char* cmd, char* result)
  357. {
  358. char buf_ps[1024];
  359. char ps[1024] = { 0 };
  360. FILE* ptr;
  361. strcpy(ps, cmd);
  362. if ((ptr = popen(ps, "r")) != NULL) {
  363. while (fgets(buf_ps, 1024, ptr) != NULL) {
  364. strcat(result, buf_ps);
  365. if (strlen(result) > 1024)
  366. break;
  367. }
  368. pclose(ptr);
  369. return 0;
  370. } else {
  371. sprintf(result, "popen %s error: %d", ps, errno);
  372. return -1;
  373. }
  374. }
  375. #endif //RVC_OS_LINUX
  376. //static int phonemedia_on_remote_recording(audio_session_t *session)
  377. //{
  378. // int rc = 0;
  379. // audio_session_t *media = session;
  380. // assert(media->record.state);
  381. //
  382. // audiocontext_remove_driver(media->context, &media->bridge->base);
  383. // {
  384. // audio_session_remote_recording_conf_t *conf = &media->record.conf;
  385. // int clock = REC_COMMON_AUDIO_CLOCK;
  386. // int ptime = REC_COMMON_AUDIO_FRAME_PTIME;
  387. // apr_status_t status;
  388. // rc = rtp_session_create2(conf->local_rtp_ip, conf->local_rtp_port, 2, &media->record.rtpsess);
  389. // if (rc != 0) {
  390. // char msg[256];
  391. // const int lastErr = WSAGetLastError();
  392. // sprintf(msg, "create rtp session failed! rtp:%d, WSALastError=%d, rc=%d", conf->local_rtp_port, lastErr, rc);
  393. // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)(msg);
  394. //#if defined(RVC_OS_LINUX)
  395. // LogWarn(Severity_Low, Error_Unexpect, ERROR_MOD_SIP_SES_CREATE_FAILED, msg);
  396. // if (lastErr == 10048) { //EADDRINUSE
  397. // char content[1025];
  398. // char cmd[256];
  399. // sprintf(cmd, "netstat -tunlp | grep -E '%d|%d'", conf->local_rtp_port, conf->local_rtp_port+1);
  400. // execute_cmd_return_result(cmd, content);
  401. // sprintf(cmd, " | cur pid: %d", getpid());
  402. // strcat(content, cmd);
  403. // LogWarn(Severity_Low, Error_Unexpect, ERROR_MOD_SIP_SES_SOCKET_INUSED, content);
  404. // }
  405. //#endif //RVC_OS_LINUX
  406. //
  407. //
  408. // goto on_error;
  409. // }
  410. // rtp_session_reset2(media->record.rtpsess, RTP_SESSION_FLAG_SENDONLY|RTP_SESSION_FLAG_NO_RTCP, conf->remote_rtp_ip, conf->remote_rtp_port, conf->remote_rtp_port+1);
  411. // status = audioresize_create(media->pool, media->engine, FRAME_TIME*2*clock/1000, ptime*2*clock/1000, FRAME_TIME*2*clock/1000, ptime*2*clock/1000, &media->record.resizestream);
  412. // if (status != APR_SUCCESS)
  413. // goto on_error;
  414. // status = audiocodec_create(media->pool, media->engine, "G729", clock, FRAME_TIME, AUDIO_CODEC_OPT_ENCODE_WRITE, &media->record.codecstream);
  415. // if (status != APR_SUCCESS)
  416. // goto on_error;
  417. // status = audiortp_create(media->pool, media->engine, media->record.rtpsess, &media->record.rtpstream);
  418. // if (status != APR_SUCCESS)
  419. // goto on_error;
  420. // {
  421. // int param;
  422. // param = clock;
  423. // audiortp_set_param(media->record.rtpstream, AUDIO_RTP_FLAG_SEND_CLOCK, &param);
  424. // audiortp_set_param(media->record.rtpstream, AUDIO_RTP_FLAG_RECV_CLOCK, &param);
  425. // param = REC_COMMON_AUDIO_PT;
  426. // audiortp_set_param(media->record.rtpstream, AUDIO_RTP_FLAG_SEND_PT, &param);
  427. // audiortp_set_param(media->record.rtpstream, AUDIO_RTP_FLAG_RECV_PT, &param);
  428. // param = ptime;
  429. // audiortp_set_param(media->record.rtpstream, AUDIO_RTP_FLAG_SEND_PTIME, &param);
  430. // audiortp_set_param(media->record.rtpstream, AUDIO_RTP_FLAG_RECV_PTIME, &param);
  431. // //audiortp_set_param(media->record.rtpstream, AUDIO_RTP_FLAG_HOOK_ARG, media);
  432. // audiortp_init(media->record.rtpstream);
  433. // }
  434. // audiostream_connect_pipeline(STREAM_DIR_WRITE, &media->record.resizestream->base, &media->record.codecstream->base, &media->record.rtpstream->base, NULL);
  435. // audiobridge_set_recorder(media->bridge, &media->record.resizestream->base);
  436. //
  437. // on_error:
  438. //
  439. // if (status != APR_SUCCESS) {
  440. // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create remote recording objects failed!");
  441. // rc = Error_Resource;
  442. // }
  443. // }
  444. // audiocontext_add_driver(media->context, &media->bridge->base);
  445. //
  446. // return rc;
  447. //}
  448. static int phonemedia_start(audio_session_t *session)
  449. {
  450. LOG_FUNCTION();
  451. audio_session_t *media = session;
  452. audio_session_phonemedia_conf_t *conf = &media->phonemedia_conf;
  453. apr_status_t status;
  454. int rc;
  455. int opt_micspk;
  456. const char *in_dev;
  457. const char *out_dev;
  458. int in_agc;
  459. int out_agc;
  460. int in_ns;
  461. int out_ns;
  462. int aec;
  463. const char *codec;
  464. in_dev = &session->conf.in_dev[conf->dev_type][0];
  465. out_dev = &session->conf.out_dev[conf->dev_type][0];
  466. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("in_dev = %s,out_dev = %s, conf dir = %d.",in_dev,out_dev, conf->dir);
  467. opt_micspk = AMS_OPT_AS_STREAM;
  468. if (conf->dir & DIR_TX) {
  469. opt_micspk |= AMS_OPT_PLAY;
  470. }
  471. if (conf->dir &DIR_RX) {
  472. opt_micspk |= AMS_OPT_RECORD;
  473. }
  474. in_agc = media->conf.agc_in[conf->dev_type];
  475. out_agc = media->conf.agc_out[conf->dev_type];
  476. in_ns = media->conf.ns_in[conf->dev_type];
  477. out_ns = media->conf.ns_out[conf->dev_type];
  478. aec = media->conf.aec[conf->dev_type];
  479. switch (conf->local_pt) {
  480. case 0:
  481. codec = "PCMU";
  482. if (conf->local_ptime == 0)
  483. conf->local_ptime = 20;
  484. if (conf->remote_ptime == 0)
  485. conf->remote_ptime = 20;
  486. break;
  487. case 8:
  488. codec = "PCMA";
  489. if (conf->local_ptime == 0)
  490. conf->local_ptime = 20;
  491. if (conf->remote_ptime == 0)
  492. conf->remote_ptime = 20;
  493. break;
  494. case 18:
  495. codec = "G729";
  496. if (conf->local_ptime == 0)
  497. conf->local_ptime = 20;
  498. if (conf->remote_ptime == 0)
  499. conf->remote_ptime = 20;
  500. break;
  501. default:
  502. codec = NULL;
  503. break;
  504. }
  505. if (codec == NULL)
  506. goto on_error;
  507. //assert(conf->local_ptime == conf->remote_ptime);
  508. if (conf->local_ptime != conf->remote_ptime) {
  509. conf->local_ptime = conf->remote_ptime;
  510. }
  511. status = apr_pool_create(&media->pool, NULL);
  512. if (status != APR_SUCCESS) {
  513. LogWarn(Severity_Low, Error_Debug, ERROR_MOD_SIP_APR_POOL_CREATE_FAILED, "create media pool failed!");
  514. return Error_Resource;
  515. }
  516. status = audioengine_create(media->pool, &media->engine);
  517. if (status != APR_SUCCESS) {
  518. LogWarn(Severity_Low, Error_Debug, ERROR_MOD_SIP_AUDIO_ENGINE_CREATE_FAILED, "create audio engine failed!");
  519. goto on_error;
  520. }
  521. status = audioengine_start(media->engine);
  522. if (status != APR_SUCCESS) {
  523. LogWarn(Severity_Low, Error_Debug, ERROR_MOD_SIP_AUDIO_ENGINE_START_FAILED, "audio engine start failed!");
  524. goto on_error;
  525. }
  526. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audioengine_start success!");
  527. rc = rtp_session_create2(conf->local_rtp_ip, conf->local_rtp_port, 2, &media->rtpsess);
  528. if (rc != 0) {
  529. char strmsg[MAX_PATH] = { 0 };
  530. snprintf(strmsg, MAX_PATH, "audio rtp session create2 failed and local port is %d, rc=%d", conf->local_rtp_port, rc);
  531. LogWarn(Severity_Low, Error_Debug, ERROR_MOD_SIP_AUDIO_RTP_SESSION_CREATE_FAILED, strmsg);
  532. LogWarn(Severity_Low, Error_InvalidState, EVENT_MOD_SIP_AUDIO_RTP_CREATE, strmsg);
  533. goto on_error;
  534. }
  535. else{
  536. char strMessage[MAX_PATH] = { 0 };
  537. snprintf(strMessage, MAX_PATH, "audio rtp create2 success and local port is %d.", conf->local_rtp_port);
  538. LogWarn(Severity_Low, Error_Debug, EVENT_MOD_SIP_AUDIO_RTP_CREATE, strMessage);
  539. }
  540. rc = rtp_session_reset2(media->rtpsess, conf->dir, conf->remote_rtp_ip, conf->remote_rtp_port, conf->remote_rtp_port + 1);
  541. if (rc != 0) {
  542. LogWarn(Severity_Low, Error_Debug, ERROR_MOD_SIP_AUDIO_RTP_SESSION_RESET_FAILED, "audio rtp session reset failed!");
  543. goto on_error;
  544. }
  545. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("rtp_session_reset2 success!");
  546. status = audiobridge_create(media->pool, media->engine, &media->bridge);
  547. if (status != APR_SUCCESS){
  548. LogWarn(Severity_Low, Error_Debug, ERROR_MOD_SIP_AUDIO_BRIDGE_CREATE_FAILED, "audio bridge create failed!");
  549. goto on_error;
  550. }
  551. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audiobridge_create success!");
  552. status = apr_pool_create(&media->micspk_pool, media->pool);
  553. if (status != APR_SUCCESS){
  554. LogWarn(Severity_Low, Error_Debug, ERROR_MOD_SIP_APR_POOL_CREATE_FAILED, "create media micspk_pool failed!");
  555. goto on_error;
  556. }
  557. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("apr_pool_create success!");
  558. if (in_agc)
  559. opt_micspk |= AMS2_OPT_AGC;
  560. if (in_ns)
  561. opt_micspk |= AMS2_OPT_NS;
  562. if (aec)
  563. opt_micspk |= AMS2_OPT_AEC;
  564. #ifdef RVC_OS_WIN
  565. //create Spk
  566. status = audiomicspk2_create(media->micspk_pool, media->engine, opt_micspk, AUDIO_CLOCK, in_dev, out_dev, &media->micspkstream);
  567. #else
  568. status = audiomicspkpulse_create(media->micspk_pool, media->engine, opt_micspk, AUDIO_CLOCK, in_dev, out_dev, conf->dev_type, &audio_device_event, &media->micspkstream);
  569. #endif
  570. if (status != APR_SUCCESS)
  571. goto on_error;
  572. //音频回调
  573. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audiomicspk_create success!");
  574. media->micspkstream->user_data = media;
  575. media->micspkstream->on_rx_audio = &rx_audio_callback;
  576. media->micspkstream->on_tx_audio = &tx_audio_callback;
  577. media->micspkstream->on_audio_ns = &rvc_audio_ns;
  578. media->micspkstream->on_audio_play_ns = &rvc_audio_play_ns;
  579. media->micspkstream->on_audio_playing = &rvc_audio_playing_data;
  580. //media->micspkstream->on_audio_device_event = &audio_device_event;
  581. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("init on_rx_audio success!");
  582. if (out_agc || out_ns) {
  583. int read_opt = AUDIO_DSP_NONE;
  584. int write_opt = AUDIO_DSP_NONE;
  585. if (out_agc)
  586. write_opt |= AUDIO_DSP_AGC;
  587. if (out_ns)
  588. write_opt |= AUDIO_DSP_DENOISE;
  589. status = audiodsp_create(media->micspk_pool, media->engine, read_opt, write_opt, AUDIO_CLOCK, &media->dspstream);
  590. if (status != APR_SUCCESS){
  591. LogWarn(Severity_Low, Error_Debug, ERROR_MOD_SIP_AUDIO_DSP_CREATE_FAILED, "create audio dsp failed!");
  592. goto on_error;
  593. }
  594. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audiodsp_create success!");
  595. }
  596. #if 0
  597. status = audioaec_create(media->pool, media->engine, AUDIO_CLOCK, FRAME_TIME,
  598. AUDIO_AEC_OPT_READ_AS_CAPTURE, &media->aecstream);
  599. if (status != APR_SUCCESS)
  600. goto on_error;
  601. #endif
  602. status = audioresize_create(media->pool, media->engine, FRAME_TIME*2*AUDIO_CLOCK/1000,
  603. conf->remote_ptime*2*AUDIO_CLOCK/1000, FRAME_TIME*2*AUDIO_CLOCK/1000,
  604. conf->local_ptime*2*AUDIO_CLOCK/1000, &media->resizestream);
  605. if (status != APR_SUCCESS){
  606. LogWarn(Severity_Low, Error_Debug, ERROR_MOD_SIP_AUDIO_RESIZE_CREATE_FAILED, "create audio resize failed!");
  607. goto on_error;
  608. }
  609. status = audiocodec_create(media->pool, media->engine, codec, AUDIO_CLOCK, FRAME_TIME,
  610. AUDIO_CODEC_OPT_ENCODE_WRITE, &media->codecstream);
  611. if (status != APR_SUCCESS){
  612. LogWarn(Severity_Low, Error_Debug, ERROR_MOD_SIP_AUDIO_CODEC_CREATE_FAILED, "create audio codec failed!");
  613. goto on_error;
  614. }
  615. status = audiortp_create(media->pool, media->engine, media->rtpsess, &media->rtpstream);
  616. if (status != APR_SUCCESS){
  617. LogWarn(Severity_Low, Error_Debug, ERROR_MOD_SIP_AUDIO_RTP_CREATE_FAILED, "create audio rtp failed!");
  618. goto on_error;
  619. }
  620. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audio_session_t session addr is 0x%08x, audiortp_create success,and media->rtpstream addrs is 0x%08x!",session, media->rtpstream);
  621. g_nAudioRecvNum = 0;
  622. g_nAudioSendNum = 0;
  623. {
  624. int param;
  625. param = AUDIO_CLOCK;
  626. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_SEND_CLOCK, &param);
  627. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_RECV_CLOCK, &param);
  628. param = conf->local_pt;
  629. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_SEND_PT, &param);
  630. param = conf->remote_pt;
  631. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_RECV_PT, &param);
  632. param = conf->local_dtmf_pt;
  633. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_SEND_DTMF, &param);
  634. param = conf->remote_dtmf_pt;
  635. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_RECV_DTMF, &param);
  636. param = conf->local_ptime;
  637. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_SEND_PTIME, &param);
  638. param = conf->remote_ptime;
  639. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_RECV_PTIME, &param);
  640. //media->rtpstream->m_on_send_hook = &m_on_recv_hook;
  641. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("recv hook addr %d,send hook addr %d", &m_on_recv_hook,&m_on_send_hook);
  642. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_HOOK_ARG, media);
  643. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("AUDIO_RTP_FLAG_HOOK_ARG addr is 0x%08x.", media);
  644. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_RECV_HOOK, (const void*)&recv_hook_callback);
  645. audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_SEND_HOOK, (const void*)&send_hook_callback);
  646. //audiortp_set_param(media->rtpstream, AUDIO_RTP_FLAG_HOOK_ARG, media->rtpstream);
  647. audiortp_init(media->rtpstream);
  648. }
  649. if (conf->dir == DIR_TX)
  650. {
  651. if (media->dspstream)
  652. {
  653. audiostream_connect_pipeline(STREAM_DIR_READ, &media->micspkstream->base, &media->dspstream->base, NULL);
  654. }
  655. else
  656. {
  657. audiostream_connect_pipeline(STREAM_DIR_READ, &media->micspkstream->base, NULL);
  658. }
  659. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_LEFT, &media->micspkstream->base);
  660. audiostream_connect_pipeline(STREAM_DIR_WRITE, &media->resizestream->base, &media->codecstream->base, &media->rtpstream->base, NULL);
  661. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_RIGHT, &media->resizestream->base);
  662. }
  663. else if (conf->dir == DIR_RX)
  664. {
  665. if (media->dspstream)
  666. {
  667. audiostream_connect_pipeline(STREAM_DIR_WRITE, &media->micspkstream->base, &media->dspstream->base, NULL);
  668. }
  669. else
  670. {
  671. audiostream_connect_pipeline(STREAM_DIR_WRITE, &media->micspkstream->base, NULL);
  672. }
  673. audiostream_connect_pipeline(STREAM_DIR_READ, &media->resizestream->base, &media->codecstream->base, &media->rtpstream->base, NULL);
  674. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_LEFT, &media->micspkstream->base);
  675. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_RIGHT, &media->resizestream->base);
  676. }
  677. else
  678. {
  679. if (media->dspstream)
  680. {
  681. audiostream_connect_pipeline(STREAM_DIR_BOTH, &media->micspkstream->base, &media->dspstream->base, NULL);
  682. }
  683. else
  684. {
  685. audiostream_connect_pipeline(STREAM_DIR_BOTH, &media->micspkstream->base, NULL);
  686. }
  687. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_LEFT, &media->micspkstream->base);
  688. audiostream_connect_pipeline(STREAM_DIR_BOTH, &media->resizestream->base, &media->codecstream->base, &media->rtpstream->base, NULL);
  689. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_RIGHT, &media->resizestream->base);
  690. }
  691. status = audiocontext_create(media->pool, media->engine, &media->context);
  692. if (status != APR_SUCCESS){
  693. LogWarn(Severity_Low, Error_Debug, ERROR_MOD_SIP_AUDIO_CONTEXT_CREATE_FAILED, "create audio context failed!");
  694. goto on_error;
  695. }
  696. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audiocontext_create success!");
  697. audiocontext_add_driver(media->context, &media->bridge->base);
  698. audioengine_start_context(media->engine, media->context);
  699. return 0;
  700. on_error:
  701. phonemedia_stop(media, TRUE);
  702. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("phonemedia_stop error!!!");
  703. return Error_Resource;
  704. }
  705. static int phonemedia_stop(audio_session_t *session, int b_record_turn_off)
  706. {
  707. audio_session_t *media = session;
  708. if (media->context) {
  709. audioengine_stop_context(media->engine, media->context);
  710. audiocontext_remove_driver(media->context, &media->bridge->base);
  711. audiocontext_destroy(media->context);
  712. media->context = NULL;
  713. }
  714. if (media->engine) {
  715. audioengine_stop(media->engine);
  716. audioengine_destroy(media->engine);
  717. media->engine = NULL;
  718. }
  719. if (media->bridge) {
  720. audiobridge_destroy(media->bridge);
  721. media->bridge = NULL;
  722. }
  723. if (media->resizestream) {
  724. audioresize_destroy(media->resizestream);
  725. media->resizestream = NULL;
  726. }
  727. if (media->codecstream) {
  728. audiocodec_destroy(media->codecstream);
  729. media->codecstream = NULL;
  730. }
  731. if (media->rtpstream) {
  732. audiortp_destroy(media->rtpstream);
  733. media->rtpstream = NULL;
  734. }
  735. if (media->rtpsess) {
  736. unsigned short ilocal_port = 0;
  737. rtp_session_get_local_rtp_port(media->rtpsess, &ilocal_port);
  738. rtp_session_destroy(media->rtpsess);
  739. {
  740. char strInfo[MAX_PATH] = { 0 };
  741. snprintf(strInfo, MAX_PATH, "audio rtp(media->rtpsess) destroy and local port is %u.", ilocal_port);
  742. LogWarn(Severity_Low, Error_Debug, EVENT_MOD_SIP_AUDIO_RTP_DESTROY, strInfo);
  743. }
  744. media->rtpsess = NULL;
  745. }
  746. if (media->dspstream) {
  747. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start audiodsp_destroy");
  748. audiodsp_destroy(media->dspstream);
  749. media->dspstream = NULL;
  750. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audiodsp_destroy success!");
  751. }
  752. if (media->micspkstream) {
  753. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start audiomicspk_destroy");
  754. #ifdef _WIN32
  755. audiomicspk2_destroy(media->micspkstream);
  756. #else
  757. audiomicspkpulse_destroy(media->micspkstream);
  758. #endif
  759. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audiomicspk_destroy success!");
  760. media->micspkstream = NULL;
  761. apr_pool_destroy(media->micspk_pool);
  762. media->micspk_pool = NULL;
  763. }
  764. if (media->pool) {
  765. apr_pool_destroy(media->pool);
  766. media->pool = NULL;
  767. }
  768. return 0;
  769. }
  770. static int phonemedia_chang_dev(audio_session_t *session, e_dev_type t)
  771. {
  772. audio_session_t *media = session;
  773. audio_session_phonemedia_conf_t *conf = &media->phonemedia_conf;
  774. int opt_micspk;
  775. const char *in_dev;
  776. const char *out_dev;
  777. int in_agc;
  778. int out_agc;
  779. int in_ns;
  780. int out_ns;
  781. int aec;
  782. in_dev = &session->conf.in_dev[t][0];
  783. out_dev = &session->conf.out_dev[t][0];
  784. in_agc = media->conf.agc_in[t];
  785. out_agc = media->conf.agc_out[t];
  786. in_ns = media->conf.ns_in[t];
  787. out_ns = media->conf.ns_out[t];
  788. aec = media->conf.aec[t];
  789. opt_micspk = AMS_OPT_AS_STREAM;
  790. if (conf->dir & DIR_TX) {
  791. opt_micspk |= AMS_OPT_PLAY;
  792. }
  793. if (conf->dir &DIR_RX) {
  794. opt_micspk |= AMS_OPT_RECORD;
  795. }
  796. if (media->pool) {
  797. //apr_status_t status;
  798. audiocontext_remove_driver(media->context, &media->bridge->base);
  799. if (media->micspkstream) {
  800. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start audiomicspk_destroy");
  801. #ifdef _WIN32
  802. audiomicspk2_destroy(media->micspkstream);
  803. #else
  804. audiomicspkpulse_destroy(media->micspkstream);
  805. #endif
  806. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audiomicspk_destroy success!");
  807. media->micspkstream = NULL;
  808. }
  809. if (media->dspstream) {
  810. audiodsp_destroy(media->dspstream);
  811. media->dspstream = NULL;
  812. }
  813. apr_pool_destroy(media->micspk_pool);
  814. apr_pool_create(&media->micspk_pool, media->pool);
  815. if (in_agc)
  816. opt_micspk |= AMS2_OPT_AGC;
  817. if (in_ns)
  818. opt_micspk |= AMS2_OPT_NS;
  819. if (aec)
  820. opt_micspk |= AMS2_OPT_AEC;
  821. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start audiomicspk_create");
  822. #ifdef RVC_OS_WIN
  823. audiomicspk2_create(media->micspk_pool, media->engine, opt_micspk, AUDIO_CLOCK, in_dev, out_dev, &media->micspkstream);
  824. #else
  825. audiomicspkpulse_create(media->micspk_pool, media->engine, opt_micspk, AUDIO_CLOCK, in_dev, out_dev, t, &audio_device_event, &media->micspkstream);
  826. #endif
  827. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start audiomicspk_create success");
  828. media->micspkstream->user_data = media;
  829. media->micspkstream->on_rx_audio = &rx_audio_callback;
  830. media->micspkstream->on_tx_audio = &tx_audio_callback;
  831. media->micspkstream->on_audio_ns = &rvc_audio_ns;
  832. media->micspkstream->on_audio_play_ns = &rvc_audio_play_ns;
  833. media->micspkstream->on_audio_playing = &rvc_audio_playing_data;
  834. //media->micspkstream->on_audio_device_event = &audio_device_event;
  835. media->phonemedia_conf.dev_type = t;
  836. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("init change dev on_rx_audio success!");
  837. if (out_agc || out_ns) {
  838. int read_opt = AUDIO_DSP_NONE;
  839. int write_opt = AUDIO_DSP_NONE;
  840. if (out_agc)
  841. write_opt |= AUDIO_DSP_AGC;
  842. if (out_ns)
  843. write_opt |= AUDIO_DSP_DENOISE;
  844. audiodsp_create(media->micspk_pool, media->engine, read_opt, write_opt, AUDIO_CLOCK, &media->dspstream);
  845. }
  846. if (conf->dir == DIR_TX) {
  847. if (media->dspstream) {
  848. audiostream_connect_pipeline(STREAM_DIR_READ, &media->micspkstream->base, &media->dspstream->base, NULL);
  849. } else {
  850. audiostream_connect_pipeline(STREAM_DIR_READ, &media->micspkstream->base, NULL);
  851. }
  852. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_LEFT, &media->micspkstream->base);
  853. audiostream_connect_pipeline(STREAM_DIR_WRITE, &media->resizestream->base, &media->codecstream->base, &media->rtpstream->base, NULL);
  854. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_RIGHT, &media->resizestream->base);
  855. }
  856. else if (conf->dir == DIR_RX) {
  857. if (media->dspstream) {
  858. audiostream_connect_pipeline(STREAM_DIR_WRITE, &media->micspkstream->base, &media->dspstream->base, NULL);
  859. } else {
  860. audiostream_connect_pipeline(STREAM_DIR_WRITE, &media->micspkstream->base, NULL);
  861. }
  862. audiostream_connect_pipeline(STREAM_DIR_READ, &media->resizestream->base, &media->codecstream->base, &media->rtpstream->base, NULL);
  863. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_LEFT, &media->micspkstream->base);
  864. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_RIGHT, &media->resizestream->base);
  865. }
  866. else {
  867. if (media->dspstream) {
  868. audiostream_connect_pipeline(STREAM_DIR_BOTH, &media->micspkstream->base, &media->dspstream->base, NULL);
  869. } else {
  870. audiostream_connect_pipeline(STREAM_DIR_BOTH, &media->micspkstream->base, NULL);
  871. }
  872. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_LEFT, &media->micspkstream->base);
  873. audiostream_connect_pipeline(STREAM_DIR_BOTH, &media->resizestream->base, &media->codecstream->base, &media->rtpstream->base, NULL);
  874. audiobridge_set_leg(media->bridge, AUDIO_BRIDGE_LEG_RIGHT, &media->resizestream->base);
  875. }
  876. audiortp_reset_jitter(media->rtpstream);
  877. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("phonemedia_chang_dev start audiocontext_add_driver");
  878. audiocontext_add_driver(media->context, &media->bridge->base);
  879. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("phonemedia_chang_dev start audiocontext_add_driver success");
  880. return 0;
  881. } else {
  882. return Error_NotInit;
  883. }
  884. return Error_Unexpect;
  885. }
  886. //static int phonemedia_start_remote_recording(audio_session_t *session, const audio_session_remote_recording_conf_t *conf)
  887. //{
  888. // audio_session_t *media = session;
  889. // if (!media->record.state) {
  890. // media->record.state = TRUE;
  891. // memcpy(&media->record.conf, conf, sizeof(audio_session_remote_recording_conf_t));
  892. // if (media->pool) {
  893. // int rc = phonemedia_on_remote_recording(media);
  894. // if (rc != 0) {
  895. // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start remote recording failed!");
  896. // }
  897. // return rc;
  898. // }
  899. // return 0;
  900. // } else {
  901. // return Error_Duplication;
  902. // }
  903. //}
  904. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  905. //// audio session
  906. static void __audionslog(void* user_data, const char* fmt, va_list arg)
  907. {
  908. vDbg(fmt, arg);
  909. }
  910. int audio_get_pcmrecord_filename(char* pbuffer, size_t ulen)
  911. {
  912. int iret = -1;
  913. char strfile[MAX_PATH] = { 0 };
  914. struct tm* t;
  915. time_t tt;
  916. time(&tt);
  917. t = localtime(&tt);
  918. snprintf(strfile, MAX_PATH, "%4d%02d%02d%02d%02d%02d", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
  919. if (NULL != pbuffer){
  920. iret = snprintf(pbuffer, MAX_PATH, "%s/%s_%s.pcm", "/opt/rvc/Temp/","agent_audio", strfile);
  921. }
  922. return iret;
  923. }
  924. int audio_session_create(const audio_session_conf_t *conf, audio_session_t **p_session)
  925. {
  926. audio_session_t *session = ZALLOC_T(audio_session_t);
  927. session->remoteaudioqueue = new Clibaudioqueue(REC_COMMON_REMOTEAUDIO_SHM_QUEUE);
  928. //session->brtpinsertqueue = false;
  929. session->baudiorecved = false;
  930. audions_callback_t t_callback = { 0 };
  931. t_callback.debug = &__audionslog;
  932. session->audionsobj = CreateIAudioNsObj(&t_callback);
  933. if (NULL != session->audionsobj){
  934. session->audionsobj->SetNsParams(8000, 10, 2);
  935. }
  936. session->audioplaynsobj = CreateIAudioNsObj(&t_callback);
  937. if (NULL != session->audioplaynsobj) {
  938. session->audioplaynsobj->SetNsParams(8000, 10, 2);
  939. }
  940. session->iaudio_seriesnumber = RVC_MIN_AUDIO_SERIESNUMBER;
  941. //char strfile[MAX_PATH] = { 0 };
  942. //if (-1 != audio_get_pcmrecord_filename(strfile, MAX_PATH)) {
  943. // session->pFile = fopen(strfile, "wb+");
  944. //}
  945. if (session) {
  946. memcpy(&session->conf, conf, sizeof(audio_session_conf_t));
  947. *p_session = session;
  948. return 0;
  949. } else {
  950. return Error_Resource;
  951. }
  952. }
  953. int audio_session_start_phonemedia(audio_session_t *session, const audio_session_phonemedia_conf_t *conf)
  954. {
  955. int rc;
  956. LOG_FUNCTION();
  957. if (!session)
  958. return Error_NotInit;
  959. if (session->pool) { // already started
  960. phonemedia_stop(session, FALSE);
  961. }
  962. phonemedia_reconfig(session, conf);
  963. rc = phonemedia_start(session);
  964. return rc;
  965. }
  966. //int audio_session_start_remote_recording(audio_session_t *session, const audio_session_remote_recording_conf_t *conf)
  967. //{
  968. // return phonemedia_start_remote_recording(session, conf);
  969. //}
  970. int audio_session_change_dev(audio_session_t *session, e_dev_type t)
  971. {
  972. return phonemedia_chang_dev(session, t);
  973. }
  974. int audio_session_stop(audio_session_t *session)
  975. {
  976. LOG_FUNCTION();
  977. return phonemedia_stop(session, TRUE);
  978. }
  979. void audio_session_destroy(audio_session_t *session)
  980. {
  981. if (session->remoteaudioqueue){
  982. delete session->remoteaudioqueue;
  983. }
  984. if (NULL != session->audionsobj) {
  985. DestroyIAudioNsObj(session->audionsobj);
  986. session->audionsobj = NULL;
  987. }
  988. if (NULL != session->audioplaynsobj) {
  989. DestroyIAudioNsObj(session->audioplaynsobj);
  990. session->audioplaynsobj = NULL;
  991. }
  992. ////if (NULL != session->pFile) {
  993. //// fclose(session->pFile);
  994. //// session->pFile = NULL;
  995. ////}
  996. assert(session->pool == NULL);
  997. free(session);
  998. }
  999. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1000. static void __stdcall __audio_log_func(int level, const char *s)
  1001. {
  1002. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)(s);
  1003. }
  1004. int audio_lib_init()
  1005. {
  1006. LOG_FUNCTION();
  1007. audio_log_set_func(&__audio_log_func);
  1008. int rc = audioframework_init();
  1009. if (rc != 0) {
  1010. return Error_Resource;
  1011. }
  1012. else {
  1013. audio_log_set_func(NULL);
  1014. #ifdef RVC_OS_WIN
  1015. int icnt, ocnt;
  1016. rc = audio_get_dev_count(&icnt, &ocnt);
  1017. if (rc == 0) {
  1018. int i;
  1019. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audio input devices(%d):", icnt);
  1020. for (i = 0; i < icnt; ++i) {
  1021. CSimpleStringA str = audio_get_dev_name(true, i);
  1022. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%d = %s", i, (LPCSTR)str);
  1023. }
  1024. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audio output devices(%d):", ocnt);
  1025. for (i = 0; i < ocnt; ++i) {
  1026. CSimpleStringA str = audio_get_dev_name(false, i);
  1027. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%d = %s", i, (LPCSTR)str);
  1028. }
  1029. }
  1030. #endif
  1031. audio_log_set_func(&__audio_log_func);
  1032. }
  1033. return 0;
  1034. }
  1035. void audio_lib_deinit()
  1036. {
  1037. LOG_FUNCTION();
  1038. audioframework_term();
  1039. }
  1040. #ifdef RVC_OS_WIN
  1041. int audio_get_dev_count(int *in_cnt, int *out_cnt)
  1042. {
  1043. int icnt = 0, ocnt = 0;
  1044. int cnt = Pa_GetDeviceCount();
  1045. for (int i = 0; i < cnt; ++i) {
  1046. const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
  1047. if (info->maxInputChannels)
  1048. icnt ++;
  1049. if (info->maxOutputChannels)
  1050. ocnt ++;
  1051. }
  1052. if (in_cnt)
  1053. *in_cnt = icnt;
  1054. if (out_cnt)
  1055. *out_cnt = ocnt;
  1056. return 0;
  1057. }
  1058. CSimpleStringA audio_get_dev_name(bool in_direction, int idx)
  1059. {
  1060. //audio_log_set_func(NULL);
  1061. int cnt = Pa_GetDeviceCount();
  1062. int ii, i;
  1063. for (i = 0, ii = 0; i < cnt; ++i) {
  1064. const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
  1065. if (in_direction) {
  1066. if (info->maxInputChannels) {
  1067. if (idx == ii) {
  1068. //audio_log_set_func(__audio_log_func);
  1069. return CSimpleStringA(info->name);
  1070. }
  1071. ii++;
  1072. }
  1073. } else {
  1074. if (info->maxOutputChannels) {
  1075. if (idx == ii) {
  1076. //audio_log_set_func(__audio_log_func);
  1077. return CSimpleStringA(info->name);
  1078. }
  1079. ii++;
  1080. }
  1081. }
  1082. }
  1083. //audio_log_set_func(__audio_log_func);
  1084. return CSimpleStringA();
  1085. }
  1086. int capture_get_audio_device_id(bool in_direction, const char *dev_name)
  1087. {
  1088. int cnt = Pa_GetDeviceCount();
  1089. int ii, i;
  1090. for (i = 0, ii = 0; i < cnt; ++i) {
  1091. const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
  1092. if (in_direction) {
  1093. if (info->maxInputChannels) {
  1094. if (strstr(info->name, dev_name) != NULL) {
  1095. return ii;
  1096. }
  1097. ii++;
  1098. }
  1099. } else {
  1100. if (info->maxOutputChannels) {
  1101. if (strstr(info->name, dev_name) != NULL) {
  1102. return ii;
  1103. }
  1104. ii++;
  1105. }
  1106. }
  1107. }
  1108. return -1;
  1109. }
  1110. int get_audio_dev_name(char*devname,char*in_dev,char*out_dev)
  1111. {
  1112. int icnt, ocnt;
  1113. int rc = audio_get_dev_count(&icnt, &ocnt);
  1114. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get audio input num=%d,output num=%d",icnt,ocnt);
  1115. if (rc == 0)
  1116. {
  1117. int i;
  1118. CSimpleStringA tmp;
  1119. for (i = 0; i < icnt; ++i)
  1120. {
  1121. tmp = audio_get_dev_name(TRUE, i);
  1122. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("input dev = %s!", tmp);
  1123. if (strstr(tmp,devname)!=NULL)
  1124. {
  1125. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get input dev = %s!", tmp);
  1126. memcpy(in_dev,tmp.GetData(),tmp.GetLength());
  1127. rc++;
  1128. }
  1129. }
  1130. for (i = 0; i < ocnt; ++i)
  1131. {
  1132. tmp = audio_get_dev_name(FALSE, i);
  1133. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("output dev = %s!", tmp);
  1134. if (strstr(tmp,devname)!=NULL)
  1135. {
  1136. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get output dev = %s!", tmp);
  1137. memcpy(out_dev,tmp.GetData(),tmp.GetLength());
  1138. rc++;
  1139. }
  1140. }
  1141. return rc;
  1142. }
  1143. else
  1144. {
  1145. return rc;
  1146. }
  1147. }
  1148. #endif