libaudiomgr.cpp 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557
  1. #include"libaudiomgr.h"
  2. #include "core_time.h"
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #ifndef RVC_PA_ADJUST_LATENCY_PROTOCOL_VERSION
  6. #define RVC_PA_ADJUST_LATENCY_PROTOCOL_VERSION 13
  7. #endif
  8. static int sample_index = 0;
  9. // From pulsecore/macro.h
  10. #define pa_memzero(x,l) (memset((x), 0, (l)))
  11. #define pa_zero(x) (pa_memzero(&(x), sizeof(x)))
  12. static uint32_t latency_ms = 20; // requested initial latency in milisec: 0 use max
  13. static pa_usec_t latency = 0; //real latency in usec (for timestamping)
  14. static int sink_index = 0;
  15. static int source_index = 0;
  16. AudioMgrImpl::AudioMgrImpl(IAudioMgrCallback* pCallback)
  17. {
  18. m_audio_context = NULL;
  19. m_callback = pCallback;
  20. }
  21. AudioMgrImpl::~AudioMgrImpl()
  22. {
  23. if (NULL != m_audio_context){
  24. if (NULL != m_audio_context->list_input_devices) {
  25. free(m_audio_context->list_input_devices);
  26. m_audio_context->list_input_devices = NULL;
  27. }
  28. if (NULL != m_audio_context->list_output_devices) {
  29. free(m_audio_context->list_output_devices);
  30. m_audio_context->list_output_devices = NULL;
  31. }
  32. if (NULL != m_audio_context->capture_buff) {
  33. free(m_audio_context->capture_buff);
  34. m_audio_context->capture_buff = NULL;
  35. }
  36. free(m_audio_context);
  37. m_audio_context = NULL;
  38. }
  39. m_callback = NULL;
  40. }
  41. int AudioMgrImpl::audio_mgr_destroy()
  42. {
  43. delete this;
  44. return 0;
  45. }
  46. /*
  47. * init pulseaudio api
  48. * args:
  49. * audio_ctx - pointer to audio context data
  50. *
  51. * asserts:
  52. * audio_ctx is not null
  53. *
  54. * returns: error code (0 = E_OK)
  55. */
  56. int AudioMgrImpl::audio_init_pulseaudio()
  57. {
  58. /*assertions*/
  59. assert(NULL != m_audio_context);
  60. //if (false == m_initialized) {
  61. // // Initialize PulseAudio
  62. // if (InitPulseAudio() < 0) {
  63. // m_callback->debug("failed to initialize PulseAudio");
  64. // if (audio_mgr_terminate() < 0) {
  65. // m_callback->debug("failed to terminate PulseAudio");
  66. // }
  67. // return -1;
  68. // }
  69. // m_initialized = true;
  70. //}
  71. if (pa_get_devicelist() < 0)
  72. {
  73. m_callback->debug( "pulse audio failed to get audio device list from pulse server\n");
  74. return -1;
  75. }
  76. return 0;
  77. }
  78. //int32_t AudioMgrImpl::InitPulseAudio()
  79. //{
  80. //int retVal = 0;
  81. //// Create a mainloop API and connection to the default server
  82. //// the mainloop is the internal asynchronous API event loop
  83. //if (m_paMainloop) {
  84. // m_callback->debug("PA main loop has already existed");
  85. // return -1;
  86. //}
  87. //m_paMainloop = pa_mainloop_new();
  88. //if (!m_paMainloop) {
  89. // m_callback->debug("could not create main loop");;
  90. // return -1;
  91. //}
  92. //m_paMainloopApi = pa_mainloop_get_api(m_paMainloop);
  93. //if (!m_paMainloopApi) {
  94. // m_callback->debug("could not create main loop API");
  95. // return -1;
  96. //}
  97. //// Create a new PulseAudio context
  98. //if (m_paContext) {
  99. // m_callback->debug("PA context has already existed");
  100. // return -1;
  101. //}
  102. //m_paContext = pa_context_new(m_paMainloopApi, "RVC VoiceEngine");
  103. //if (!m_paContext) {
  104. // m_callback->debug("could not create context");
  105. // return -1;
  106. //}
  107. //if (pa_context_connect(m_paContext, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0)
  108. //{
  109. // m_callback->debug("AUDIO: PULSE - unable to connect to server: pa_context_connect failed");
  110. // return -1;
  111. //}
  112. //
  113. // return 0;
  114. //}
  115. /*
  116. * pa_mainloop will call this function when it's ready to tell us
  117. * about a source (input).
  118. * Since we're not threading when listing devices,
  119. * there's no need for mutexes on the devicelist structure
  120. * args:
  121. * c - pointer to pulse context
  122. * l - pointer to source info
  123. * eol - end of list
  124. * data - pointer to user data (audio context)
  125. *
  126. * asserts:
  127. * none
  128. *
  129. * returns: none
  130. */
  131. static void pa_sourcelist_cb(pa_context* c, const pa_source_info* l, int eol, void* data)
  132. {
  133. rvc_audio_context_t* audio_ctx = (rvc_audio_context_t*)data;
  134. int channels = 1;
  135. /*
  136. * If eol is set to a positive number,
  137. * you're at the end of the list
  138. */
  139. if (eol > 0)
  140. return;
  141. source_index++;
  142. if (l->sample_spec.channels < 1)
  143. channels = 1;
  144. else
  145. channels = l->sample_spec.channels;
  146. double my_latency = 0.0;
  147. int verbosity = 1;
  148. //if (verbosity > 0)
  149. //{
  150. //
  151. // printf("AUDIO: =======[ Input Device #%d ]=======\n", source_index);
  152. // printf(" Description: %s\n", l->description);
  153. // printf(" Name: %s\n", l->name);
  154. // printf(" Index: %d\n", l->index);
  155. // printf(" Channels: %d (default to: %d)\n", l->sample_spec.channels, channels);
  156. // printf(" SampleRate: %d\n", l->sample_spec.rate);
  157. // printf(" Latency: %llu (usec)\n", (long long unsigned) l->latency);
  158. // printf(" Configured Latency: %llu (usec)\n", (long long unsigned) l->configured_latency);
  159. // printf(" Card: %d\n", l->card);
  160. // printf(" monitor_of_sink_name: %s\n", l->monitor_of_sink_name);
  161. // printf(" driver: %s\n", l->driver);
  162. // if (l->active_port && l->active_port->name){
  163. // printf(" name: %s\n", l->active_port->name);
  164. // }
  165. // if (l->active_port && l->active_port->description){
  166. // printf(" description name: %s\n", l->active_port->description);
  167. // }
  168. // printf(" Volume channels: %d\n", l->volume.channels);
  169. // for(int i = 0; i < l->volume.channels; i++) {
  170. // printf(" Volume value: %d\n", l->volume.values[i]);
  171. // }
  172. // printf("\n");
  173. //}
  174. if (my_latency <= 0.0)
  175. my_latency = (double)latency_ms / 1000;
  176. if (l->monitor_of_sink == PA_INVALID_INDEX)
  177. {
  178. audio_ctx->num_input_dev++;
  179. /*add device to list*/
  180. audio_ctx->list_input_devices = (rvc_audio_device_t*)realloc(audio_ctx->list_input_devices, audio_ctx->num_input_dev * sizeof(rvc_audio_device_t));
  181. if (audio_ctx->list_input_devices == NULL)
  182. {
  183. //printf("AUDIO: FATAL memory allocation failure (pa_sourcelist_cb): %s\n", strerror(errno));
  184. exit(-1);
  185. }
  186. /*fill device data*/
  187. audio_ctx->list_input_devices[audio_ctx->num_input_dev - 1].id = l->index; /*saves dev id*/
  188. strncpy(audio_ctx->list_input_devices[audio_ctx->num_input_dev - 1].name, l->name, MAX_PATH_EX-1);
  189. strncpy(audio_ctx->list_input_devices[audio_ctx->num_input_dev - 1].description, l->description, MAX_PATH-1);
  190. audio_ctx->list_input_devices[audio_ctx->num_input_dev - 1].channels = channels;
  191. audio_ctx->list_input_devices[audio_ctx->num_input_dev - 1].samprate = l->sample_spec.rate;
  192. audio_ctx->list_input_devices[audio_ctx->num_input_dev - 1].low_latency = my_latency; /*in seconds*/
  193. audio_ctx->list_input_devices[audio_ctx->num_input_dev - 1].high_latency = my_latency; /*in seconds*/
  194. }
  195. }
  196. void PaSetVolumeCallback(pa_context* c,
  197. int success,
  198. void* /*pThis*/) {
  199. if (!success) {
  200. //printf("failed to set volume\n");
  201. }
  202. else {
  203. //printf("success to set volume\n");
  204. }
  205. }
  206. static void pa_setsourcevolume_cb(pa_context* c, const pa_source_info* l, int eol, void* data)
  207. {
  208. rvc_volume_set_t* audio_volume = (rvc_volume_set_t*)data;
  209. /*
  210. * If eol is set to a positive number,
  211. * you're at the end of the list
  212. */
  213. if (eol > 0)
  214. return;
  215. if (l->monitor_of_sink == PA_INVALID_INDEX)
  216. {
  217. if (strstr(l->description, audio_volume->strdevicename)) {
  218. pa_cvolume cvolumes;
  219. // Set the same volume for all channels
  220. pa_cvolume_set(&cvolumes, l->channel_map.channels, audio_volume->ivolume);
  221. pa_operation* paOperation = NULL;
  222. if (!(paOperation = pa_context_set_source_volume_by_index(c, l->index, &cvolumes, PaSetVolumeCallback, NULL))) {
  223. audio_volume->volume_flag = 1;
  224. }
  225. pa_operation_unref(paOperation);
  226. }
  227. }
  228. }
  229. static void pa_setsinkvolume_cb(pa_context* c, const pa_sink_info* l, int eol, void* data)
  230. {
  231. rvc_volume_set_t* audio_volume = (rvc_volume_set_t*)data;
  232. /*
  233. * If eol is set to a positive number,
  234. * you're at the end of the list
  235. */
  236. if (eol > 0)
  237. return;
  238. if (strstr(l->description, audio_volume->strdevicename)) {
  239. pa_cvolume cvolumes;
  240. // Set the same volume for all channels
  241. pa_cvolume_set(&cvolumes, l->channel_map.channels, audio_volume->ivolume);
  242. pa_operation* paOperation = NULL;
  243. if (!(paOperation = pa_context_set_sink_volume_by_index(c, l->index, &cvolumes, PaSetVolumeCallback, NULL))) {
  244. audio_volume->volume_flag = 1;
  245. }
  246. pa_operation_unref(paOperation);
  247. }
  248. }
  249. static void pa_sourcevolume_cb(pa_context* c, const pa_source_info* l, int eol, void* data)
  250. {
  251. rvc_audio_volume_t* audio_volume = (rvc_audio_volume_t*)data;
  252. /*
  253. * If eol is set to a positive number,
  254. * you're at the end of the list
  255. */
  256. if (eol > 0)
  257. return;
  258. //{
  259. // printf("AUDIO: =======[ Input Device #%d ]=======\n", source_index);
  260. // printf(" Description: %s\n", l->description);
  261. // printf(" Name: %s\n", l->name);
  262. // printf(" Index: %d\n", l->index);
  263. // printf(" SampleRate: %d\n", l->sample_spec.rate);
  264. // printf(" Latency: %llu (usec)\n", (long long unsigned) l->latency);
  265. // printf(" Configured Latency: %llu (usec)\n", (long long unsigned) l->configured_latency);
  266. // printf(" Card: %d\n", l->card);
  267. // printf(" monitor_of_sink_name: %s\n", l->monitor_of_sink_name);
  268. // printf(" driver: %s\n", l->driver);
  269. // if (l->active_port && l->active_port->name) {
  270. // printf(" name: %s\n", l->active_port->name);
  271. // }
  272. // if (l->active_port && l->active_port->description) {
  273. // printf(" description name: %s\n", l->active_port->description);
  274. // }
  275. // printf(" Volume channels: %d\n", l->volume.channels);
  276. // for (int i = 0; i < l->volume.channels; i++) {
  277. // printf(" Volume value: %d\n", l->volume.values[i]);
  278. // }
  279. // printf("\n");
  280. //}
  281. if (l->monitor_of_sink == PA_INVALID_INDEX)
  282. {
  283. if (strstr(l->description, audio_volume->strdevicename)){
  284. audio_volume->cvolumes = l->volume;
  285. audio_volume->volume_flag = 1;
  286. }
  287. }
  288. }
  289. static void pa_sinkvolume_cb(pa_context* c, const pa_sink_info* l, int eol, void* userdata)
  290. {
  291. rvc_audio_volume_t* audio_volume = (rvc_audio_volume_t*)userdata;
  292. /*
  293. * If eol is set to a positive number,
  294. * you're at the end of the list
  295. */
  296. if (eol > 0)
  297. return;
  298. //{
  299. // printf("AUDIO: =======[ Output Device #%d ]=======\n", sink_index);
  300. // printf(" Description: %s\n", l->description);
  301. // printf(" Name: %s\n", l->name);
  302. // printf(" Index: %d\n", l->index);
  303. // printf(" Channels: %d\n", l->channel_map.channels);
  304. // printf(" SampleRate: %d\n", l->sample_spec.rate);
  305. // printf(" Latency: %llu (usec)\n", (long long unsigned) l->latency);
  306. // printf(" Configured Latency: %llu (usec)\n", (long long unsigned) l->configured_latency);
  307. // printf(" Card: %d\n", l->card);
  308. // printf(" monitor_of_sink_name: %s\n", l->monitor_source_name);
  309. // printf(" driver: %s\n", l->driver);
  310. // printf(" n_ports: %d\n", l->n_ports);
  311. // printf(" name: %s\n", l->active_port->name);
  312. // printf(" description name: %s\n", l->active_port->description);
  313. // printf(" Volume channels: %d\n", l->volume.channels);
  314. // for (int i = 0; i < l->volume.channels; i++) {
  315. // printf(" Volume value: %d\n", l->volume.values[i]);
  316. // }
  317. // printf("\n");
  318. //}
  319. if (strstr(l->description, audio_volume->strdevicename)) {
  320. audio_volume->cvolumes = l->volume;
  321. audio_volume->volume_flag = 1;
  322. }
  323. //{
  324. // pa_cvolume cvolumes;
  325. // // Set the same volume for all channels
  326. // int ivolume = 65536;
  327. // pa_cvolume_set(&cvolumes, l->channel_map.channels, ivolume);
  328. // printf("%s:%d. audio_dev->id = %d, audio_dev->channels = %d, ivolume = %d.\n", __FUNCTION__, __LINE__, l->index, l->channel_map.channels, ivolume);
  329. // for (int i = 0; i < cvolumes.channels; i++) {
  330. // printf("%s:%d. cvolumes.values[%d] = %d.\n", __FUNCTION__, __LINE__, i, cvolumes.values[i]);
  331. // }
  332. // pa_operation* paOperation = NULL;
  333. // if (!(paOperation = pa_context_set_sink_volume_by_name(c, l->name, &cvolumes, PaSetVolumeCallback, NULL))) {
  334. // printf("pa_context_set_sink_volume_by_index() failed\n");
  335. // return;
  336. // }
  337. // pa_operation_unref(paOperation);
  338. //}
  339. }
  340. /*
  341. * pa_mainloop will call this function when it's ready to tell us
  342. * about a source (input).
  343. * This callback is pretty much identical to the previous
  344. * but it will only print the output devices
  345. * args:
  346. * c - pointer to pulse context
  347. * l - pointer to sink info
  348. * eol - end of list
  349. * data - pointer to user data (audio context)
  350. *
  351. * asserts:
  352. * none
  353. *
  354. * returns: none
  355. */
  356. static void pa_sinklist_cb(pa_context* c, const pa_sink_info* l, int eol, void* userdata)
  357. {
  358. rvc_audio_context_t* audio_ctx = (rvc_audio_context_t*)userdata;
  359. /*
  360. * If eol is set to a positive number,
  361. * you're at the end of the list
  362. */
  363. if (eol > 0)
  364. return;
  365. sink_index++;
  366. double my_latency = 0.0;
  367. int verbosity = 1;
  368. //if (verbosity > 0)
  369. //{
  370. // printf("AUDIO: =======[ Output Device #%d ]=======\n", sink_index);
  371. // printf(" Description: %s\n", l->description);
  372. // printf(" Name: %s\n", l->name);
  373. // printf(" Index: %d\n", l->index);
  374. // printf(" Channels: %d\n", l->channel_map.channels);
  375. // printf(" SampleRate: %d\n", l->sample_spec.rate);
  376. // printf(" Latency: %llu (usec)\n", (long long unsigned) l->latency);
  377. // printf(" Configured Latency: %llu (usec)\n", (long long unsigned) l->configured_latency);
  378. // printf(" Card: %d\n", l->card);
  379. // printf(" monitor_of_sink_name: %s\n", l->monitor_source_name);
  380. // printf(" driver: %s\n", l->driver);
  381. // printf(" n_ports: %d\n", l->n_ports);
  382. // printf(" name: %s\n", l->active_port->name);
  383. // printf(" description name: %s\n", l->active_port->description);
  384. // printf(" Volume channels: %d\n", l->volume.channels);
  385. // for (int i = 0; i < l->volume.channels; i++) {
  386. // printf(" Volume value: %d\n", l->volume.values[i]);
  387. // }
  388. // printf("\n");
  389. //}
  390. if (my_latency <= 0.0)
  391. my_latency = (double)latency_ms / 1000;
  392. audio_ctx->num_output_dev++;
  393. /*add device to list*/
  394. audio_ctx->list_output_devices = (rvc_audio_device_t*)realloc(audio_ctx->list_output_devices, audio_ctx->num_output_dev * sizeof(rvc_audio_device_t));
  395. if (audio_ctx->list_output_devices == NULL)
  396. {
  397. printf("AUDIO: FATAL memory allocation failure (pa_sinklist_cb): %s\n", strerror(errno));
  398. exit(-1);
  399. }
  400. /*fill device data*/
  401. audio_ctx->list_output_devices[audio_ctx->num_output_dev - 1].id = l->index; /*saves dev id*/
  402. strncpy(audio_ctx->list_output_devices[audio_ctx->num_output_dev - 1].name, l->name, MAX_PATH_EX-1);
  403. strncpy(audio_ctx->list_output_devices[audio_ctx->num_output_dev - 1].description, l->description, MAX_PATH-1);
  404. audio_ctx->list_output_devices[audio_ctx->num_output_dev - 1].channels = l->channel_map.channels;
  405. audio_ctx->list_output_devices[audio_ctx->num_output_dev - 1].samprate = l->sample_spec.rate;
  406. audio_ctx->list_output_devices[audio_ctx->num_output_dev - 1].low_latency = my_latency; /*in seconds*/
  407. audio_ctx->list_output_devices[audio_ctx->num_output_dev - 1].high_latency = my_latency; /*in seconds*/
  408. }
  409. /*
  410. * This callback gets called when our context changes state.
  411. * We really only care about when it's ready or if it has failed
  412. * args:
  413. * c -pointer to pulse context
  414. * data - pointer to user data
  415. *
  416. * asserts:
  417. * none
  418. *
  419. * retuns: none
  420. */
  421. static void pa_state_cb(pa_context* c, void* data)
  422. {
  423. pa_context_state_t state;
  424. int* pa_ready = (int*)data;
  425. state = pa_context_get_state(c);
  426. switch (state)
  427. {
  428. // These are just here for reference
  429. case PA_CONTEXT_UNCONNECTED:
  430. //printf("unconnected\n");
  431. break;
  432. case PA_CONTEXT_CONNECTING:
  433. case PA_CONTEXT_AUTHORIZING:
  434. case PA_CONTEXT_SETTING_NAME:
  435. default:
  436. //printf("no state\n");
  437. break;
  438. case PA_CONTEXT_FAILED:
  439. case PA_CONTEXT_TERMINATED:
  440. *pa_ready = 2;
  441. //printf("failed\n");
  442. break;
  443. case PA_CONTEXT_READY:
  444. *pa_ready = 1;
  445. //printf("ready\n");
  446. break;
  447. }
  448. }
  449. /*
  450. * clean up and disconnect
  451. * args:
  452. * pa_ctx - pointer to pulse context
  453. * pa_ml - pointer to pulse mainloop
  454. *
  455. * asserts:
  456. * none
  457. *
  458. * returns:
  459. * none
  460. */
  461. static void finish(pa_context* pa_ctx, pa_mainloop* pa_ml)
  462. {
  463. /* clean up and disconnect */
  464. pa_context_disconnect(pa_ctx);
  465. pa_context_unref(pa_ctx);
  466. pa_mainloop_free(pa_ml);
  467. }
  468. /*
  469. * iterate the main loop until all devices are listed
  470. * args:
  471. * audio_ctx - pointer to audio context
  472. *
  473. * asserts:
  474. * audio_ctx is not null
  475. *
  476. * returns: error code
  477. */
  478. int AudioMgrImpl::pa_get_devicelist()
  479. {
  480. /*assertions*/
  481. assert(m_audio_context != NULL);
  482. /* Define our pulse audio loop and connection variables */
  483. pa_mainloop* pa_ml;
  484. pa_mainloop_api* pa_mlapi;
  485. pa_operation* pa_op = NULL;
  486. pa_context* pa_ctx;
  487. /* We'll need these state variables to keep track of our requests */
  488. int state = 0;
  489. int pa_ready = 0;
  490. /* Create a mainloop API and connection to the default server */
  491. pa_ml = pa_mainloop_new();
  492. pa_mlapi = pa_mainloop_get_api(pa_ml);
  493. pa_ctx = pa_context_new(pa_mlapi, "getDevices");
  494. /* This function connects to the pulse server */
  495. if (pa_context_connect(pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0)
  496. {
  497. if(m_callback)
  498. m_callback->debug("AUDIO: PULSE - unable to connect to server: pa_context_connect failed");
  499. finish(pa_ctx, pa_ml);
  500. return -1;
  501. }
  502. /*
  503. * This function defines a callback so the server will tell us
  504. * it's state.
  505. * Our callback will wait for the state to be ready.
  506. * The callback will modify the variable to 1 so we know when we
  507. * have a connection and it's ready.
  508. * If there's an error, the callback will set pa_ready to 2
  509. */
  510. pa_context_set_state_callback(pa_ctx, pa_state_cb, &pa_ready);
  511. /*
  512. * Now we'll enter into an infinite loop until we get the data
  513. * we receive or if there's an error
  514. */
  515. for (;;)
  516. {
  517. /*
  518. * We can't do anything until PA is ready,
  519. * so just iterate the mainloop and continue
  520. */
  521. if (pa_ready == 0)
  522. {
  523. pa_mainloop_iterate(pa_ml, 1, NULL);
  524. continue;
  525. }
  526. ///* We couldn't get a connection to the server, so exit out */
  527. if (pa_ready == 2)
  528. {
  529. finish(pa_ctx, pa_ml);
  530. return -1;
  531. }
  532. /*
  533. * At this point, we're connected to the server and ready
  534. * to make requests
  535. */
  536. switch (state)
  537. {
  538. /* State 0: we haven't done anything yet */
  539. case 0:
  540. /*
  541. * This sends an operation to the server.
  542. * pa_sinklist_cb is our callback function and a pointer
  543. * o our devicelist will be passed to the callback
  544. * (audio_ctx) The operation ID is stored in the
  545. * pa_op variable
  546. */
  547. pa_op = pa_context_get_sink_info_list(
  548. pa_ctx,
  549. pa_sinklist_cb,
  550. (void*)m_audio_context);
  551. /* Update state for next iteration through the loop */
  552. state++;
  553. break;
  554. case 1:
  555. /*
  556. * Now we wait for our operation to complete.
  557. * When it's complete our pa_output_devicelist is
  558. * filled out, and we move along to the next state
  559. */
  560. if (pa_operation_get_state(pa_op) == PA_OPERATION_DONE)
  561. {
  562. pa_operation_unref(pa_op);
  563. /*
  564. * Now we perform another operation to get the
  565. * source(input device) list just like before.
  566. * This time we pass a pointer to our input structure
  567. */
  568. pa_op = pa_context_get_source_info_list(
  569. pa_ctx,
  570. pa_sourcelist_cb,
  571. (void*)m_audio_context);
  572. /* Update the state so we know what to do next */
  573. state++;
  574. }
  575. break;
  576. case 2:
  577. if (pa_operation_get_state(pa_op) == PA_OPERATION_DONE)
  578. {
  579. /*
  580. * Now we're done,
  581. * clean up and disconnect and return
  582. */
  583. pa_operation_unref(pa_op);
  584. finish(pa_ctx, pa_ml);
  585. return 0;
  586. }
  587. break;
  588. default:
  589. /* We should never see this state */
  590. if(m_callback)
  591. m_callback->debug("AUDIO: Pulse audio in state %d", state);
  592. return -1;
  593. }
  594. /*
  595. * Iterate the main loop and go again. The second argument is whether
  596. * or not the iteration should block until something is ready to be
  597. * done. Set it to zero for non-blocking.
  598. */
  599. pa_mainloop_iterate(pa_ml, 1, NULL);
  600. }
  601. finish(pa_ctx, pa_ml);
  602. return 0;
  603. }
  604. /*
  605. * get the number of available audio devices
  606. *
  607. * args:
  608. * binput - is input device
  609. * asserts:
  610. * audio_ctx is not null
  611. *
  612. * returns: number of listed audio devices
  613. */
  614. int AudioMgrImpl::audio_get_device_count(bool binput)
  615. {
  616. /*assertions*/
  617. assert(m_audio_context != NULL);
  618. if (binput){
  619. return m_audio_context->num_input_dev;
  620. }
  621. else {
  622. return m_audio_context->num_output_dev;
  623. }
  624. }
  625. /*
  626. * get the audio device referenced by index
  627. * args:
  628. * index - index of audio device
  629. *
  630. * asserts:
  631. * audio_ctx is not null
  632. *
  633. * returns: audio device referenced by index
  634. */
  635. rvc_audio_device_t* AudioMgrImpl::audio_get_input_device(int index)
  636. {
  637. /*assertions*/
  638. assert(m_audio_context != NULL);
  639. if (index >= m_audio_context->num_input_dev){
  640. //printf("AUDIO: (audio_get_input_device) bad index %i using %i\n",index, m_audio_context->num_input_dev - 1);
  641. index = m_audio_context->num_input_dev - 1;
  642. }
  643. if (index < 0){
  644. //printf("AUDIO: (audio_get_input_device) bad index %i using 0\n", index);
  645. index = 0;
  646. }
  647. return &m_audio_context->list_input_devices[index];
  648. }
  649. /*
  650. * get the output audio device referenced by index
  651. * args:
  652. * index - index of output audio device
  653. *
  654. * asserts:
  655. * audio_ctx is not null
  656. *
  657. * returns: output audio device referenced by index
  658. */
  659. rvc_audio_device_t* AudioMgrImpl::audio_get_output_device( int index)
  660. {
  661. /*assertions*/
  662. assert(m_audio_context != NULL);
  663. if (index >= m_audio_context->num_output_dev)
  664. {
  665. //printf("AUDIO: (audio_get_output_device) bad index %i using %i\n",index, m_audio_context->num_output_dev - 1);
  666. index = m_audio_context->num_output_dev - 1;
  667. }
  668. if (index < 0)
  669. {
  670. //printf("AUDIO: (audio_get_output_device) bad index %i using 0\n", index);
  671. index = 0;
  672. }
  673. return &m_audio_context->list_output_devices[index];
  674. }
  675. int AudioMgrImpl::audio_get_device_name(char* pstrbuf, size_t ulen, bool binput, int index)
  676. {
  677. int iret = -1;
  678. //模拟立体声
  679. const char stranalogstereo[] = { 0x20,0xe6,0xa8,0xa1,0xe6,0x8b,0x9f,0xe7,0xab,0x8b,0xe4,0xbd,0x93,0xe5,0xa3,0xb0,0 };
  680. //数字立体声
  681. const char strdigitalstereo[] = { 0x20,0xe6,0x95,0xb0,0xe5,0xad,0x97,0xe7,0xab,0x8b,0xe4,0xbd,0x93,0xe5,0xa3,0xb0,0 };
  682. //立体声
  683. const char strstereo[] = { 0x20,0xe7,0xab,0x8b,0xe4,0xbd,0x93,0xe5,0xa3,0xb0,0 };
  684. //多声道
  685. const char strmultistereo[] = { 0x20,0xe5,0xa4,0x9a,0xe5,0xa3,0xb0,0xe9,0x81,0x93,0 };
  686. rvc_audio_device_t* audio_device = NULL;
  687. if (binput){
  688. audio_device = audio_get_input_device(index);
  689. }
  690. else{
  691. audio_device = audio_get_output_device(index);
  692. }
  693. size_t unamelen = strlen(audio_device->description);
  694. if (ulen > unamelen){
  695. memcpy(pstrbuf, audio_device->description, ulen);
  696. char* pindex = NULL;
  697. if ((pindex = strstr(pstrbuf, stranalogstereo))||(pindex = strstr(pstrbuf, strdigitalstereo))){
  698. *pindex = 0;
  699. }
  700. if ((pindex = strstr(pstrbuf, strstereo)) || (pindex = strstr(pstrbuf, strmultistereo))) {
  701. *pindex = 0;
  702. }
  703. iret = 0;
  704. }
  705. return iret;
  706. }
  707. int AudioMgrImpl::audio_get_device_id(const char* pstrname, bool binput)
  708. {
  709. int iret = -1;
  710. if (NULL == pstrname){
  711. return iret;
  712. }
  713. int icount = audio_get_device_count(binput);
  714. if (icount > 0){
  715. for (int index = 0; index < icount; index++){
  716. rvc_audio_device_t* audio_device = NULL;
  717. if (binput) {
  718. audio_device = audio_get_input_device(index);
  719. }
  720. else {
  721. audio_device = audio_get_output_device(index);
  722. }
  723. if (NULL != audio_device){
  724. if (strstr(audio_device->description, pstrname)){
  725. iret = index;
  726. break;
  727. }
  728. }
  729. }
  730. }
  731. return iret;
  732. }
  733. int AudioMgrImpl::audio_get_device_volume(int* ivolume, const char* pstrname, bool binput)
  734. {
  735. int iret = -1;
  736. pa_mainloop* pa_ml;
  737. pa_mainloop_api* pa_mlapi;
  738. pa_operation* pa_op = NULL;
  739. pa_context* pa_ctx;
  740. /* We'll need these state variables to keep track of our requests */
  741. int state = 0;
  742. int pa_ready = 0;
  743. rvc_audio_volume_t rvc_volume = { 0 };
  744. strcpy(rvc_volume.strdevicename, pstrname);
  745. /* Create a mainloop API and connection to the default server */
  746. pa_ml = pa_mainloop_new();
  747. pa_mlapi = pa_mainloop_get_api(pa_ml);
  748. pa_ctx = pa_context_new(pa_mlapi, "get audio volume");
  749. /* This function connects to the pulse server */
  750. if (pa_context_connect(pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0)
  751. {
  752. if(m_callback)
  753. m_callback->debug("AUDIO: PULSE - unable to connect to server: pa_context_connect failed");
  754. finish(pa_ctx, pa_ml);
  755. return -1;
  756. }
  757. /*
  758. * This function defines a callback so the server will tell us
  759. * it's state.
  760. * Our callback will wait for the state to be ready.
  761. * The callback will modify the variable to 1 so we know when we
  762. * have a connection and it's ready.
  763. * If there's an error, the callback will set pa_ready to 2
  764. */
  765. pa_context_set_state_callback(pa_ctx, pa_state_cb, &pa_ready);
  766. /*
  767. * Now we'll enter into an infinite loop until we get the data
  768. * we receive or if there's an error
  769. */
  770. for (;;)
  771. {
  772. /*
  773. * We can't do anything until PA is ready,
  774. * so just iterate the mainloop and continue
  775. */
  776. if (pa_ready == 0)
  777. {
  778. pa_mainloop_iterate(pa_ml, 1, NULL);
  779. continue;
  780. }
  781. ///* We couldn't get a connection to the server, so exit out */
  782. if (pa_ready == 2)
  783. {
  784. finish(pa_ctx, pa_ml);
  785. return -1;
  786. }
  787. /*
  788. * At this point, we're connected to the server and ready
  789. * to make requests
  790. */
  791. if (0 == state){
  792. if (binput) {
  793. pa_op = pa_context_get_source_info_list(
  794. pa_ctx,
  795. pa_sourcevolume_cb,
  796. (void*)& rvc_volume);
  797. }
  798. else
  799. {
  800. pa_op = pa_context_get_sink_info_list(
  801. pa_ctx,
  802. pa_sinkvolume_cb,
  803. (void*)& rvc_volume);
  804. }
  805. state++;
  806. }
  807. if (rvc_volume.volume_flag){
  808. *ivolume = rvc_volume.cvolumes.values[0];
  809. pa_operation_unref(pa_op);
  810. break;
  811. }
  812. if (pa_operation_get_state(pa_op) == PA_OPERATION_DONE)
  813. {
  814. /*
  815. * Now we're done,
  816. * clean up and disconnect and return
  817. */
  818. pa_operation_unref(pa_op);
  819. finish(pa_ctx, pa_ml);
  820. return 0;
  821. }
  822. /*
  823. * Iterate the main loop and go again. The second argument is whether
  824. * or not the iteration should block until something is ready to be
  825. * done. Set it to zero for non-blocking.
  826. */
  827. pa_mainloop_iterate(pa_ml, 1, NULL);
  828. }
  829. finish(pa_ctx, pa_ml);
  830. return iret;
  831. }
  832. int AudioMgrImpl::audio_set_device_volume(int ivolume, const char* pstrname, bool binput)
  833. {
  834. int iret = -1;
  835. pa_mainloop* pa_ml;
  836. pa_mainloop_api* pa_mlapi;
  837. pa_operation* pa_op = NULL;
  838. pa_context* pa_ctx;
  839. /* We'll need these state variables to keep track of our requests */
  840. int state = 0;
  841. int pa_ready = 0;
  842. rvc_volume_set_t rvc_volume = { 0 };
  843. strcpy(rvc_volume.strdevicename, pstrname);
  844. rvc_volume.ivolume = ivolume;
  845. /* Create a mainloop API and connection to the default server */
  846. pa_ml = pa_mainloop_new();
  847. pa_mlapi = pa_mainloop_get_api(pa_ml);
  848. pa_ctx = pa_context_new(pa_mlapi, "set audio volume");
  849. /* This function connects to the pulse server */
  850. if (pa_context_connect(pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0)
  851. {
  852. if (m_callback)
  853. m_callback->debug("AUDIO: PULSE - unable to connect to server: pa_context_connect failed");
  854. finish(pa_ctx, pa_ml);
  855. return -1;
  856. }
  857. /*
  858. * This function defines a callback so the server will tell us
  859. * it's state.
  860. * Our callback will wait for the state to be ready.
  861. * The callback will modify the variable to 1 so we know when we
  862. * have a connection and it's ready.
  863. * If there's an error, the callback will set pa_ready to 2
  864. */
  865. pa_context_set_state_callback(pa_ctx, pa_state_cb, &pa_ready);
  866. /*
  867. * Now we'll enter into an infinite loop until we get the data
  868. * we receive or if there's an error
  869. */
  870. for (;;)
  871. {
  872. /*
  873. * We can't do anything until PA is ready,
  874. * so just iterate the mainloop and continue
  875. */
  876. if (pa_ready == 0)
  877. {
  878. pa_mainloop_iterate(pa_ml, 1, NULL);
  879. continue;
  880. }
  881. ///* We couldn't get a connection to the server, so exit out */
  882. if (pa_ready == 2)
  883. {
  884. finish(pa_ctx, pa_ml);
  885. return -1;
  886. }
  887. /*
  888. * At this point, we're connected to the server and ready
  889. * to make requests
  890. */
  891. if (0 == state) {
  892. if (binput) {
  893. pa_op = pa_context_get_source_info_list(
  894. pa_ctx,
  895. pa_setsourcevolume_cb,
  896. (void*)&rvc_volume);
  897. }
  898. else
  899. {
  900. pa_op = pa_context_get_sink_info_list(
  901. pa_ctx,
  902. pa_setsinkvolume_cb,
  903. (void*)&rvc_volume);
  904. }
  905. state++;
  906. }
  907. if (rvc_volume.volume_flag) {
  908. pa_operation_unref(pa_op);
  909. break;
  910. }
  911. if (pa_operation_get_state(pa_op) == PA_OPERATION_DONE)
  912. {
  913. /*
  914. * Now we're done,
  915. * clean up and disconnect and return
  916. */
  917. pa_operation_unref(pa_op);
  918. finish(pa_ctx, pa_ml);
  919. return 0;
  920. }
  921. /*
  922. * Iterate the main loop and go again. The second argument is whether
  923. * or not the iteration should block until something is ready to be
  924. * done. Set it to zero for non-blocking.
  925. */
  926. pa_mainloop_iterate(pa_ml, 1, NULL);
  927. }
  928. finish(pa_ctx, pa_ml);
  929. return iret;
  930. }
  931. int AudioMgrImpl::audio_mgr_initialize()
  932. {
  933. int iret = -1;
  934. m_audio_context = (rvc_audio_context_t*)calloc(1, sizeof(rvc_audio_context_t));
  935. if (NULL == m_audio_context){
  936. if (m_callback)
  937. m_callback->debug("%s:%d couldn't allocate audio context.", __FUNCTION__, __LINE__);
  938. return iret;
  939. }
  940. iret = audio_init_pulseaudio();
  941. /*force a valid number of channels*/
  942. if (m_audio_context->channels > 2) {
  943. m_audio_context->channels = 2;
  944. }
  945. return iret;
  946. }
  947. /*
  948. * close and clean audio context for pulse audio api
  949. *
  950. * asserts:
  951. * none
  952. *
  953. * returns: none
  954. */
  955. int AudioMgrImpl::audio_close_pulseaudio()
  956. {
  957. int iret = -1;
  958. if (m_audio_context == NULL){
  959. return iret;
  960. }
  961. if (m_audio_context->stream_flag == AUDIO_STRM_ON) {
  962. stop_audio_capture();
  963. }
  964. if (NULL != m_audio_context->list_input_devices) {
  965. free(m_audio_context->list_input_devices);
  966. m_audio_context->list_input_devices = NULL;
  967. }
  968. if (NULL != m_audio_context->list_output_devices){
  969. free(m_audio_context->list_output_devices);
  970. m_audio_context->list_output_devices = NULL;
  971. }
  972. if (NULL != m_audio_context->capture_buff) {
  973. free(m_audio_context->capture_buff);
  974. m_audio_context->capture_buff = NULL;
  975. }
  976. free(m_audio_context);
  977. m_audio_context = NULL;
  978. iret = 0;
  979. return iret;
  980. }
  981. /*
  982. * stop and join the main loop iteration thread
  983. *
  984. * asserts:
  985. * audio_ctx is not null
  986. *
  987. * returns: error code
  988. */
  989. int AudioMgrImpl::stop_audio_capture()
  990. {
  991. /*assertions*/
  992. assert(m_audio_context != NULL);
  993. m_audio_context->stream_flag = AUDIO_STRM_OFF;
  994. if (0 == __THREAD_JOIN(m_readthread)){
  995. if (m_callback)
  996. m_callback->debug("read thread join success!");
  997. }
  998. else{
  999. if (m_callback)
  1000. m_callback->debug("read thread join failed!");
  1001. }
  1002. return 0;
  1003. }
  1004. int AudioMgrImpl::audio_mgr_terminate()
  1005. {
  1006. int iret = -1;
  1007. /*assertions*/
  1008. assert(m_audio_context != NULL);
  1009. /* thread must be joined before destroying the mutex
  1010. * so no need to unlock before destroying it
  1011. */
  1012. iret = audio_close_pulseaudio();
  1013. //if (!m_paMainloop) {
  1014. // return 0;
  1015. //}
  1016. //// Disconnect the context
  1017. //if (m_paContext) {
  1018. // (pa_context_disconnect)(m_paContext);
  1019. //}
  1020. //// Unreference the context
  1021. //if (m_paContext) {
  1022. // (pa_context_unref)(m_paContext);
  1023. //}
  1024. //m_paContext = NULL;
  1025. //
  1026. //pa_mainloop_free(m_paMainloop);
  1027. //m_paMainloop = NULL;
  1028. return iret;
  1029. }
  1030. /*
  1031. * update pulse audio latency
  1032. * args:
  1033. * s - pointer to pa_stream
  1034. *
  1035. * asserts:
  1036. * none
  1037. *
  1038. * returns:none
  1039. */
  1040. static void get_latency(pa_stream* s)
  1041. {
  1042. pa_usec_t l;
  1043. int negative;
  1044. pa_stream_get_timing_info(s);
  1045. if (pa_stream_get_latency(s, &l, &negative) != 0)
  1046. {
  1047. fprintf(stderr, "AUDIO: Pulseaudio pa_stream_get_latency() failed\n");
  1048. return;
  1049. }
  1050. //latency = l * (negative?-1:1);
  1051. latency = l; /*can only be negative in monitoring streams*/
  1052. }
  1053. /*
  1054. * audio record callback
  1055. * args:
  1056. * s - pointer to pa_stream
  1057. * length - buffer length
  1058. * data - pointer to user data
  1059. *
  1060. * asserts:
  1061. * none
  1062. *
  1063. * returns: none
  1064. */
  1065. static void stream_request_cb(pa_stream* s, size_t length, void* data)
  1066. {
  1067. rvc_audio_context_t* audio_ctx = (rvc_audio_context_t*)data;
  1068. if (audio_ctx->channels == 0){
  1069. return;
  1070. }
  1071. if (audio_ctx->samprate == 0){
  1072. return;
  1073. }
  1074. uint64_t frame_length = NSEC_PER_SEC / audio_ctx->samprate; /*in nanosec*/
  1075. int64_t ts = 0;
  1076. int64_t buff_ts = 0;
  1077. uint32_t i = 0;
  1078. while (pa_stream_readable_size(s) > 0)
  1079. {
  1080. const void* inputBuffer;
  1081. size_t length;
  1082. /*read from stream*/
  1083. if (pa_stream_peek(s, &inputBuffer, &length) < 0){
  1084. return;
  1085. }
  1086. else {
  1087. //printf("%s:%d pa_stream_peek audio length is %d.\n", __FUNCTION__, __LINE__, length);
  1088. }
  1089. if (length == 0)
  1090. {
  1091. return; /*buffer is empty*/
  1092. }
  1093. get_latency(s);
  1094. ts = ns_time_monotonic() - (latency * 1000);
  1095. if (audio_ctx->last_ts <= 0)
  1096. audio_ctx->last_ts = ts;
  1097. uint32_t numSamples = (uint32_t)length / sizeof(sample_t);
  1098. audio_ctx->audio_param.on_audio_callback(inputBuffer, length, audio_ctx->audio_param.user_data);
  1099. pa_stream_drop(s); /*clean the samples*/
  1100. }
  1101. }
  1102. /*
  1103. * Iterate the main loop while recording is on.
  1104. * This function runs under it's own thread called by audio_pulse_start
  1105. * args:
  1106. * data - pointer to user data (audio context)
  1107. *
  1108. * asserts:
  1109. * data is not null
  1110. *
  1111. * returns: pointer to error code
  1112. */
  1113. void* pulse_read_audio(void* data)
  1114. {
  1115. AudioMgrImpl* audio_mgr = (AudioMgrImpl*)data;
  1116. assert(audio_mgr != NULL);
  1117. IAudioMgrCallback* callback = audio_mgr->audio_get_callback();
  1118. assert(callback != NULL);
  1119. rvc_audio_context_t* audio_ctx = audio_mgr->audio_get_context();
  1120. /*assertions*/
  1121. assert(audio_ctx != NULL);
  1122. pa_mainloop* pa_ml;
  1123. pa_mainloop_api* pa_mlapi;
  1124. pa_buffer_attr bufattr;
  1125. pa_stream* recordstream = NULL; // pulse audio stream
  1126. pa_context* pa_ctx; //pulse context
  1127. pa_sample_spec ss;
  1128. pa_stream_flags_t flags = PA_STREAM_NOFLAGS;
  1129. int32_t pastream_flag = (int32_t)PA_STREAM_NOFLAGS;
  1130. int r;
  1131. int pa_ready = 0;
  1132. /* Create a mainloop API and connection to the default server */
  1133. pa_ml = pa_mainloop_new();
  1134. pa_mlapi = pa_mainloop_get_api(pa_ml);
  1135. pa_ctx = pa_context_new(pa_mlapi, "rvc pulse API");
  1136. if (pa_context_connect(pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0)
  1137. {
  1138. callback->debug("AUDIO: PULSE - unable to connect to server: pa_context_connect failed.");
  1139. finish(pa_ctx, pa_ml);
  1140. return ((void*)-1);
  1141. }
  1142. /*
  1143. * This function defines a callback so the server will tell us it's state.
  1144. * Our callback will wait for the state to be ready. The callback will
  1145. * modify the variable to 1 so we know when we have a connection and it's
  1146. * ready.
  1147. * If there's an error, the callback will set pa_ready to 2
  1148. */
  1149. pa_context_set_state_callback(pa_ctx, pa_state_cb, &pa_ready);
  1150. /*
  1151. * This function defines a time event callback (called every TIME_EVENT_USEC)
  1152. */
  1153. //pa_context_rttime_new(pa_ctx, pa_rtclock_now() + TIME_EVENT_USEC, time_event_callback, NULL);
  1154. /*
  1155. * We can't do anything until PA is ready, so just iterate the mainloop
  1156. * and continue
  1157. */
  1158. while (pa_ready == 0){
  1159. pa_mainloop_iterate(pa_ml, 1, NULL);
  1160. }
  1161. if (pa_ready == 2){
  1162. finish(pa_ctx, pa_ml);
  1163. return ((void*)-1);
  1164. }
  1165. /* set the sample spec (frame rate, channels and format) */
  1166. ss.rate = audio_ctx->samprate;
  1167. ss.channels = audio_ctx->channels;
  1168. ss.format = audio_ctx->eformat/*PA_SAMPLE_FLOAT32LE*/; /*for PCM -> PA_SAMPLE_S16LE*/
  1169. recordstream = pa_stream_new(pa_ctx, "Record", &ss, NULL);
  1170. if (!recordstream)
  1171. callback->debug("AUDIO: (pulse audio) pa_stream_new failed (chan:%d rate:%d)",
  1172. ss.channels, ss.rate);
  1173. /* define the callbacks */
  1174. pa_stream_set_read_callback(recordstream, stream_request_cb, (void*)audio_ctx);
  1175. // Set properties of the record buffer
  1176. pa_zero(bufattr);
  1177. /* optimal value for all is (uint32_t)-1 ~= 2 sec */
  1178. bufattr.maxlength = (uint32_t)-1;
  1179. bufattr.prebuf = (uint32_t)-1;
  1180. bufattr.minreq = (uint32_t)-1;
  1181. if (audio_ctx->latency > 0){
  1182. bufattr.fragsize = bufattr.tlength = pa_usec_to_bytes((audio_ctx->latency * 1000) * PA_USEC_PER_MSEC, &ss);
  1183. uint32_t uvsersion = pa_context_get_protocol_version(pa_ctx);
  1184. if (uvsersion >= RVC_PA_ADJUST_LATENCY_PROTOCOL_VERSION) {
  1185. pastream_flag |= PA_STREAM_ADJUST_LATENCY;
  1186. }
  1187. callback->debug("pa protocol version is %d.", uvsersion);
  1188. }
  1189. else {
  1190. bufattr.fragsize = bufattr.tlength = (uint32_t)-1;
  1191. }
  1192. pastream_flag |= PA_STREAM_INTERPOLATE_TIMING;
  1193. pastream_flag |= PA_STREAM_AUTO_TIMING_UPDATE;
  1194. char* dev = audio_ctx->list_input_devices[audio_ctx->device].name;
  1195. callback->debug("AUDIO: (pulse audio) connecting to device %s (channels %d rate %d)",
  1196. dev, ss.channels, ss.rate);
  1197. r = pa_stream_connect_record(recordstream, dev, &bufattr, (pa_stream_flags_t)pastream_flag);
  1198. if (r < 0)
  1199. {
  1200. callback->debug("AUDIO: (pulse audio) skip latency adjustment");
  1201. /*
  1202. * Old pulse audio servers don't like the ADJUST_LATENCY flag,
  1203. * so retry without that
  1204. */
  1205. r = pa_stream_connect_record(recordstream, dev, &bufattr,
  1206. pa_stream_flags_t((int32_t)PA_STREAM_INTERPOLATE_TIMING |
  1207. (int32_t)PA_STREAM_AUTO_TIMING_UPDATE));
  1208. }
  1209. else {
  1210. callback->debug("pa_stream_connect_record success!");
  1211. }
  1212. if (r < 0)
  1213. {
  1214. callback->debug("AUDIO: (pulse audio) pa_stream_connect_record failed");
  1215. finish(pa_ctx, pa_ml);
  1216. return ((void*)-1);
  1217. }
  1218. get_latency(recordstream);
  1219. /*
  1220. * Iterate the main loop while streaming. The second argument is whether
  1221. * or not the iteration should block until something is ready to be
  1222. * done. Set it to zero for non-blocking.
  1223. */
  1224. while (audio_ctx->stream_flag == AUDIO_STRM_ON){
  1225. pa_mainloop_iterate(pa_ml, 1, NULL);
  1226. }
  1227. callback->debug("AUDIO: (pulse audio) stream terminated(%i)", audio_ctx->stream_flag);
  1228. pa_stream_disconnect(recordstream);
  1229. pa_stream_unref(recordstream);
  1230. finish(pa_ctx, pa_ml);
  1231. return ((void*)0);
  1232. }
  1233. int AudioMgrImpl::set_audio_capture_params(audiocap_param_t* param)
  1234. {
  1235. assert(param != NULL);
  1236. audio_set_pulseaudio_device(param->ideviceid);
  1237. audio_set_pulsecap_params(param);
  1238. return 0;
  1239. }
  1240. /*
  1241. * set audio device
  1242. * index - device index to set
  1243. *
  1244. * asserts:
  1245. * audio_ctx is not null
  1246. *
  1247. * returns: none
  1248. */
  1249. int AudioMgrImpl::audio_set_pulseaudio_device(int index)
  1250. {
  1251. /*assertions*/
  1252. assert(m_audio_context != NULL);
  1253. if (index >= m_audio_context->num_input_dev) {
  1254. m_audio_context->device = m_audio_context->num_input_dev - 1;
  1255. }
  1256. else if (index >= 0) {
  1257. m_audio_context->device = index;
  1258. }
  1259. int verbosity = 1;
  1260. if (verbosity > 0) {
  1261. printf("AUDIO: Pulseaudio device changed to %i\n", m_audio_context->device);
  1262. printf("AUDIO: Pulseaudio device description is %s\n", m_audio_context->list_input_devices[m_audio_context->device].description);
  1263. }
  1264. m_audio_context->latency = m_audio_context->list_input_devices[m_audio_context->device].high_latency;
  1265. m_audio_context->channels = m_audio_context->list_input_devices[m_audio_context->device].channels;
  1266. if (m_audio_context->channels > 2){
  1267. m_audio_context->channels = 2;/*limit it to stereo input*/
  1268. }
  1269. m_audio_context->samprate = m_audio_context->list_input_devices[m_audio_context->device].samprate;
  1270. return 0;
  1271. }
  1272. int AudioMgrImpl::audio_set_pulsecap_params(audiocap_param_t* param)
  1273. {
  1274. assert(param != NULL);
  1275. m_audio_context->channels = param->ichannels;
  1276. if (m_audio_context->channels > 2) {
  1277. m_audio_context->channels = 2;/*limit it to stereo input*/
  1278. }
  1279. m_audio_context->samprate = param->isamprate;
  1280. m_audio_context->eformat = pa_sample_format_t(param->isampleformat);
  1281. m_audio_context->audio_param.on_audio_callback = param->on_audio_callback;
  1282. m_audio_context->audio_param.user_data = param->user_data;
  1283. m_audio_context->latency = param->flatency;
  1284. //m_audio_context->samprate = m_audio_context->list_input_devices[m_audio_context->device].samprate;
  1285. }
  1286. /*
  1287. * set the current latency
  1288. *
  1289. * asserts:
  1290. * audio_ctx is not null
  1291. *
  1292. * returns: none
  1293. */
  1294. void AudioMgrImpl::audio_set_latency(double latency)
  1295. {
  1296. /*assertions*/
  1297. assert(m_audio_context != NULL);
  1298. m_audio_context->latency = latency;
  1299. }
  1300. rvc_audio_context_t* AudioMgrImpl::audio_get_context()
  1301. {
  1302. return m_audio_context;
  1303. }
  1304. IAudioMgrCallback* AudioMgrImpl::audio_get_callback()
  1305. {
  1306. return m_callback;
  1307. }
  1308. int AudioMgrImpl::start_audio_capture()
  1309. {
  1310. /*assertions*/
  1311. assert(m_audio_context != NULL);
  1312. m_audio_context->stream_flag = AUDIO_STRM_ON;
  1313. //printf("%s:%d stream_flag = %d, audio context is 0x%0x.\n",__FUNCTION__, __LINE__, m_audio_context->stream_flag, m_audio_context);
  1314. /* start audio capture thread */
  1315. if (__THREAD_CREATE(&m_readthread, pulse_read_audio, this)){
  1316. if (m_callback)
  1317. m_callback->debug("AUDIO: (pulse audio) read thread creation failed");
  1318. m_audio_context->stream_flag = AUDIO_STRM_OFF;
  1319. return (-1);
  1320. }
  1321. else {
  1322. if (m_callback)
  1323. m_callback->debug("AUDIO: (pulse audio) read thread creation success, and thread id is %u.", m_readthread);
  1324. }
  1325. return 0;
  1326. }
  1327. int AudioMgrImpl::AudioPulseInit()
  1328. {
  1329. return 0;
  1330. //return (int)m_audio_pulse->Init();
  1331. }