| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628 |
- // libaudiorender.cpp : Defines the exported functions for the DLL application.
- //
- #include "stdafx.h"
- #ifndef _CRT_SECURE_NO_WARNINGS
- #define _CRT_SECURE_NO_WARNINGS
- #endif
- #include "libaudiorender.h"
- #include "../../rvcmediacommon/rvc_media_common.h"
- #ifndef RVC_AUDIO_FRAME_SIZE
- #define RVC_AUDIO_FRAME_SIZE 320
- #endif
- #ifndef RVC_AUDIO_FREQUENCY
- #define RVC_AUDIO_FREQUENCY 8000
- #endif
- #ifndef RVC_AUDIO_BUFFER_LEN
- #define RVC_AUDIO_BUFFER_LEN 512
- #endif
- #ifndef RVC_DEFAULT_BITPERSAMPLE
- #define RVC_DEFAULT_BITPERSAMPLE 16
- #endif
- AudioRenderImpl::AudioRenderImpl(audiorender_callback_t* pCallback)
- {
- memcpy(&m_audiorender_cb, pCallback, sizeof(audiorender_callback_t));
- m_pAudioCaptureClient = NULL;
- m_pAudioClient = NULL;
- m_pMMDevice = NULL;
- m_hEventStop = NULL;
- m_hTimerWakeUp = NULL;
- m_hTask = NULL;
- m_pwfx = NULL;
- m_iQueueNumber = 0;
- m_audio_cap = NULL;
- m_frame_format = NULL;
- memset(m_strFilePathName, 0, MAX_PATH);
- m_bRecordPCM = false;
- }
- bool AudioRenderImpl::InitAudioFrame(audio_frame* pframe)
- {
- bool bret = false;
- if (NULL != pframe){
- pframe->bitspersample = RVC_DEFAULT_BITPERSAMPLE;
- pframe->format = 1;
- pframe->nchannels = 1;
- pframe->samplespersec = RVC_AUDIO_FREQUENCY;
- pframe->framesize = RVC_AUDIO_FRAME_SIZE;
- pframe->data = NULL;
- bret = true;
- }
- return bret;
- }
- DWORD AudioRenderImpl::pfThreadFunc(LPVOID lpThreadParameter)
- {
- AudioRenderImpl* pCapture = (AudioRenderImpl*)lpThreadParameter;
- pCapture->RenderFunc();
- return 0;
- }
- void AudioRenderImpl::LogRenderInfo()
- {
- uint32_t uConvertRatio = 1;
- if (NULL != m_frame_format){
- if (m_frame_format->samplespersec&&m_frame_format->nchannels&&m_frame_format->bitspersample){
- uConvertRatio = (m_pwfx->nSamplesPerSec*m_pwfx->nChannels*m_pwfx->wBitsPerSample)/(m_frame_format->samplespersec*m_frame_format->nchannels*m_frame_format->bitspersample);
- }
- }
- RenderLog(AUDIORENDER_LOG_DEBUG, "current speaker render audio convert ratio is %d.", uConvertRatio);
- eSpeakerSamplingDepthRate eSampleType = GetSpeakerSampleRate(m_pwfx->wBitsPerSample, m_pwfx->nSamplesPerSec);
- RenderLog(AUDIORENDER_LOG_DEBUG, "Speaker Sample Type is %d.", eSampleType);
- }
- void AudioRenderImpl::RenderLog(audiorender_loglevel elevel, const char *fmt, ... )
- {
- if (m_audiorender_cb.debug){
- va_list arg;
- va_start(arg, fmt);
- if (*m_audiorender_cb.debug){
- (*m_audiorender_cb.debug)(elevel, m_audiorender_cb.user_data, fmt, arg);
- }
- va_end(arg);
- }
- }
- void AudioRenderImpl::OnRenderFailed()
- {
- }
- void AudioRenderImpl::OnAudioRenderExcption()
- {
- }
- int AudioRenderImpl::StartRender(int iQueue, void* pFrameformat, const char* pSwitchName)
- {
- m_iQueueNumber = iQueue;
- if (NULL != m_frame_format){
- delete m_frame_format;
- m_frame_format = NULL;
- }
- m_frame_format = new audio_frame();
- if (NULL != m_frame_format){
- if (NULL != pFrameformat){
- m_frame_format->bitspersample = ((audio_frame*)pFrameformat)->bitspersample;
- m_frame_format->nchannels = ((audio_frame*)pFrameformat)->nchannels;
- m_frame_format->format = ((audio_frame*)pFrameformat)->format;
- m_frame_format->samplespersec = ((audio_frame*)pFrameformat)->samplespersec;
- m_frame_format->framesize = ((audio_frame*)pFrameformat)->framesize;
- }
- else{
- InitAudioFrame(m_frame_format);
- }
- }
- if (NULL != pSwitchName){
- size_t ulen = strlen(pSwitchName);
- if (ulen >= MAX_PATH){
- ulen = MAX_PATH - 1;
- }
- memcpy(m_strFilePathName, pSwitchName, ulen);
- if (strlen(m_strFilePathName) > 0){
- m_bRecordPCM = true;
- }
- }
- if (InitQueueInfo(iQueue)){
- return -1;
- }
- CoInitialize(NULL);
- IMMDeviceEnumerator *pMMDeviceEnumerator = NULL;
- HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL,
- __uuidof(IMMDeviceEnumerator), (void**)&pMMDeviceEnumerator);
- if (FAILED(hr)){
- CoUninitialize();
- return -1;
- }
- // get the default render endpoint
- hr = pMMDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &m_pMMDevice);
- if (FAILED(hr)){
- CoUninitialize();
- return -1;
- }
- pMMDeviceEnumerator->Release();
- m_hEventStop = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (m_hEventStop == NULL){
- CoUninitialize();
- return -1;
- }
- hr = m_pMMDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&m_pAudioClient);
- if (FAILED(hr)){
- goto error;
- }
- REFERENCE_TIME hnsDefaultDevicePeriod(0);
-
- if (NULL != m_pAudioClient){
- hr = m_pAudioClient->GetDevicePeriod(&hnsDefaultDevicePeriod, NULL);
- if (FAILED(hr)){
- goto error;
- }
- }
- else{
- goto error;
- }
- hr = m_pAudioClient->GetMixFormat(&m_pwfx);
- if (FAILED(hr)){
- goto error;
- }
- else{
- RenderLog(AUDIORENDER_LOG_DEBUG, "speaker render format is %0x, 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);
- RenderLog(AUDIORENDER_LOG_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);
- }
- if (!AdjustFormatTo16Bits(m_pwfx)){
- goto error;
- }
- m_hTimerWakeUp = CreateWaitableTimer(NULL, FALSE, NULL);
- if (m_hTimerWakeUp == NULL){
- goto error;
- }
- if (NULL != m_pAudioClient){
- hr = m_pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_LOOPBACK, 0, 0, m_pwfx, 0);
- if (FAILED(hr)){
- goto error;
- }
- }
- else{
- goto error;
- }
- if (NULL != m_pAudioClient){
- hr = m_pAudioClient->GetService(__uuidof(IAudioCaptureClient), (void**)&m_pAudioCaptureClient);
- if (FAILED(hr)){
- goto error;
- }
- }
- else{
- goto error;
- }
- DWORD nTaskIndex = 0;
- m_hTask = AvSetMmThreadCharacteristics("Capture", &nTaskIndex);
- if (NULL == m_hTask){
- goto error;
- }
- LARGE_INTEGER liFirstFire;
- liFirstFire.QuadPart = -hnsDefaultDevicePeriod / 2; // negative means relative time
- LONG lTimeBetweenFires = (LONG)hnsDefaultDevicePeriod / 2 / (10 * 1000); // convert to milliseconds
- BOOL bOK = SetWaitableTimer(m_hTimerWakeUp, &liFirstFire, lTimeBetweenFires, NULL, NULL, FALSE);
- if (!bOK){
- goto error;
- }
- if (NULL != m_pAudioClient){
- hr = m_pAudioClient->Start();
- if (FAILED(hr)){
- goto error;
- }
- }
- else{
- goto error;
- }
- m_hThread = CreateThread(NULL, 0, pfThreadFunc, this, 0, 0);
- if (m_hThread == NULL){
- goto error;
- }
- CoUninitialize();
- return 0;
- error:
- Close();
- CoUninitialize();
- return -1;
- }
- uint32_t AudioRenderImpl::ConvertDouble2SingleChannel(char* pDstBuf, const uint32_t uDstLen, const unsigned char* pSrcBuf, uint32_t uSrcLen, uint32_t uBitDeepth)
- {
- uint32_t uRet = 0;
- uint32_t uOneChannelLen = uSrcLen/2;
- uint32_t i = 0;
- for (; i < uOneChannelLen/2 && i < uDstLen/uBitDeepth; i++){
- memcpy((uint16_t*)pDstBuf + i, ((uint32_t*)(pSrcBuf))+i, uBitDeepth);
- }
- if (i == uOneChannelLen/2){
- uRet = uOneChannelLen;
- }
- return uRet;
- }
- eSpeakerSamplingDepthRate AudioRenderImpl::GetSpeakerSampleRate(uint32_t udepth, uint32_t usamplerate)
- {
- eSpeakerSamplingDepthRate eType = eSixteenBitsDVD;
- if (16 == udepth){
- switch(usamplerate)
- {
- case 44100:
- eType = eSixteenBitsCD;
- break;
- case 48000:
- eType = eSixteenBitsDVD;
- break;
- case 96000:
- eType = eSixteenBitsStatdioLow;
- break;
- case 192000:
- eType = eSixteenBitsStatdioHigh;
- break;
- }
- }
- else if (24 == udepth){
- switch(usamplerate)
- {
- case 44100:
- eType = eTwentyfourStatdioA;
- break;
- case 48000:
- eType = eTwentyfourStatdioB;
- break;
- case 96000:
- eType = eTwentyfourStatdioC;
- break;
- case 192000:
- eType = eTwentyfourStatdioD;
- break;
- }
- }
- return eType;
- }
-
- int AudioRenderImpl::InitQueueInfo(int iQueue)
- {
- int iRet = -1;
- char* pQueueName = NULL;
- if (0 == iQueue){
- pQueueName = REC_COMMON_REMOTEAUDIO_SHM_QUEUE;
- }
- else {
- pQueueName = REC_COMMON_AUDIO_SALES_SHM_QUEUE;
- }
- if (NULL != pQueueName){
- m_audio_cap = new Clibaudioqueue(pQueueName);
- if (NULL != m_audio_cap){
- iRet = 0;
- RenderLog(AUDIORENDER_LOG_DEBUG, "audio render insert queue name is %s.", pQueueName);
- }
- }
-
- return iRet;
- }
- 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)
- {
- uint32_t uRet = 0;
-
- uint32_t uSingleChannelDataLen = uBufferLen;
- uint32_t uSingleChannelBufferLen = 0;
- char* pSingleChannelBuf = (char*)malloc(uBufferLen*sizeof(char));
- if (NULL != pSingleChannelBuf){
- memset(pSingleChannelBuf, 0, uBufferLen*sizeof(char));
- uSingleChannelBufferLen = uBufferLen*sizeof(char);
- }
- if (eDoubleChannel == m_pwfx->nChannels){
- if (eSingleChannel == pDestFrameFormat->nchannels){
- uSingleChannelDataLen = ConvertDouble2SingleChannel(pSingleChannelBuf, uSingleChannelBufferLen, pCbBuffer, uBufferLen, m_pwfx->wBitsPerSample/8);
- }
- else{
- memcpy(pSingleChannelBuf, pCbBuffer, uBufferLen);
- }
- }
- else{
- if (eSingleChannel == pDestFrameFormat->nchannels){
- memcpy(pSingleChannelBuf, pCbBuffer, uBufferLen);
- }
- else{
- RenderLog(AUDIORENDER_LOG_INFO, "not support single channel convert to double channels.");
- }
- }
- spx_uint32_t uInLen = uSingleChannelDataLen;
- int iRet = speex_resampler_process_int(st, 0, (spx_int16_t*)pSingleChannelBuf, &uInLen, pOutAudio, &uAudioBufferLen);
- if (RESAMPLER_ERR_SUCCESS == iRet){
- *pAudioLen = uAudioBufferLen;
- uRet = uAudioBufferLen;
- }
- if (NULL != pSingleChannelBuf){
- free(pSingleChannelBuf);
- pSingleChannelBuf = NULL;
- }
- return uRet;
- }
- void AudioRenderImpl::RenderFunc()
- {
- HANDLE waitArray[2] = { m_hEventStop, m_hTimerWakeUp };
- DWORD dwWaitResult;
- UINT32 nNextPacketSize(0);
- BYTE *pData = NULL;
- UINT32 nNumFramesToRead;
- DWORD dwFlags;
- CoInitialize(NULL);
- SpeexResamplerState *st = NULL;
- int err = 0;
- spx_int16_t OutAudioBuffer[RVC_AUDIO_BUFFER_LEN] = {0};
- spx_uint32_t uIndex = 0;
- spx_uint32_t uValidAudioLen = 0;
- spx_uint32_t uLeftBufferLen = RVC_AUDIO_BUFFER_LEN;
- int iseriesnumber = 0;
- FILE* pRecord = NULL;
- if (m_bRecordPCM){
- pRecord = fopen(m_strFilePathName, "wb+");
- }
- LogRenderInfo();
- st = speex_resampler_init_frac(1, m_pwfx->nSamplesPerSec, m_frame_format->samplespersec, m_pwfx->nSamplesPerSec, m_frame_format->samplespersec, 0, &err);
- while (true){
- dwWaitResult = WaitForMultipleObjects(sizeof(waitArray) / sizeof(waitArray[0]), waitArray, false, INFINITE);
- if (WAIT_OBJECT_0 == dwWaitResult) {
- RenderLog(AUDIORENDER_LOG_DEBUG, "exit circle for set event stop.");
- break;
- }
- if (WAIT_OBJECT_0 + 1 != dwWaitResult){
- RenderLog(AUDIORENDER_LOG_DEBUG, "exit circle for time wake up.");
- break;
- }
- HRESULT hr = S_OK;
- if (NULL != m_pAudioCaptureClient){
- m_pAudioCaptureClient->GetNextPacketSize(&nNextPacketSize);
- if (FAILED(hr)){
- break;
- }
- }else{
- break;
- }
- if (nNextPacketSize == 0) {
- continue;
- }
- if (NULL != m_pAudioCaptureClient){
- hr = m_pAudioCaptureClient->GetBuffer(&pData, &nNumFramesToRead, &dwFlags, NULL, NULL);
- if (FAILED(hr)){
- break;
- }
- }
- else{
- break;
- }
- if (0 != nNumFramesToRead){
- uIndex = TranslateBuffer2DestFrameFormat((spx_int16_t*)((char*)OutAudioBuffer+uIndex), &uValidAudioLen, uLeftBufferLen, pData, nNumFramesToRead*m_pwfx->nBlockAlign, st, m_frame_format);
- uLeftBufferLen -= uValidAudioLen;
- //RenderLog(AUDIORENDER_LOG_DEBUG, "translate valid audio len is %d,left buffer len is %d.", uValidAudioLen, uLeftBufferLen);
- if (uLeftBufferLen <= RVC_AUDIO_BUFFER_LEN - m_frame_format->framesize){
- //RenderLog(AUDIORENDER_LOG_DEBUG, "audio len = %d.", RVC_AUDIO_BUFFER_LEN - uLeftBufferLen);
- if (m_audio_cap){
- audio_frame framedata;
- framedata.bitspersample = m_frame_format->bitspersample;
- framedata.format = m_frame_format->format;
- framedata.nchannels = m_frame_format->nchannels;
- framedata.samplespersec = m_frame_format->samplespersec;
- framedata.framesize = m_frame_format->framesize;
- framedata.data = (char*)OutAudioBuffer;
- framedata.iseriesnumber = iseriesnumber++;
- bool bRet = m_audio_cap->InsertAudio(&framedata);
- if (bRet){
- if (0 == framedata.iseriesnumber % 1000){
- RenderLog(AUDIORENDER_LOG_DEBUG, "speaker audio[%d] InsertAudio success.", framedata.iseriesnumber);
- }
- }
- else{
- RenderLog(AUDIORENDER_LOG_INFO, "speaker audio InsertAudio failed.");
- }
- if (m_bRecordPCM){
- if (NULL != pRecord){
- fwrite(framedata.data, framedata.framesize, 1, pRecord);
- }
- }
- }
- uLeftBufferLen = RVC_AUDIO_BUFFER_LEN;
- memset(OutAudioBuffer, 0 , RVC_AUDIO_BUFFER_LEN);
- uIndex = 0;
- }
- else{
- uValidAudioLen = 0;
- }
- }
- if (NULL != m_pAudioCaptureClient){
- m_pAudioCaptureClient->ReleaseBuffer(nNumFramesToRead);
- }
- }
- if (NULL != pRecord){
- fclose(pRecord);
- pRecord = NULL;
- }
- speex_resampler_destroy(st);
- CoUninitialize();
- }
- bool AudioRenderImpl::AdjustFormatTo16Bits(WAVEFORMATEX *pwfx)
- {
- bool bRet = false;
- if (NULL != pwfx){
- if (pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT){
- pwfx->wFormatTag = WAVE_FORMAT_PCM;
- pwfx->wBitsPerSample = 16;
- pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;
- pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;
- bRet = true;
- }
- else if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE){
- PWAVEFORMATEXTENSIBLE pEx = reinterpret_cast<PWAVEFORMATEXTENSIBLE>(pwfx);
- if (IsEqualGUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, pEx->SubFormat)){
- pEx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
- pEx->Samples.wValidBitsPerSample = 16;
- pwfx->wBitsPerSample = 16;
- pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;
- pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;
- bRet = true;
- }
- }
- }
- return bRet;
- }
- int AudioRenderImpl::StopRender()
- {
- RenderLog(AUDIORENDER_LOG_DEBUG, "stop audio render.");
-
- m_bRecordPCM = false;
- memset(m_strFilePathName, 0, MAX_PATH);
- if (m_pAudioClient){
- m_pAudioClient->Stop();
- }
- SetEvent(m_hEventStop);
- RenderLog(AUDIORENDER_LOG_DEBUG, "m_hEventStop SetEvent.");
- WaitForSingleObject(m_hThread, -1);
- if (m_audio_cap){
- Sleep(10);
- m_audio_cap->ClearAudioQueue();
- }
- if (m_frame_format){
- delete m_frame_format;
- m_frame_format = NULL;
- }
- Close();
- return 0;
- }
- int AudioRenderImpl::ReStartRender()
- {
- if (0 == StopRender()){
- StartRender(m_iQueueNumber, m_frame_format, m_strFilePathName);
- }
- return 0;
- }
- void AudioRenderImpl::Close()
- {
- if (m_hEventStop != NULL)
- {
- CloseHandle(m_hEventStop);
- m_hEventStop = NULL;
- }
- if (m_pAudioClient)
- {
- m_pAudioClient->Release();
- m_pAudioClient = NULL;
- }
- if (m_pwfx != NULL)
- {
- CoTaskMemFree(m_pwfx);
- m_pwfx = NULL;
- }
- if (m_hTimerWakeUp != NULL)
- {
- CancelWaitableTimer(m_hTimerWakeUp);
- CloseHandle(m_hTimerWakeUp);
- m_hTimerWakeUp = NULL;
- }
- if (m_hTask != NULL)
- {
- AvRevertMmThreadCharacteristics(m_hTask);
- m_hTask = NULL;
- }
- if (m_pAudioCaptureClient != NULL)
- {
- m_pAudioCaptureClient->Release();
- m_pAudioCaptureClient = NULL;
- }
- }
- void AudioRenderImpl::Release()
- {
- delete this;
- }
- AudioRenderImpl::~AudioRenderImpl()
- {
-
- }
|