Browse Source

Z991239-1954 #comment fix: 媒体资源控制实体替换使用pulseaudio音频库

陈礼鹏80274480 4 năm trước cách đây
mục cha
commit
65be4d6668

+ 6 - 7
Module/mod_mediacontroller/CMakeLists.txt

@@ -9,9 +9,11 @@ endif(RVC_DEBUG_MODE)
 if(MSVC)
     set(STDAFXCPP stdafx.cpp)
 	 set(VIDEOCAPTURECPP )
+	 set(AUDIOCAPTURECPP )
 else()
 	 set(STDAFXCPP )
 	 set(VIDEOCAPTURECPP videocapobj.h videocapobj.cpp)
+	 set(AUDIOCAPTURECPP audiocapobj.h audiocapobj.cpp)
 endif(MSVC)
 
 set(${MODULE_PREFIX}_SRCS
@@ -25,6 +27,7 @@ set(${MODULE_PREFIX}_SRCS
 
 	${STDAFXCPP}
 	${VIDEOCAPTURECPP}
+	${AUDIOCAPTURECPP}
 
     capture.cpp
     mod_mediacontroller.cpp
@@ -42,9 +45,6 @@ conan_cmake_run(REQUIRES portaudio/v190600.20161030@LR04.02_ThirdParty/testing
 BASIC_SETUP CMAKE_TARGETS
 BUILD missing)
 else(WIN32)
-conan_cmake_run(REQUIRES portaudio/v19.0.6@LR04.02_ThirdParty/testing
-BASIC_SETUP CMAKE_TARGETS
-BUILD missing)
 endif(WIN32)
 
 
@@ -101,9 +101,9 @@ endif(WIN32)
 
 
 target_include_directories(${MODULE_NAME} PRIVATE
-	${CONAN_INCLUDE_DIRS_PORTAUDIO}
 	${CONAN_INCLUDE_DIRS_FFMPEG}
 	if(WIN32)
+	${CONAN_INCLUDE_DIRS_PORTAUDIO}
 	${CONAN_INCLUDE_DIRS_IPP}
 	${CONAN_INCLUDE_DIRS_SPEEXDSP}
 	${CONAN_INCLUDE_DIRS_APR}/apr-1
@@ -112,11 +112,11 @@ target_include_directories(${MODULE_NAME} PRIVATE
 )
 
 target_link_directories(${MODULE_NAME} PRIVATE
-	${CONAN_LIB_DIRS_PORTAUDIO}
 	${CONAN_LIB_DIRS_FFMPEG}
 	${CONAN_LIB_DIRS_SPANDSP}
 	${CONAN_LIB_DIRS_SPEEXDSP}
 	if(WIN32)
+	${CONAN_LIB_DIRS_PORTAUDIO}
 	${CONAN_LIB_DIRS_IPP}
 	${CONAN_LIB_DIRS_APACHE-APR}
 	${CONAN_LIB_DIRS_LIB8K}
@@ -125,7 +125,6 @@ target_link_directories(${MODULE_NAME} PRIVATE
 	endif(WIN32)
 )
 
-message(STATUS "CONAN_PKG_LIBS_APACHE-APR = ${CONAN_PKG_LIBS_APACHE-APR}")
 # 添加实体需要依赖的其他共享库(包括系统库)
 if(WIN32)
 set(${MODULE_PREFIX}_LIBS  ${MODULE_BASE_LIBS} 
@@ -148,7 +147,6 @@ set(${MODULE_PREFIX}_LIBS  ${MODULE_BASE_LIBS}
 )
 else(WIN32)
 set(${MODULE_PREFIX}_LIBS  ${MODULE_BASE_LIBS} 	
-	${CONAN_PKG_LIBS_PORTAUDIO}
 	${CONAN_PKG_LIBS_FFMPEG}
 	mediadeviceinfo
 	videocapture
@@ -160,6 +158,7 @@ set(${MODULE_PREFIX}_LIBS  ${MODULE_BASE_LIBS}
 	${CONAN_PKG_LIBS_APR}
 	${CONAN_PKG_LIBS_SPANDSP}
 	${CONAN_PKG_LIBS_SPEEXDSP}
+	audiomgr
 )
 endif(WIN32)
 

+ 81 - 0
Module/mod_mediacontroller/audiocapobj.cpp

@@ -0,0 +1,81 @@
+#include"audiocapobj.h"
+#include<stdlib.h>
+#include<string.h>
+#include<stdarg.h>
+#include <time.h>
+#include <stdio.h>
+#include "SpBase.h"
+
+AudioCapObj::AudioCapObj()
+{
+	Dbg("%s:%d", __FUNCTION__, __LINE__);
+	m_pAudioMgr = CreateAudioMgrObj(this);
+	Dbg("%s:%d", __FUNCTION__, __LINE__);
+}
+
+AudioCapObj::~AudioCapObj()
+{
+	if (NULL != m_pAudioMgr){
+		DestroyIAudioMgrObj(m_pAudioMgr);
+	}
+}
+
+int AudioCapObj::AudioMgrInitialize()
+{
+	return m_pAudioMgr->audio_mgr_initialize();
+}
+
+int AudioCapObj::AudioMgrTerminate()
+{
+	return m_pAudioMgr->audio_mgr_terminate();
+}
+
+int AudioCapObj::audio_get_device_count(bool binput)
+{
+	return m_pAudioMgr->audio_get_device_count(binput);
+}
+
+int AudioCapObj::audio_get_device_name(char* strbuf, size_t ulen, bool binput, int index)
+{
+	return m_pAudioMgr->audio_get_device_name(strbuf, ulen, binput, index);
+}
+
+int AudioCapObj::audio_get_device_id(const char* pstrname, bool binput)
+{
+	return m_pAudioMgr->audio_get_device_id(pstrname, binput);
+}
+
+int AudioCapObj::set_audio_capture_params(audiocap_param_t* param)
+{
+	return m_pAudioMgr->set_audio_capture_params(param);
+}
+
+int AudioCapObj::start_audio_capture()
+{
+	return m_pAudioMgr->start_audio_capture();
+}
+
+int AudioCapObj::stop_audio_capture()
+{
+	return m_pAudioMgr->stop_audio_capture();
+}
+
+
+void AudioCapObj::debug(const char* fmt, ...)
+{
+	va_list arg;
+	va_start(arg, fmt);
+	vDbg(fmt, arg);
+	va_end(arg);
+}
+
+
+void AudioCapObj::on_audio_mgr_failed()
+{
+
+}
+
+void AudioCapObj::on_audio_mgr_excption()
+{
+
+}

+ 27 - 0
Module/mod_mediacontroller/audiocapobj.h

@@ -0,0 +1,27 @@
+#pragma once
+
+#include "../../Other/libaudiomgr/iaudiomgrinterface.h"
+
+
+class AudioCapObj : public IAudioMgrCallback
+{
+public:
+	AudioCapObj();
+	virtual ~AudioCapObj();
+
+	void debug(const char* fmt, ...);
+	void on_audio_mgr_failed();
+	void on_audio_mgr_excption();
+
+	int AudioMgrInitialize();
+	int AudioMgrTerminate();
+	int audio_get_device_count(bool binput);
+	int audio_get_device_name(char* strbuf, size_t ulen, bool binput, int index);
+	int audio_get_device_id(const char* pstrname, bool binput);
+	int set_audio_capture_params(audiocap_param_t* param);
+	int start_audio_capture();
+	int stop_audio_capture();
+
+private:
+	IAudioMgr* m_pAudioMgr;
+};

+ 302 - 191
Module/mod_mediacontroller/capture.cpp

@@ -65,12 +65,60 @@ static int Bin2Str(unsigned char *x, int xlen, char *str, int str_size)
 	return k;
 }
 
+
+#ifdef RVC_OS_WIN
+
+static int audio_get_dev_count(int* in_cnt, int* out_cnt)
+{
+	int icnt = 0, ocnt = 0;
+	int cnt = Pa_GetDeviceCount();
+	for (int i = 0; i < cnt; ++i) {
+		const PaDeviceInfo* info = Pa_GetDeviceInfo(i);
+		if (info->maxInputChannels)
+			icnt++;
+		if (info->maxOutputChannels)
+			ocnt++;
+	}
+	if (in_cnt)
+		* in_cnt = icnt;
+	if (out_cnt)
+		* out_cnt = ocnt;
+	return 0;
+}
+
+static CSimpleStringA audio_get_dev_name(bool in_direction, int idx)
+{
+	int cnt = Pa_GetDeviceCount();
+	int ii, i;
+	for (i = 0, ii = 0; i < cnt; ++i) {
+		const PaDeviceInfo* info = Pa_GetDeviceInfo(i);
+		if (in_direction) {
+			if (info->maxInputChannels) {
+				if (idx == ii) {
+					return CSimpleStringA(info->name);
+				}
+				ii++;
+			}
+		}
+		else {
+			if (info->maxOutputChannels) {
+				if (idx == ii) {
+					return CSimpleStringA(info->name);
+				}
+				ii++;
+			}
+		}
+	}
+	return CSimpleStringA();
+}
+
+
 static int translate_id(int in_direction, int idx)
 {
 	int i, n, ii;
 	n = Pa_GetDeviceCount();
 	for (i = 0, ii = 0; i < n; ++i) {
-		const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
+		const PaDeviceInfo* info = Pa_GetDeviceInfo(i);
 		if (in_direction) {
 			if (info->maxInputChannels) {
 				if (ii == idx) {
@@ -78,7 +126,8 @@ static int translate_id(int in_direction, int idx)
 				}
 				ii++;
 			}
-		} else {
+		}
+		else {
 			if (info->maxOutputChannels) {
 				if (ii == idx) {
 					return i;
@@ -90,14 +139,42 @@ static int translate_id(int in_direction, int idx)
 	return -1;
 }
 
-static int StreamCallback(const void *input, 
-	void *output, 
-	unsigned long frameCount, 
-	const PaStreamCallbackTimeInfo* timeInfo, 
-	PaStreamCallbackFlags statusFlags, 
-	void *userData)
+
+int capture_get_audio_device_id(bool in_direction, const char* dev_name)
+{
+	int cnt = Pa_GetDeviceCount();
+	int ii, i;
+	for (i = 0, ii = 0; i < cnt; ++i) {
+		const PaDeviceInfo* info = Pa_GetDeviceInfo(i);
+		if (in_direction) {
+			if (info->maxInputChannels) {
+				if (strstr(info->name, dev_name) != NULL) {
+					return ii;
+				}
+				ii++;
+			}
+		}
+		else {
+			if (info->maxOutputChannels) {
+				if (strstr(info->name, dev_name) != NULL) {
+					return ii;
+				}
+				ii++;
+			}
+		}
+	}
+	return -1;
+}
+
+
+static int StreamCallback(const void* input,
+	void* output,
+	unsigned long frameCount,
+	const PaStreamCallbackTimeInfo* timeInfo,
+	PaStreamCallbackFlags statusFlags,
+	void* userData)
 {
-	audio_capture_t *audio_cap = (audio_capture_t*)userData;
+	audio_capture_t* audio_cap = (audio_capture_t*)userData;
 
 	if (input) {
 		audio_frame frm;
@@ -167,23 +244,23 @@ static int StreamCallback(const void *input,
 	}
 
 	if (output) {
-		memset(output, 0, frameCount<<1);
+		memset(output, 0, frameCount << 1);
 	}
-	
+
 
 	return paContinue;
 }
 
-static int Sales_StreamCallback(const void *input, 
-	void *output, 
-	unsigned long frameCount, 
-	const PaStreamCallbackTimeInfo* timeInfo, 
-	PaStreamCallbackFlags statusFlags, 
-	void *userData)
+static int Sales_StreamCallback(const void* input,
+	void* output,
+	unsigned long frameCount,
+	const PaStreamCallbackTimeInfo* timeInfo,
+	PaStreamCallbackFlags statusFlags,
+	void* userData)
 {
-	rvc_audio_capture_t *audio_cap = (rvc_audio_capture_t*)userData;
+	rvc_audio_capture_t* audio_cap = (rvc_audio_capture_t*)userData;
 
-	if ((NULL != audio_cap) && (NULL != audio_cap->audio_shm_queue) && (NULL != input)){
+	if ((NULL != audio_cap) && (NULL != audio_cap->audio_shm_queue) && (NULL != input)) {
 		audio_frame frm;
 		audio_frame dst_frm;
 
@@ -212,7 +289,7 @@ static int Sales_StreamCallback(const void *input,
 			}
 			else {
 				if ((audio_cap->iaudio_capture_peroid) > 0 && (0 == dst_frm.iseriesnumber % audio_cap->iaudio_capture_peroid)) {
-					if (audio_cap->iseriesnumber > INT_MAX) { 
+					if (audio_cap->iseriesnumber > INT_MAX) {
 						audio_cap->iseriesnumber = 0;
 					}
 					//Dbg("current audio frame series number is %d.", frm.iseriesnumber);
@@ -234,80 +311,34 @@ static int Sales_StreamCallback(const void *input,
 			}
 		}
 
-		if (eSingleWriteLocal == audio_cap->eType){
-			fwrite(frm.data, frm.framesize, 1,(FILE*)(audio_cap->pdata));
+		if (eSingleWriteLocal == audio_cap->eType) {
+			fwrite(frm.data, frm.framesize, 1, (FILE*)(audio_cap->pdata));
 		}
 	}
 
 	if (output) {
-		memset(output, 0, frameCount<<1);
+		memset(output, 0, frameCount << 1);
 	}
 
 
 	return paContinue;
 }
 
-static rvc_audio_capture_t *salesrecord_audio_capture_create(rvc_sales_audio_capture_t *cap)
-{
-	rvc_audio_capture_t *audio_cap = ZALLOC_T(rvc_audio_capture_t);
-	if (audio_cap) {
-		audio_cap->parent = cap;
-		audio_cap->audio_shm_queue = new Clibaudioqueue(REC_COMMON_AUDIO_SALES_SHM_QUEUE);
-		audio_cap->iseriesnumber = 0;
-		audio_cap->eType = eUnKnown;
-		audio_cap->pdata = NULL;
-	}
-	return audio_cap;
-}
-
-static void salesrecord_audio_capture_destroy(rvc_audio_capture_t *audio_cap)
-{
-	if (NULL != audio_cap){
-		if (NULL != audio_cap->audio_shm_queue){
-			delete audio_cap->audio_shm_queue;
-			audio_cap->audio_shm_queue = NULL;
-			Dbg("set audio_cap audio_shm_queue null");
-		}
-		free(audio_cap);
-	}
-}
-
-static audio_capture_t *audio_capture_create(capture_t *cap)
-{
-	audio_capture_t *audio_cap = ZALLOC_T(audio_capture_t);
-	if (audio_cap) {
-		audio_cap->parent = cap;
-		audio_cap->shm_queue = new Clibaudioqueue(REC_COMMON_AUDIO_SHM_QUEUE);
-		audio_cap->handfree_shm_queue = new Clibaudioqueue(REC_COMMON_HANDFREE_AUDIO_SHM_QUEUE);
-		audio_cap->salesol_shm_queue = new Clibaudioqueue(REC_COMMON_AUDIO_SALESOL_SHM_QUEUE);
-		//audio_cap->sales_shm_queue = new Clibaudioqueue(REC_COMMON_AUDIO_SALES_SHM_QUEUE);
-	}
-	return audio_cap;
-}
-
-static void audio_capture_destroy(audio_capture_t *audio_cap)
-{
-	delete audio_cap->shm_queue;
-	delete audio_cap->handfree_shm_queue;
-	delete audio_cap->salesol_shm_queue;
-	//delete audio_cap->sales_shm_queue;
-	free(audio_cap);
-}
 
-static int audio_capture_start(audio_capture_t *audio_cap)
+static int portaudio_capture_start(audio_capture_t* audio_cap)
 {
-	capture_t *cap = audio_cap->parent;
+	capture_t* cap = audio_cap->parent;
 
 	PaStreamParameters outParam = { 0 };
-	PaStreamParameters inParam = {0};
-	PaStreamParameters salesInParam = {0};
+	PaStreamParameters inParam = { 0 };
+	PaStreamParameters salesInParam = { 0 };
 	PaError paError = paNoError;
 
 	int nId = capture_get_audio_device_id(true, cap->config.strAudioIn);
-	if (nId == -1) 
+	if (nId == -1)
 	{
 		//需要立即处理的告警使用Severity_High
-		LogError(Severity_High,Error_DevMedia,ERROR_MOD_MEDIACONTROLLER_HANDFREEIN_INITFAIL,"hand free in device config error,please check");
+		LogError(Severity_High, Error_DevMedia, ERROR_MOD_MEDIACONTROLLER_HANDFREEIN_INITFAIL, "hand free in device config error,please check");
 		return Error_AudioIN;
 	}
 
@@ -323,7 +354,7 @@ static int audio_capture_start(audio_capture_t *audio_cap)
 	}
 	else
 	{
-		Dbg("[%d] in dev name is %s, defaultSampleRate = %f",in_dev_id, in_info->name, in_info->defaultSampleRate);
+		Dbg("[%d] in dev name is %s, defaultSampleRate = %f", in_dev_id, in_info->name, in_info->defaultSampleRate);
 	}
 	inParam.channelCount = 1;
 	audio_cap->dev_channels = 1;
@@ -346,10 +377,10 @@ static int audio_capture_start(audio_capture_t *audio_cap)
 	}
 
 	nId = capture_get_audio_device_id(false, cap->config.strAudioOut);
-	if (nId == -1) 
+	if (nId == -1)
 	{
 		//需要立即处理的告警使用Severity_High
-		LogError(Severity_High,Error_DevMedia,ERROR_MOD_MEDIACONTROLLER_HANDFREEOUT_INITFAIL,"hand free out device config error,please check");
+		LogError(Severity_High, Error_DevMedia, ERROR_MOD_MEDIACONTROLLER_HANDFREEOUT_INITFAIL, "hand free out device config error,please check");
 		return Error_AudioOut;
 	}
 	int out_dev_id = translate_id(FALSE, nId);
@@ -363,7 +394,6 @@ static int audio_capture_start(audio_capture_t *audio_cap)
 		return Error_AudioOut;
 	}
 
-#ifdef RVC_OS_WIN
 	outParam.channelCount = 1;
 	outParam.device = out_dev_id;
 	outParam.suggestedLatency = out_info->defaultLowOutputLatency;
@@ -374,12 +404,11 @@ static int audio_capture_start(audio_capture_t *audio_cap)
 		Dbg("audio capture create error, cannot open output audio device.");
 		return Error_AudioOut;
 	}
-#endif
 
 	//打开流设备,可以用以下代码替换paError = Pa_OpenStream(&audio_cap->stream, &inParam, &outParam, CAPTURE_CLOCK, 
 	//CAPTURE_FRAME_TIME * CAPTURE_CLOCK/1000, paClipOff|paDitherOff, &StreamCallback, audio_cap);
 	paError = Pa_OpenStream(&audio_cap->stream, &inParam, NULL, inSampleRate,
-		CAPTURE_FRAME_TIME * inSampleRate /1000, paClipOff|paDitherOff, &StreamCallback, audio_cap);
+		CAPTURE_FRAME_TIME * inSampleRate / 1000, paClipOff | paDitherOff, &StreamCallback, audio_cap);
 
 	if (paNoError != paError) {
 		Dbg("[%d] in dev %s port audio open stream failed! paError = %d", in_dev_id, in_info->name, paError);
@@ -403,33 +432,29 @@ static int audio_capture_start(audio_capture_t *audio_cap)
 	return Error_Succeed;
 }
 
-static void audio_capture_stop(audio_capture_t *audio_cap)
+
+static void portaudio_capture_stop(audio_capture_t* audio_cap)
 {
 	if (audio_cap->stream) {
 		Pa_AbortStream(audio_cap->stream);
 		Pa_CloseStream(audio_cap->stream);
 		audio_cap->stream = NULL;
 	}
-	//if (audio_cap->sales_stream) {
-	//	Pa_AbortStream(audio_cap->sales_stream);
-	//	Pa_CloseStream(audio_cap->sales_stream);
-	//	audio_cap->sales_stream = NULL;
-	//}
 }
 
 
-static int record_audio_capture_start(rvc_audio_capture_t *audio_cap)
+static int record_portaudio_capture_start(rvc_audio_capture_t* audio_cap)
 {
-	rvc_sales_audio_capture_t *cap = audio_cap->parent;
-	PaStreamParameters salesInParam = {0};
+	rvc_sales_audio_capture_t* cap = audio_cap->parent;
+	PaStreamParameters salesInParam = { 0 };
 
 	PaError paError;
-	const PaDeviceInfo *info;
+	const PaDeviceInfo* info;
 	int nId = capture_get_audio_device_id(true, cap->rvc_audio_config.strAudioIn);
-	if (nId == -1) 
+	if (nId == -1)
 	{
 		//需要立即处理的告警使用Severity_High
-		LogError(Severity_High,Error_DevMedia,ERROR_MOD_MEDIACONTROLLER_HANDFREEIN_INITFAIL,"hand free in device config error,please check");
+		LogError(Severity_High, Error_DevMedia, ERROR_MOD_MEDIACONTROLLER_HANDFREEIN_INITFAIL, "hand free in device config error,please check");
 		return Error_AudioIN;
 	}
 
@@ -462,7 +487,7 @@ static int record_audio_capture_start(rvc_audio_capture_t *audio_cap)
 	}
 
 	paError = Pa_OpenStream(&audio_cap->stream, &salesInParam, NULL, info->defaultSampleRate,
-		audio_cap->iaudio_capture_peroid * info->defaultSampleRate /1000, paClipOff|paDitherOff, &Sales_StreamCallback, audio_cap);
+		audio_cap->iaudio_capture_peroid * info->defaultSampleRate / 1000, paClipOff | paDitherOff, &Sales_StreamCallback, audio_cap);
 
 	if (paError != paNoError) {
 		Dbg("port audio open sales stream failed! paError = %d", paError);
@@ -479,16 +504,16 @@ static int record_audio_capture_start(rvc_audio_capture_t *audio_cap)
 }
 
 
-static void record_audio_capture_stop(rvc_audio_capture_t *audio_cap)
+static void record_portaudio_capture_stop(rvc_audio_capture_t* audio_cap)
 {
-	if (NULL != audio_cap){
+	if (NULL != audio_cap) {
 		if (audio_cap->stream) {
 			PaError Error = Pa_AbortStream(audio_cap->stream);
-			if (paNoError == Error){
+			if (paNoError == Error) {
 				Dbg("Pa_AbortStream no error.");
 			}
 			Error = Pa_CloseStream(audio_cap->stream);
-			if (paNoError == Error){
+			if (paNoError == Error) {
 				Dbg("Pa_CloseStream no error.");
 			}
 			audio_cap->stream = NULL;
@@ -496,6 +521,169 @@ static void record_audio_capture_stop(rvc_audio_capture_t *audio_cap)
 		audio_cap->iseriesnumber = 0;
 	}
 }
+#else
+
+static void audio_data_callback(const void* input, unsigned long audiolen, void* userdata)
+{
+	audio_capture_t* audio_cap = (audio_capture_t*)userdata;
+
+	if (input) {
+		audio_frame frm;
+		audio_frame dst_frm;
+
+		frm.bitspersample = 2;
+		frm.format = 1;
+		frm.data = (char*)const_cast<void*>(input);
+		frm.framesize = audiolen;
+		frm.nchannels = 1;
+		frm.samplespersec = 8000;
+		frm.iseriesnumber = 0;
+
+		if (!audio_cap->shm_queue->InsertAudio(&frm)) {
+			Dbg("[StreamCallback] InsertAudio to shm_queue failed!");
+		}
+		else {
+			Dbg("[StreamCallback] InsertAudio to shm_queue success! and framesize is :%d, and shm_queue length is %d.", frm.framesize, audio_cap->shm_queue->GetAudioLens());
+		}
+	}
+
+	return;
+}
+
+
+static int pulseaudio_capture_start(audio_capture_t* audio_cap)
+{
+	int iret = -1;
+
+	capture_t* cap = audio_cap->parent;
+	
+	if (NULL != audio_cap->paudiocap){
+		audiocap_param_t param = { 0 };
+		param.ideviceid = 2;
+		param.ichannels = 1;
+		param.isampleformat = 3 /*PA_SAMPLE_S16LE*/;
+		param.isamprate = 8000;
+		param.flatency = 0.02;
+		param.on_audio_callback = &audio_data_callback;
+		param.user_data = audio_cap;
+
+		audio_cap->paudiocap->set_audio_capture_params(&param);
+		iret = audio_cap->paudiocap->start_audio_capture();
+	}
+
+
+
+	return iret;
+}
+
+
+static void pulseaudio_capture_stop(audio_capture_t* audio_cap)
+{
+	if (audio_cap->paudiocap) {
+		audio_cap->paudiocap->stop_audio_capture();
+	}
+}
+
+
+static int record_pulseaudio_capture_start(rvc_audio_capture_t* audio_cap)
+{
+	rvc_sales_audio_capture_t* cap = audio_cap->parent;
+
+	return Error_Succeed;
+}
+
+
+static void record_pulseaudio_capture_stop(rvc_audio_capture_t* audio_cap)
+{
+	return;
+}
+
+#endif
+
+
+static rvc_audio_capture_t *salesrecord_audio_capture_create(rvc_sales_audio_capture_t *cap)
+{
+	rvc_audio_capture_t *audio_cap = ZALLOC_T(rvc_audio_capture_t);
+	if (audio_cap) {
+		audio_cap->parent = cap;
+		audio_cap->audio_shm_queue = new Clibaudioqueue(REC_COMMON_AUDIO_SALES_SHM_QUEUE);
+		audio_cap->iseriesnumber = 0;
+		audio_cap->eType = eUnKnown;
+		audio_cap->pdata = NULL;
+	}
+	return audio_cap;
+}
+
+static void salesrecord_audio_capture_destroy(rvc_audio_capture_t *audio_cap)
+{
+	if (NULL != audio_cap){
+		if (NULL != audio_cap->audio_shm_queue){
+			delete audio_cap->audio_shm_queue;
+			audio_cap->audio_shm_queue = NULL;
+			Dbg("set audio_cap audio_shm_queue null");
+		}
+		free(audio_cap);
+	}
+}
+
+static audio_capture_t *audio_capture_create(capture_t *cap)
+{
+	audio_capture_t *audio_cap = ZALLOC_T(audio_capture_t);
+	if (audio_cap) {
+		audio_cap->parent = cap;
+		audio_cap->shm_queue = new Clibaudioqueue(REC_COMMON_AUDIO_SHM_QUEUE);
+		audio_cap->salesol_shm_queue = new Clibaudioqueue(REC_COMMON_AUDIO_SALESOL_SHM_QUEUE);
+	}
+	return audio_cap;
+}
+
+static void audio_capture_destroy(audio_capture_t *audio_cap)
+{
+	delete audio_cap->shm_queue;
+	delete audio_cap->salesol_shm_queue;
+	free(audio_cap);
+}
+
+
+static int audio_capture_start(audio_capture_t* audio_cap)
+{
+#ifdef RVC_OS_WIN
+	return portaudio_capture_start(audio_cap);
+#else
+	return pulseaudio_capture_start(audio_cap);
+#endif
+}
+
+
+static void audio_capture_stop(audio_capture_t* audio_cap)
+{
+#ifdef RVC_OS_WIN
+	return portaudio_capture_stop(audio_cap);
+#else
+	return pulseaudio_capture_stop(audio_cap);
+#endif
+}
+
+
+static int record_audio_capture_start(rvc_audio_capture_t* audio_cap)
+{
+#ifdef RVC_OS_WIN
+	return record_portaudio_capture_start(audio_cap);
+#else
+	return record_pulseaudio_capture_start(audio_cap);
+#endif
+}
+
+
+static void record_audio_capture_stop(rvc_audio_capture_t* audio_cap)
+{
+#ifdef RVC_OS_WIN
+	return record_portaudio_capture_stop(audio_cap);
+#else
+	return record_pulseaudio_capture_stop(audio_cap);
+#endif
+}
+
 
 static int calc_capture_mode(int width, int height, int *mode)
 {
@@ -1107,48 +1295,6 @@ static void video_capture_stop(video_capture_t *video_cap)
 #endif // RVC_OS_WIN
 }
 
-static int audio_get_dev_count(int *in_cnt, int *out_cnt)
-{
-	int icnt = 0, ocnt = 0;
-	int cnt = Pa_GetDeviceCount();
-	for (int i = 0; i < cnt; ++i) {
-		const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
-		if (info->maxInputChannels)
-			icnt ++;
-		if (info->maxOutputChannels)
-			ocnt ++;
-	}
-	if (in_cnt)
-		*in_cnt = icnt;
-	if (out_cnt)
-		*out_cnt = ocnt;
-	return 0;
-}
-
-static CSimpleStringA audio_get_dev_name(bool in_direction, int idx)
-{
-	int cnt = Pa_GetDeviceCount();
-	int ii, i;
-	for (i = 0, ii = 0; i < cnt; ++i) {
-		const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
-		if (in_direction) {
-			if (info->maxInputChannels) {
-				if (idx == ii) {
-					return CSimpleStringA(info->name);
-				}
-				ii++;
-			}
-		} else {
-			if (info->maxOutputChannels) {
-				if (idx == ii) {
-					return CSimpleStringA(info->name);
-				}
-				ii++;
-			}
-		}
-	}
-	return CSimpleStringA();
-}
 
 namespace MediaController {
 
@@ -1596,31 +1742,6 @@ namespace MediaController {
 		return 0;
 	}
 
-	int capture_get_audio_device_id(bool in_direction, const char *dev_name)
-	{
-		int cnt = Pa_GetDeviceCount();
-		int ii, i;
-		for (i = 0, ii = 0; i < cnt; ++i) {
-			const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
-			if (in_direction) {
-				if (info->maxInputChannels) {
-					if (strstr(info->name, dev_name) != NULL) {
-						return ii;
-					}
-					ii++;
-				}
-			} else {
-				if (info->maxOutputChannels) {
-					if (strstr(info->name, dev_name) != NULL) {
-						return ii;
-					}
-					ii++;
-				}
-			}
-		}
-		return -1;
-	}
-
 	int capture_get_video_device_id(const char *dev_name)
 	{
 #ifdef RVC_OS_WIN
@@ -1740,31 +1861,6 @@ namespace MediaController {
 			}
 		}
 
-#else
-		PaError Error = Pa_Initialize();
-		if (Error == paNoError) {
-			//avcodec_register_all();
-		}
-		else {
-			Dbg("PaInitialize failed, rc=%d", Error);
-			return Error_Resource;
-		}
-
-		{
-			int inumber = 0;
-			int icount = rvc_videocap_get_device_count();
-			for (int i = 0; i < 64 && inumber < icount; ++i) {
-				char strcamera[2 * MAX_PATH] = { 0 };
-				char strpath[MAX_PATH] = { 0 };
-
-				if (0 == rvc_videocap_get_device_fullpathname(i, strcamera, 2 * MAX_PATH)){
-					Dbg("%d = %s", inumber++, strcamera);
-				}
-			}
-		}
-
-#endif // RVC_OS_WIN
-
 		{
 			int icnt, ocnt;
 			int rc = audio_get_dev_count(&icnt, &ocnt);
@@ -1781,8 +1877,23 @@ namespace MediaController {
 					Dbg("%d = %s", i, (LPCSTR)str);
 				}
 			}
+	}
+
+#else
+		{
+			int inumber = 0;
+			int icount = rvc_videocap_get_device_count();
+			for (int i = 0; i < 64 && inumber < icount; ++i) {
+				char strcamera[2 * MAX_PATH] = { 0 };
+				char strpath[MAX_PATH] = { 0 };
+
+				if (0 == rvc_videocap_get_device_fullpathname(i, strcamera, 2 * MAX_PATH)){
+					Dbg("%d = %s", inumber++, strcamera);
+				}
+			}
 		}
 
+#endif // RVC_OS_WIN
 		return Error_Succeed;
 	}
 
@@ -1974,8 +2085,8 @@ namespace MediaController {
 
 	void capture_lib_term()
 	{
-		Pa_Terminate();
 #ifdef RVC_OS_WIN
+		Pa_Terminate();
 		videoframework_term();
 		CoUninitialize();
 #else

+ 18 - 5
Module/mod_mediacontroller/capture.h

@@ -2,17 +2,18 @@
 
 #include "SpBase.h"
 #include "../include/EventCode.h"
-#include <portaudio.h>
+
 #include "../../Other/libaudioqueue/libaudioqueue.h"
 #include "../../Other/libvideoqueue/libvideoqueue.h"
 #include "../..//Other/libvideoframework/videoutil.h"
 
 #ifdef RVC_OS_WIN
+#include <portaudio.h>
 #include "../../Other/libvideoframework/videoframework.h"
 #else
 #include "../../Other/libmediadeviceinfo/imediadeviceinfo.h"
 #include "videocapobj.h"
-
+#include "audiocapobj.h"
 #endif // RVC_OS_WIN
 
 
@@ -87,7 +88,12 @@ namespace MediaController {
 	};
 
 	typedef struct audio_capture_t {
-		PaStream *stream;
+#ifdef RVC_OS_WIN
+		PaStream* stream;
+#else
+		AudioCapObj* paudiocap;
+#endif
+		
 		Clibaudioqueue *shm_queue;
 		Clibaudioqueue* handfree_shm_queue;		// 远程连线时免提音频队列
 		Clibaudioqueue *salesol_shm_queue;		// 在线双录音频队列
@@ -103,7 +109,11 @@ namespace MediaController {
 
 	//音频采集结构体
 	typedef struct rvc_audio_capture_s{
-		PaStream *stream;
+#ifdef RVC_OS_WIN
+		PaStream* stream;
+#else
+		AudioCapObj* paudiocap;
+#endif
 		Clibaudioqueue *audio_shm_queue;					// 音频包存储队列
 		rvc_sales_audio_capture_t *parent;
 
@@ -190,7 +200,10 @@ namespace MediaController {
 	int videocap_innerdev_fetch(CSimpleStringA &frontcam,CSimpleStringA &rearcam);
 	int videocap_outerdev_fetch(CSimpleStringA envcam,CSimpleStringA optcam,CSimpleStringA ewscam,CAutoArray<CSimpleStringA> &hspcams,CSimpleStringA &outercam);
 	void capture_lib_term();
-	int capture_get_audio_device_id(bool in_direction, const char *dev_name);
+
+#ifdef RVC_OS_WIN
+	int capture_get_audio_device_id(bool in_direction, const char* dev_name);
+#endif
 	int capture_get_video_device_id(const char *dev_name);
 	bool capture_adj_brightness(capture_t *cap,int nvalue,ErrorCodeEnum nCode);
 	bool capture_set_autobrightness(capture_t *cap,ErrorCodeEnum nCode);

+ 54 - 0
Module/mod_mediacontroller/mod_mediacontroller.cpp

@@ -92,6 +92,7 @@ public:
 		m_env_mutex = PTHREAD_MUTEX_INITIALIZER;
 		m_opt_mutex = PTHREAD_MUTEX_INITIALIZER;
 		m_envopt_mutex = PTHREAD_MUTEX_INITIALIZER;
+		m_pAudioCap = NULL;
 #endif
 	}
 
@@ -195,6 +196,19 @@ public:
 				Dbg("Begin BeginRecv ACM_TYPE_DEVICE success!");
 			}
 		}
+#ifdef RVC_OS_WIN
+#else
+		{
+			m_pAudioCap = new AudioCapObj();
+			if (0 == m_pAudioCap->AudioMgrInitialize()) {
+				Dbg("Audio Manager Initialize success!");
+			}
+			else {
+				Dbg("Audio Manager Initialize failed!");
+				return;
+			}
+		}
+#endif
 
 		//is Pad Version
 		m_eDeviceType = RvcGetDeviceType();
@@ -215,6 +229,10 @@ public:
 		Error = (ErrorCodeEnum)capture_lib_init();
 		if (Error == Error_Succeed)
 		{
+#ifdef RVC_OS_WIN
+#else
+			RvcGetAudioDevice();
+#endif
 			Error = LoadConfig(&conf);
 			if (Error!=Error_Succeed)
 			{
@@ -475,6 +493,32 @@ public:
 #endif // RVC_OS_WIN
 	}
 
+#ifdef RVC_OS_WIN
+#else
+	ErrorCodeEnum RvcGetAudioDevice()
+	{
+		ErrorCodeEnum Error = Error_Param;
+		if (NULL != m_pAudioCap){
+			int icountmic = m_pAudioCap->audio_get_device_count(true);
+			Dbg("audio input device(%d):", icountmic);
+			int i = 0;
+			for (; i < icountmic; i++) {
+				char strname[MAX_PATH] = { 0 };
+				m_pAudioCap->audio_get_device_name(strname, MAX_PATH, true, i);
+				Dbg("%d = %s", i, strname);
+			}
+			int icountspeaker = m_pAudioCap->audio_get_device_count(false);
+			Dbg("audio output device(%d):", icountspeaker);
+			for (i = 0; i < icountspeaker; i++) {
+				char strname[MAX_PATH] = { 0 };
+				m_pAudioCap->audio_get_device_name(strname, MAX_PATH, false, i);
+				Dbg("%d = %s", i, strname);
+			}
+			Error = Error_Succeed;
+		}
+		return Error;
+	}
+#endif
 
 	DeviceTypeEnum RvcGetDeviceType()
 	{
@@ -664,6 +708,11 @@ public:
 			DestroyIAudioRenderObj(m_pAudioRenderObj);
 		}
 #else
+		if (NULL != m_pAudioCap){
+			m_pAudioCap->AudioMgrTerminate();
+			delete m_pAudioCap;
+			m_pAudioCap = NULL;
+		}
 
 #endif // RVC_OS_WIN
 
@@ -1796,6 +1845,10 @@ private:
 			Error = (ErrorCodeEnum)capture_create(&conf, &m_capture);
 			if (Error == Error_Succeed) 
 			{
+#ifdef RVC_OS_WIN
+#else
+				m_capture->audio->paudiocap = m_pAudioCap;
+#endif
 				Error = capture_start(m_capture);
 				Dbg("capture_start Error code=0x%x",Error);
 				if (Error != Error_Succeed)
@@ -2258,6 +2311,7 @@ private:
 	pthread_mutex_t m_env_mutex;
 	pthread_mutex_t m_opt_mutex;
 	pthread_mutex_t m_envopt_mutex;
+	AudioCapObj* m_pAudioCap;
 #endif
 };