libaudiorender.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. // libaudiorender.cpp : Defines the exported functions for the DLL application.
  2. //
  3. #include "stdafx.h"
  4. #define _CRT_SECURE_NO_WARNINGS
  5. #include "libaudiorender.h"
  6. #include "SpBase.h"
  7. #define REC_COMMON_REMOTEAUDIO_SHM_QUEUE "rvc.shm.agentaudio.q" //0
  8. #define REC_COMMON_AUDIO_SALES_SHM_QUEUE "rvc.shm.sales_audio.q" //1
  9. #ifndef RVC_AUDIO_FRAME_SIZE
  10. #define RVC_AUDIO_FRAME_SIZE 320
  11. #endif
  12. #ifndef RVC_AUDIO_FREQUENCY
  13. #define RVC_AUDIO_FREQUENCY 8000
  14. #endif
  15. #ifndef RVC_AUDIO_BUFFER_LEN
  16. #define RVC_AUDIO_BUFFER_LEN 512
  17. #endif
  18. #ifndef RVC_DEFAULT_BITPERSAMPLE
  19. #define RVC_DEFAULT_BITPERSAMPLE 16
  20. #endif
  21. AudioRenderImpl::AudioRenderImpl()
  22. {
  23. m_pAudioCaptureClient = NULL;
  24. m_pAudioClient = NULL;
  25. m_pMMDevice = NULL;
  26. m_hEventStop = NULL;
  27. m_hTimerWakeUp = NULL;
  28. m_hTask = NULL;
  29. m_pwfx = NULL;
  30. m_iQueueNumber = 0;
  31. m_audio_cap = NULL;
  32. m_frame_format = NULL;
  33. memset(m_strFilePathName, 0, MAX_PATH);
  34. m_bRecordPCM = false;
  35. }
  36. bool AudioRenderImpl::InitAudioFrame(audio_frame* pframe)
  37. {
  38. bool bret = false;
  39. if (NULL != pframe){
  40. pframe->bitspersample = RVC_DEFAULT_BITPERSAMPLE;
  41. pframe->format = 1;
  42. pframe->nchannels = 1;
  43. pframe->samplespersec = RVC_AUDIO_FREQUENCY;
  44. pframe->framesize = RVC_AUDIO_FRAME_SIZE;
  45. pframe->data = NULL;
  46. bret = true;
  47. }
  48. return bret;
  49. }
  50. DWORD AudioRenderImpl::pfThreadFunc(LPVOID lpThreadParameter)
  51. {
  52. AudioRenderImpl* pCapture = (AudioRenderImpl*)lpThreadParameter;
  53. pCapture->RenderFunc();
  54. return 0;
  55. }
  56. void AudioRenderImpl::LogRenderInfo()
  57. {
  58. uint32_t uConvertRatio = 1;
  59. if (NULL != m_frame_format){
  60. if (m_frame_format->samplespersec&&m_frame_format->nchannels&&m_frame_format->bitspersample){
  61. uConvertRatio = (m_pwfx->nSamplesPerSec*m_pwfx->nChannels*m_pwfx->wBitsPerSample)/(m_frame_format->samplespersec*m_frame_format->nchannels*m_frame_format->bitspersample);
  62. }
  63. }
  64. Debug("current speaker render audio convert ratio is %d.", uConvertRatio);
  65. eSpeakerSamplingDepthRate eSampleType = GetSpeakerSampleRate(m_pwfx->wBitsPerSample, m_pwfx->nSamplesPerSec);
  66. Debug("Speaker Sample Type is %d.", eSampleType);
  67. }
  68. void AudioRenderImpl::Debug( const char *fmt, ... )
  69. {
  70. va_list arg;
  71. va_start(arg, fmt);
  72. vDbg(fmt, arg);
  73. va_end(arg);
  74. }
  75. void AudioRenderImpl::OnRenderFailed()
  76. {
  77. }
  78. void AudioRenderImpl::OnAudioRenderExcption()
  79. {
  80. }
  81. int AudioRenderImpl::StartRender(int iQueue, void* pFrameformat, const char* pSwitchName)
  82. {
  83. m_iQueueNumber = iQueue;
  84. if (NULL != m_frame_format){
  85. delete m_frame_format;
  86. m_frame_format = NULL;
  87. }
  88. m_frame_format = new audio_frame();
  89. if (NULL != m_frame_format){
  90. if (NULL != pFrameformat){
  91. m_frame_format->bitspersample = ((audio_frame*)pFrameformat)->bitspersample;
  92. m_frame_format->nchannels = ((audio_frame*)pFrameformat)->nchannels;
  93. m_frame_format->format = ((audio_frame*)pFrameformat)->format;
  94. m_frame_format->samplespersec = ((audio_frame*)pFrameformat)->samplespersec;
  95. m_frame_format->framesize = ((audio_frame*)pFrameformat)->framesize;
  96. }
  97. else{
  98. InitAudioFrame(m_frame_format);
  99. }
  100. }
  101. if (NULL != pSwitchName){
  102. size_t ulen = strlen(pSwitchName);
  103. if (ulen >= MAX_PATH){
  104. ulen = MAX_PATH - 1;
  105. }
  106. memcpy(m_strFilePathName, pSwitchName, ulen);
  107. if (strlen(m_strFilePathName) > 0){
  108. m_bRecordPCM = true;
  109. }
  110. }
  111. if (InitQueueInfo(iQueue)){
  112. return -1;
  113. }
  114. CoInitialize(NULL);
  115. IMMDeviceEnumerator *pMMDeviceEnumerator = NULL;
  116. HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL,
  117. __uuidof(IMMDeviceEnumerator), (void**)&pMMDeviceEnumerator);
  118. if (FAILED(hr)){
  119. CoUninitialize();
  120. return -1;
  121. }
  122. // get the default render endpoint
  123. hr = pMMDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &m_pMMDevice);
  124. if (FAILED(hr)){
  125. CoUninitialize();
  126. return -1;
  127. }
  128. pMMDeviceEnumerator->Release();
  129. m_hEventStop = CreateEvent(NULL, TRUE, FALSE, NULL);
  130. if (m_hEventStop == NULL){
  131. CoUninitialize();
  132. return -1;
  133. }
  134. hr = m_pMMDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&m_pAudioClient);
  135. if (FAILED(hr)){
  136. goto error;
  137. }
  138. REFERENCE_TIME hnsDefaultDevicePeriod(0);
  139. if (NULL != m_pAudioClient){
  140. hr = m_pAudioClient->GetDevicePeriod(&hnsDefaultDevicePeriod, NULL);
  141. if (FAILED(hr)){
  142. goto error;
  143. }
  144. }
  145. else{
  146. goto error;
  147. }
  148. hr = m_pAudioClient->GetMixFormat(&m_pwfx);
  149. if (FAILED(hr)){
  150. goto error;
  151. }
  152. else{
  153. Debug("speaker render format is 0x%08x, channels is %d, samples rate is %d, buffer size is %d, block size of data is %d.",m_pwfx->wFormatTag, m_pwfx->nChannels, m_pwfx->nSamplesPerSec, m_pwfx->nAvgBytesPerSec, m_pwfx->nBlockAlign);
  154. Debug("destination audio frame format is %d, samples rate is %d, bits per sample is %d, channels number is %d.", m_frame_format->format, m_frame_format->samplespersec, m_frame_format->bitspersample, m_frame_format->nchannels);
  155. }
  156. if (!AdjustFormatTo16Bits(m_pwfx)){
  157. goto error;
  158. }
  159. m_hTimerWakeUp = CreateWaitableTimer(NULL, FALSE, NULL);
  160. if (m_hTimerWakeUp == NULL){
  161. goto error;
  162. }
  163. if (NULL != m_pAudioClient){
  164. hr = m_pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_LOOPBACK, 0, 0, m_pwfx, 0);
  165. if (FAILED(hr)){
  166. goto error;
  167. }
  168. }
  169. else{
  170. goto error;
  171. }
  172. if (NULL != m_pAudioClient){
  173. hr = m_pAudioClient->GetService(__uuidof(IAudioCaptureClient), (void**)&m_pAudioCaptureClient);
  174. if (FAILED(hr)){
  175. goto error;
  176. }
  177. }
  178. else{
  179. goto error;
  180. }
  181. DWORD nTaskIndex = 0;
  182. m_hTask = AvSetMmThreadCharacteristics("Capture", &nTaskIndex);
  183. if (NULL == m_hTask){
  184. goto error;
  185. }
  186. LARGE_INTEGER liFirstFire;
  187. liFirstFire.QuadPart = -hnsDefaultDevicePeriod / 2; // negative means relative time
  188. LONG lTimeBetweenFires = (LONG)hnsDefaultDevicePeriod / 2 / (10 * 1000); // convert to milliseconds
  189. BOOL bOK = SetWaitableTimer(m_hTimerWakeUp, &liFirstFire, lTimeBetweenFires, NULL, NULL, FALSE);
  190. if (!bOK){
  191. goto error;
  192. }
  193. if (NULL != m_pAudioClient){
  194. hr = m_pAudioClient->Start();
  195. if (FAILED(hr)){
  196. goto error;
  197. }
  198. }
  199. else{
  200. goto error;
  201. }
  202. m_hThread = CreateThread(NULL, 0, pfThreadFunc, this, 0, 0);
  203. if (m_hThread == NULL){
  204. goto error;
  205. }
  206. CoUninitialize();
  207. return 0;
  208. error:
  209. Close();
  210. CoUninitialize();
  211. return -1;
  212. }
  213. uint32_t AudioRenderImpl::ConvertDouble2SingleChannel(char* pDstBuf, const uint32_t uDstLen, const unsigned char* pSrcBuf, uint32_t uSrcLen, uint32_t uBitDeepth)
  214. {
  215. uint32_t uRet = 0;
  216. uint32_t uOneChannelLen = uSrcLen/2;
  217. uint32_t i = 0;
  218. for (; i < uOneChannelLen/2 && i < uDstLen/uBitDeepth; i++){
  219. memcpy((uint16_t*)pDstBuf + i, ((uint32_t*)(pSrcBuf))+i, uBitDeepth);
  220. }
  221. if (i == uOneChannelLen/2){
  222. uRet = uOneChannelLen;
  223. }
  224. return uRet;
  225. }
  226. eSpeakerSamplingDepthRate AudioRenderImpl::GetSpeakerSampleRate(uint32_t udepth, uint32_t usamplerate)
  227. {
  228. eSpeakerSamplingDepthRate eType = eSixteenBitsDVD;
  229. if (16 == udepth){
  230. switch(usamplerate)
  231. {
  232. case 44100:
  233. eType = eSixteenBitsCD;
  234. break;
  235. case 48000:
  236. eType = eSixteenBitsDVD;
  237. break;
  238. case 96000:
  239. eType = eSixteenBitsStatdioLow;
  240. break;
  241. case 192000:
  242. eType = eSixteenBitsStatdioHigh;
  243. break;
  244. }
  245. }
  246. else if (24 == udepth){
  247. switch(usamplerate)
  248. {
  249. case 44100:
  250. eType = eTwentyfourStatdioA;
  251. break;
  252. case 48000:
  253. eType = eTwentyfourStatdioB;
  254. break;
  255. case 96000:
  256. eType = eTwentyfourStatdioC;
  257. break;
  258. case 192000:
  259. eType = eTwentyfourStatdioD;
  260. break;
  261. }
  262. }
  263. return eType;
  264. }
  265. int AudioRenderImpl::InitQueueInfo(int iQueue)
  266. {
  267. int iRet = -1;
  268. char* pQueueName = NULL;
  269. if (0 == iQueue){
  270. pQueueName = REC_COMMON_REMOTEAUDIO_SHM_QUEUE;
  271. }
  272. else {
  273. pQueueName = REC_COMMON_AUDIO_SALES_SHM_QUEUE;
  274. }
  275. if (NULL != pQueueName){
  276. m_audio_cap = new Clibaudioqueue(pQueueName);
  277. if (NULL != m_audio_cap){
  278. iRet = 0;
  279. Debug("audio render insert queue name is %s.", pQueueName);
  280. }
  281. }
  282. return iRet;
  283. }
  284. uint32_t AudioRenderImpl::TranslateBuffer2DestFrameFormat(spx_int16_t* pOutAudio, spx_uint32_t* pAudioLen, spx_uint32_t uAudioBufferLen, unsigned char* pCbBuffer, const uint32_t uBufferLen, SpeexResamplerState *st, const audio_frame* pDestFrameFormat)
  285. {
  286. uint32_t uRet = 0;
  287. uint32_t uSingleChannelDataLen = uBufferLen;
  288. uint32_t uSingleChannelBufferLen = 0;
  289. char* pSingleChannelBuf = (char*)malloc(uBufferLen*sizeof(char));
  290. if (NULL != pSingleChannelBuf){
  291. memset(pSingleChannelBuf, 0, uBufferLen*sizeof(char));
  292. uSingleChannelBufferLen = uBufferLen*sizeof(char);
  293. }
  294. if (eDoubleChannel == m_pwfx->nChannels){
  295. if (eSingleChannel == pDestFrameFormat->nchannels){
  296. uSingleChannelDataLen = ConvertDouble2SingleChannel(pSingleChannelBuf, uSingleChannelBufferLen, pCbBuffer, uBufferLen, m_pwfx->wBitsPerSample/8);
  297. }
  298. else{
  299. memcpy(pSingleChannelBuf, pCbBuffer, uBufferLen);
  300. }
  301. }
  302. else{
  303. if (eSingleChannel == pDestFrameFormat->nchannels){
  304. memcpy(pSingleChannelBuf, pCbBuffer, uBufferLen);
  305. }
  306. else{
  307. Debug("not support single channel convert to double channels.");
  308. }
  309. }
  310. spx_uint32_t uInLen = uSingleChannelDataLen;
  311. int iRet = speex_resampler_process_int(st, 0, (spx_int16_t*)pSingleChannelBuf, &uInLen, pOutAudio, &uAudioBufferLen);
  312. if (RESAMPLER_ERR_SUCCESS == iRet){
  313. *pAudioLen = uAudioBufferLen;
  314. uRet = uAudioBufferLen;
  315. }
  316. if (NULL != pSingleChannelBuf){
  317. free(pSingleChannelBuf);
  318. pSingleChannelBuf = NULL;
  319. }
  320. return uRet;
  321. }
  322. void AudioRenderImpl::RenderFunc()
  323. {
  324. HANDLE waitArray[2] = { m_hEventStop, m_hTimerWakeUp };
  325. DWORD dwWaitResult;
  326. UINT32 nNextPacketSize(0);
  327. BYTE *pData = NULL;
  328. UINT32 nNumFramesToRead;
  329. DWORD dwFlags;
  330. CoInitialize(NULL);
  331. SpeexResamplerState *st = NULL;
  332. int err = 0;
  333. spx_int16_t OutAudioBuffer[RVC_AUDIO_BUFFER_LEN] = {0};
  334. spx_uint32_t uIndex = 0;
  335. spx_uint32_t uValidAudioLen = 0;
  336. spx_uint32_t uLeftBufferLen = RVC_AUDIO_BUFFER_LEN;
  337. FILE* pRecord = NULL;
  338. if (m_bRecordPCM){
  339. pRecord = fopen(m_strFilePathName, "wb+");
  340. }
  341. LogRenderInfo();
  342. st = speex_resampler_init_frac(1, m_pwfx->nSamplesPerSec, m_frame_format->samplespersec, m_pwfx->nSamplesPerSec, m_frame_format->samplespersec, 0, &err);
  343. while (TRUE){
  344. dwWaitResult = WaitForMultipleObjects(sizeof(waitArray) / sizeof(waitArray[0]), waitArray, FALSE, INFINITE);
  345. if (WAIT_OBJECT_0 == dwWaitResult) {
  346. Debug("exit circle for set event stop.");
  347. break;
  348. }
  349. if (WAIT_OBJECT_0 + 1 != dwWaitResult){
  350. Debug("exit circle for time wake up.");
  351. break;
  352. }
  353. HRESULT hr = S_OK;
  354. if (NULL != m_pAudioCaptureClient){
  355. m_pAudioCaptureClient->GetNextPacketSize(&nNextPacketSize);
  356. if (FAILED(hr)){
  357. break;
  358. }
  359. }else{
  360. break;
  361. }
  362. if (nNextPacketSize == 0) {
  363. continue;
  364. }
  365. if (NULL != m_pAudioCaptureClient){
  366. hr = m_pAudioCaptureClient->GetBuffer(&pData, &nNumFramesToRead, &dwFlags, NULL, NULL);
  367. if (FAILED(hr)){
  368. break;
  369. }
  370. }
  371. else{
  372. break;
  373. }
  374. if (0 != nNumFramesToRead){
  375. uIndex = TranslateBuffer2DestFrameFormat((spx_int16_t*)((char*)OutAudioBuffer+uIndex), &uValidAudioLen, uLeftBufferLen, pData, nNumFramesToRead*m_pwfx->nBlockAlign,st,m_frame_format);
  376. uLeftBufferLen -= uValidAudioLen;
  377. //Debug("translate valid audio len is %d,left buffer len is %d.", uValidAudioLen, uLeftBufferLen);
  378. if (uLeftBufferLen <= RVC_AUDIO_BUFFER_LEN - m_frame_format->framesize){
  379. //Debug("audio len = %d.", RVC_AUDIO_BUFFER_LEN - uLeftBufferLen);
  380. if (m_audio_cap){
  381. audio_frame framedata;
  382. framedata.bitspersample = m_frame_format->bitspersample;
  383. framedata.format = m_frame_format->format;
  384. framedata.nchannels = m_frame_format->nchannels;
  385. framedata.samplespersec = m_frame_format->samplespersec;
  386. framedata.framesize = m_frame_format->framesize;
  387. framedata.data = (char*)OutAudioBuffer;
  388. m_audio_cap->InsertAudio(&framedata);
  389. if (m_bRecordPCM){
  390. if (NULL != pRecord){
  391. fwrite(framedata.data, framedata.framesize, 1, pRecord);
  392. }
  393. }
  394. }
  395. uLeftBufferLen = RVC_AUDIO_BUFFER_LEN;
  396. memset(OutAudioBuffer, 0 , RVC_AUDIO_BUFFER_LEN);
  397. uIndex = 0;
  398. }
  399. else{
  400. uValidAudioLen = 0;
  401. //Debug("continue next capture.");
  402. }
  403. }
  404. if (NULL != m_pAudioCaptureClient){
  405. m_pAudioCaptureClient->ReleaseBuffer(nNumFramesToRead);
  406. }
  407. }
  408. if (NULL != pRecord){
  409. fclose(pRecord);
  410. pRecord = NULL;
  411. }
  412. speex_resampler_destroy(st);
  413. CoUninitialize();
  414. }
  415. BOOL AudioRenderImpl::AdjustFormatTo16Bits(WAVEFORMATEX *pwfx)
  416. {
  417. BOOL bRet = FALSE;
  418. if (NULL != pwfx){
  419. if (pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT){
  420. pwfx->wFormatTag = WAVE_FORMAT_PCM;
  421. pwfx->wBitsPerSample = 16;
  422. pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;
  423. pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;
  424. bRet = TRUE;
  425. }
  426. else if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE){
  427. PWAVEFORMATEXTENSIBLE pEx = reinterpret_cast<PWAVEFORMATEXTENSIBLE>(pwfx);
  428. if (IsEqualGUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, pEx->SubFormat)){
  429. pEx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
  430. pEx->Samples.wValidBitsPerSample = 16;
  431. pwfx->wBitsPerSample = 16;
  432. pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;
  433. pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;
  434. bRet = TRUE;
  435. }
  436. }
  437. }
  438. return bRet;
  439. }
  440. int AudioRenderImpl::StopRender()
  441. {
  442. Debug("stop audio render.");
  443. m_bRecordPCM = false;
  444. memset(m_strFilePathName, 0, MAX_PATH);
  445. if (m_pAudioClient){
  446. m_pAudioClient->Stop();
  447. }
  448. SetEvent(m_hEventStop);
  449. Debug("m_hEventStop SetEvent.");
  450. WaitForSingleObject(m_hThread, -1);
  451. if (m_audio_cap){
  452. Sleep(10);
  453. m_audio_cap->ClearAudioQueue();
  454. }
  455. if (m_frame_format){
  456. delete m_frame_format;
  457. m_frame_format = NULL;
  458. }
  459. Close();
  460. return 0;
  461. }
  462. int AudioRenderImpl::ReStartRender()
  463. {
  464. if (0 == StopRender()){
  465. StartRender(m_iQueueNumber, m_frame_format, m_strFilePathName);
  466. }
  467. return 0;
  468. }
  469. void AudioRenderImpl::Close()
  470. {
  471. if (m_hEventStop != NULL)
  472. {
  473. CloseHandle(m_hEventStop);
  474. m_hEventStop = NULL;
  475. }
  476. if (m_pAudioClient)
  477. {
  478. m_pAudioClient->Release();
  479. m_pAudioClient = NULL;
  480. }
  481. if (m_pwfx != NULL)
  482. {
  483. CoTaskMemFree(m_pwfx);
  484. m_pwfx = NULL;
  485. }
  486. if (m_hTimerWakeUp != NULL)
  487. {
  488. CancelWaitableTimer(m_hTimerWakeUp);
  489. CloseHandle(m_hTimerWakeUp);
  490. m_hTimerWakeUp = NULL;
  491. }
  492. if (m_hTask != NULL)
  493. {
  494. AvRevertMmThreadCharacteristics(m_hTask);
  495. m_hTask = NULL;
  496. }
  497. if (m_pAudioCaptureClient != NULL)
  498. {
  499. m_pAudioCaptureClient->Release();
  500. m_pAudioCaptureClient = NULL;
  501. }
  502. }
  503. void AudioRenderImpl::Release()
  504. {
  505. delete this;
  506. }
  507. AudioRenderImpl::~AudioRenderImpl()
  508. {
  509. }