Pārlūkot izejas kodu

Z991239-1563 #comment other: Linux下提挂机声音切换功能迁移改造

陈礼鹏80274480 4 gadi atpakaļ
vecāks
revīzija
66f748b70b

+ 0 - 13
Other/libaudioframework/CMakeLists.txt

@@ -322,19 +322,6 @@ endif(WIN32)
 
 target_link_libraries(${MODULE_NAME} PRIVATE ${${MODULE_PREFIX}_LIBS})  
 
-if(MSVC)
-	install(TARGETS ${MODULE_NAME} 
-    RUNTIME DESTINATION "${RVC_RUNTIME_PATH}" COMPONENT libraries
-    ARCHIVE DESTINATION "${RVC_LIBRARY_PATH}" COMPONENT develops EXCLUDE_FROM_ALL
-    LIBRARY DESTINATION "${RVC_LIBRARY_PATH}" COMPONENT libraries
-    )
-else(MSVC)
-install(TARGETS ${MODULE_NAME} 
-    RUNTIME DESTINATION "${RVC_RUNTIME_PATH}"
-    ARCHIVE DESTINATION "${RVC_LIBRARY_PATH}"
-    LIBRARY DESTINATION "${RVC_RUNTIME_PATH}"
-    COMPONENT libraries)
-endif(MSVC)
 
 if(MSVC)
 set(OTHER_CONAN_DEP_LIBS ${OTHER_CONAN_DEP_LIBS} ${CONAN_BIN_DIRS} PARENT_SCOPE)

+ 4 - 4
Other/libaudioframework/audiocontext.c

@@ -2,6 +2,7 @@
 #include "audiocontext.h"
 #include "audiostream.h"
 #include "audiodriver.h"
+#include "audiolog.h"
 
 #ifdef _WIN32
 #else
@@ -55,7 +56,9 @@ static void *APR_THREAD_FUNC audiocontext_run(apr_thread_t *thread_handle, void
 #ifdef _WIN32
 		WaitForSingleObject(ctx->sem, INFINITE);
 #else
+		audio_log_v(AUDIO_LOG_LEVEL_INFO, "before sem_wait......");
 		sem_wait(ctx->sem);
+		audio_log_v(AUDIO_LOG_LEVEL_INFO, "after sem_wait......");
 #endif // _WIN32
 		if (!ctx->bstop) {
 			int i;
@@ -63,6 +66,7 @@ static void *APR_THREAD_FUNC audiocontext_run(apr_thread_t *thread_handle, void
 			//OutputDebugStringA("enter lock");
 			for (i = 0; i < ctx->arr_drv->nelts; ++i) {
 				audiodriver_t *drv = APR_ARRAY_IDX(ctx->arr_drv, i, audiodriver_t*);
+				//ÔÝʱÆÁ±ÎrtpÁ÷·¢Ë͹¦ÄÜ
 				drv->vtbl->process_frame(drv);
 			}
 			while (ctx->event_list_cnt > 0) {
@@ -113,10 +117,6 @@ apr_status_t audiocontext_create(apr_pool_t *pool, audioengine_t *e, audiocontex
 	if (ctx->sem){
 		int ivalue = -1;
 		sem_getvalue(ctx->sem, &ivalue);
-		printf("%s:%d sem_init success, and sem value is %d.\n", __FUNCTION__, __LINE__, ivalue);
-	}
-	else {
-		printf("%s:%d sem_init failed for %s.\n", __FUNCTION__, __LINE__, strerror(errno));
 	}
 #endif // _WIN32
 	if (!ctx->sem) {

+ 1 - 0
Other/libaudioframework/audioengine.c

@@ -74,6 +74,7 @@ static void engine_on_clock(audioengine_t *e)
 		for (i = 0; i < e->arr_ctx->nelts; ++i) {
 			audiocontext_t *ctx = APR_ARRAY_IDX(e->arr_ctx, i, audiocontext_t*);
 			audiocontext_signal(ctx);
+			audio_log_v(AUDIO_LOG_LEVEL_INFO, "audiocontext_signal ********");
 		}
 	}
 	apr_thread_mutex_unlock(e->mtx);

+ 117 - 46
Other/libaudioframework/audiomicspklinux.c

@@ -1,4 +1,3 @@
-#include "precompile.h"
 #include "audiomicspklinux.h"
 #include "audiocontext.h"
 #include "audiolog.h"
@@ -7,8 +6,11 @@
 #include <portaudio.h>
 #include <assert.h>
 #include <speex/speex_resampler.h>
+#include <time.h>
+
 
 #define MAX_DELAY			60
+#define CLOCK_PERIOD		20
 
 static int get_device_index(int indev, const char* key)
 {
@@ -39,20 +41,21 @@ static int outStreamCallback(const void* input,
 	apr_status_t status;
 
 	if (output) {
-		unsigned nsamples_req = frameCount;
-		if (micspk->ply_buf_cnt == 0 && nsamples_req == micspk->capture_frame_samples) {
-			SHORT data[160];
-			spx_uint32_t in_len = micspk->frame_samples;
-			spx_uint32_t out_len = micspk->capture_frame_samples;
-			delay_buf_get((delay_buf*)micspk->ply_dbuf, data);
-			if (micspk->user_data)
-			{
-				micspk->on_rx_audio((char*)data, micspk->user_data);
-			}
-			//speex_resampler_process_int((SpeexResamplerState*)micspk->output_resample_state, 0,
-			//	data, &in_len, (spx_int16_t*)output, &out_len);
-			memcpy(output, data, in_len*sizeof(float));
-		}
+		//unsigned nsamples_req = frameCount;
+		//if (micspk->ply_buf_cnt == 0 && nsamples_req == micspk->capture_frame_samples) {
+		//	SHORT data[160];
+		//	spx_uint32_t in_len = micspk->frame_samples;
+		//	spx_uint32_t out_len = micspk->capture_frame_samples;
+		//	delay_buf_get((delay_buf*)micspk->ply_dbuf, data);
+		//	if (micspk->user_data)
+		//	{
+		//		micspk->on_rx_audio((char*)data, micspk->user_data);
+		//	}
+		//	//speex_resampler_process_int((SpeexResamplerState*)micspk->output_resample_state, 0,
+		//	//	data, &in_len, (spx_int16_t*)output, &out_len);
+		//	memcpy(output, data, in_len*sizeof(float));
+		//}
+		audio_log_v(AUDIO_LOG_LEVEL_INFO, "audio speaker outStreamCallback.");
 	}
 	return paContinue;
 }
@@ -74,19 +77,20 @@ static int inStreamCallback(const void* input,
 		}
 		else {
 			unsigned long nsamples = frameCount + micspk->rec_buf_cnt;
-			while (nsamples >= micspk->frame_samples) {
-				unsigned chunk_count = micspk->frame_samples - micspk->rec_buf_cnt;
-				memcpy(micspk->rec_buf + micspk->rec_buf_cnt, input, chunk_count << 1);
-				input = (const short*)input + chunk_count;
-				delay_buf_put(micspk->rec_dbuf, micspk->rec_buf);
-				micspk->rec_buf_cnt = 0;
-				nsamples -= micspk->frame_samples;
-			}
-			if (nsamples > 0) {
-				memcpy(micspk->rec_buf + micspk->rec_buf_cnt, input, nsamples << 1);
-				micspk->rec_buf_cnt += nsamples;
-			}
+			//while (nsamples >= micspk->frame_samples) {
+			//	unsigned chunk_count = micspk->frame_samples - micspk->rec_buf_cnt;
+			//	memcpy(micspk->rec_buf + micspk->rec_buf_cnt, input, chunk_count << 1);
+			//	input = (const short*)input + chunk_count;
+			//	delay_buf_put(micspk->rec_dbuf, micspk->rec_buf);
+			//	micspk->rec_buf_cnt = 0;
+			//	nsamples -= micspk->frame_samples;
+			//}
+			//if (nsamples > 0) {
+			//	memcpy(micspk->rec_buf + micspk->rec_buf_cnt, input, nsamples << 1);
+			//	micspk->rec_buf_cnt += nsamples;
+			//}
 		}
+		audio_log_v(AUDIO_LOG_LEVEL_INFO, "audio micro inStreamCallback.");
 	}
 	
 	return paContinue;
@@ -125,6 +129,8 @@ static audiostream_vtbl_t g_stream_vtbl = {
 
 void audiomicspklinux_destroy(audiomicspklinux_t* micspk)
 {
+	sem_post(micspk->audio_device_started_sem);
+
 	if (micspk->ply_stream) {
 		Pa_AbortStream(micspk->ply_stream);
 		Pa_CloseStream(micspk->ply_stream);
@@ -142,6 +148,7 @@ void audiomicspklinux_destroy(audiomicspklinux_t* micspk)
 	if (micspk->opt & AMS_OPT_AS_ENGINE) {
 		//DeleteCriticalSection(&micspk->engine_lock);
 	}
+	sem_destroy(micspk->audio_device_started_sem);
 }
 
 static int initialize_speaker(audiomicspklinux_t* micspk)
@@ -170,7 +177,7 @@ static int initialize_speaker(audiomicspklinux_t* micspk)
 	}
 	audio_log_v(AUDIO_LOG_LEVEL_INFO, "audio micspk create success! audio output device defaultSampleRate is %f", info->defaultSampleRate);
 
-	UINT32 capture_frame_samples = info->defaultSampleRate * FRAME_TIME / 1000;
+	uint32_t capture_frame_samples = info->defaultSampleRate * FRAME_TIME / 1000;
 
 	paError = Pa_OpenStream(&micspk->ply_stream, NULL, &outParam, info->defaultSampleRate, capture_frame_samples, paClipOff, &outStreamCallback, micspk);
 	if (paError != 0) {
@@ -196,8 +203,8 @@ static int initialize_speaker(audiomicspklinux_t* micspk)
 static int initialize_micro(audiomicspklinux_t* micspk)
 {
 	const PaDeviceInfo* info;
-	PaStreamParameters inParam;
-	PaError paError;
+	PaStreamParameters inParam = {0};
+	
 	int micro_dev_id = micspk->rec_dev_id;
 
 	if (micro_dev_id == -1) {
@@ -207,30 +214,33 @@ static int initialize_micro(audiomicspklinux_t* micspk)
 			return APR_EGENERAL;
 		}
 	}
+
 	info = Pa_GetDeviceInfo(micro_dev_id);
 	inParam.device = micro_dev_id;
 	inParam.channelCount = 1;
 	inParam.sampleFormat = paFloat32;
-	inParam.suggestedLatency = info->defaultLowOutputLatency;
+	inParam.suggestedLatency = info->defaultLowInputLatency;
 	inParam.hostApiSpecificStreamInfo = NULL;
-	if (Pa_IsFormatSupported(NULL, &inParam, info->defaultSampleRate) != paNoError) {
+	audio_log_v(AUDIO_LOG_LEVEL_INFO, "audio input device name is %s.", info->name);
+	PaError paError = Pa_IsFormatSupported(&inParam, NULL, info->defaultSampleRate);
+	if (paNoError != paError) {
 		audio_log_v(AUDIO_LOG_LEVEL_ERROR, "audio micro create error, cannot open audio input device.");
 		return APR_EGENERAL;
 	}
 	audio_log_v(AUDIO_LOG_LEVEL_INFO, "audio micspk create success, open audio input device success! and defaultSampleRate is %f.", info->defaultSampleRate);
 
-	UINT32 capture_frame_samples = info->defaultSampleRate * FRAME_TIME / 1000;
+	uint32_t capture_frame_samples = info->defaultSampleRate * FRAME_TIME / 1000;
 
-	paError = Pa_OpenStream(&micspk->rec_stream, NULL, &inParam, info->defaultSampleRate, capture_frame_samples, paClipOff, &inStreamCallback, micspk);
-	if (paError != 0) {
-		audio_log_v(AUDIO_LOG_LEVEL_ERROR, "audio micspk create error, Pa_OpenStream function failed in dir! ");
+	paError = Pa_OpenStream(&micspk->rec_stream, &inParam, NULL, info->defaultSampleRate, capture_frame_samples, paClipOff|paDitherOff, &inStreamCallback, micspk);
+	if (paNoError != paError) {
+		audio_log_v(AUDIO_LOG_LEVEL_ERROR, "audio input Pa_OpenStream function failed for %s.", Pa_GetErrorText(paError));
 		return APR_EGENERAL;
 	}
 	audio_log_v(AUDIO_LOG_LEVEL_INFO, "audio micspk create success, audio input device Pa_OpenStream success!");
 
 	paError = Pa_StartStream(micspk->rec_stream);
 	if (paError != 0) {
-		audio_log_v(AUDIO_LOG_LEVEL_ERROR, "Pa_StartStream function failed in dir! ");
+		audio_log_v(AUDIO_LOG_LEVEL_ERROR, "Pa_StartStream function failed!");
 		Pa_CloseStream(micspk->rec_stream);
 		micspk->rec_stream = NULL;
 		return APR_EGENERAL;
@@ -271,12 +281,11 @@ static void uninitialize_micro(audiomicspklinux_t* micspk)
 	audio_log_v(AUDIO_LOG_LEVEL_INFO, "uninitialize_micro success!");
 }
 
-
-void* audiowork_proc(void* param)
+void* APR_THREAD_FUNC* audiowork_proc(apr_thread_t* threadhandle, void* param)
 {
 	audiomicspklinux_t* micspk = (audiomicspklinux_t*)param;
 	int rc;
-
+	audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d micspk addr is 0x%0x, current sem addr is 0x%0x.  started flag is %s.", __FUNCTION__, __LINE__, param, micspk->audio_device_started_sem, micspk->baudio_device_started_flag ? "true" : "false");
 	//
 	// record need play because of AEC, so 
 	// record <---> record and play
@@ -313,8 +322,36 @@ void* audiowork_proc(void* param)
 			audio_log_v(AUDIO_LOG_LEVEL_INFO, "play mode initialize speak louder param success!");
 		}
 	}
-on_error:
 
+	micspk->baudio_device_started_flag = true;
+
+	audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d micspk addr is 0x%0x, current sem addr is 0x%0x.", __FUNCTION__, __LINE__, micspk, micspk->audio_device_started_sem);
+
+	while (true)
+	{
+		struct timespec ts;
+		//int ivalue = -1;
+		clock_gettime(CLOCK_REALTIME, &ts);
+		ts.tv_nsec += 1000 * 1000 * CLOCK_PERIOD;
+		
+		//sem_getvalue(micspk->audio_device_started_sem, &ivalue);
+		//audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d current sem value is %d.", __FUNCTION__, __LINE__, ivalue);
+		if (-1 == sem_timedwait(micspk->audio_device_started_sem, &ts)) {
+			if (ETIMEDOUT == errno) {
+				if (micspk->opt & AMS_OPT_RECORD) {
+					//on_clock_rec(micspk);
+				}
+				else if (micspk->opt & AMS_OPT_PLAY) {
+					//on_clock_spk(micspk);
+				}
+			}
+		}
+		else {
+			break;
+		}
+	} 
+
+on_error:
 	if (micspk->opt & AMS_OPT_RECORD) {
 		uninitialize_micro(micspk);
 		uninitialize_speaker(micspk);
@@ -352,6 +389,7 @@ apr_status_t audiomicspklinux_create(apr_pool_t* pool,
 
 	micspk = apr_palloc(pool, sizeof(audiomicspklinux_t));
 	memset(micspk, 0, sizeof(audiomicspklinux_t));
+	micspk->audio_device_started_sem = (sem_t*)apr_palloc(pool, sizeof(sem_t));
 
 	frame_samples = FRAME_TIME * clock / 1000;
 	capture_frame_samples = FRAME_TIME * clock / 1000;
@@ -368,23 +406,56 @@ apr_status_t audiomicspklinux_create(apr_pool_t* pool,
 
 	if (opt & AMS_OPT_PLAY) {
 		micspk->base.direction |= STREAM_DIR_WRITE;
-		delay_buf_create(clock, frame_samples, 1, MAX_DELAY, 0, (delay_buf * *)& micspk->ply_dbuf);
+		delay_buf_create(clock, frame_samples, 1, MAX_DELAY, 0, (delay_buf**)& micspk->ply_dbuf);
 		micspk->ply_buf = (short*)apr_palloc(pool, frame_samples << 1);
 		micspk->ply_buf_cnt = 0;
 		//micspk->output_resample_state = speex_resampler_init(1, AUDIO_CLOCK, CAPTURE_AUDIO_CLOCK, RESAMPLE_QUALITY, NULL);
 	}
 	if (opt & AMS_OPT_RECORD) {
 		micspk->base.direction |= STREAM_DIR_READ;
-		delay_buf_create(clock, frame_samples, 1, MAX_DELAY, 0, (delay_buf * *)& micspk->rec_dbuf);
+		delay_buf_create(clock, frame_samples, 1, MAX_DELAY, 0, (delay_buf**)& micspk->rec_dbuf);
 		//micspk->input_resample_state = speex_resampler_init(1, CAPTURE_AUDIO_CLOCK, AUDIO_CLOCK, RESAMPLE_QUALITY, NULL);
 	}
-
-	int err = pthread_create(&micspk->audio_work_threadid, NULL, audiowork_proc, micspk);
-	if (0 == err) {
+	micspk->baudio_device_started_flag = false;
+	sem_init(micspk->audio_device_started_sem, 0, 0);
+	audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d micspk addr is 0x%0x, current sem addr is 0x%0x. started flag is %s.", __FUNCTION__, __LINE__, micspk, micspk->audio_device_started_sem, micspk->baudio_device_started_flag ? "true" : "false");
+	apr_status_t err = apr_thread_create(&micspk->audio_work_threadid, NULL, audiowork_proc, micspk, pool);
+	if (APR_SUCCESS == err) {
 		Dbg("create audiomicspk work thread success, %lu.", micspk->audio_work_threadid);
+		bool baudio_work_thread_exit = false;
+		
+		do {
+			struct timespec ts;
+			int ivalue = -1;
+			clock_gettime(CLOCK_REALTIME, &ts);
+			ts.tv_nsec += 1000 * 1000 * 10;
+			sem_getvalue(micspk->audio_device_started_sem, &ivalue);
+			audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d current sem value is %d.", __FUNCTION__, __LINE__, ivalue);
+			if(-1 == sem_timedwait(micspk->audio_device_started_sem, &ts)) {
+				if (ETIMEDOUT == errno){
+					if (micspk->baudio_device_started_flag) {
+						audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d audio device is already started.", __FUNCTION__, __LINE__);
+						break;
+					}
+				}
+			}
+			else{
+				audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d audio device work thread has exit.", __FUNCTION__, __LINE__);
+				baudio_work_thread_exit = true;
+			}
+		} while (!baudio_work_thread_exit);
+
+		if (baudio_work_thread_exit) {
+			audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d", __FUNCTION__, __LINE__);
+			audiomicspklinux_destroy(micspk);
+			audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d", __FUNCTION__, __LINE__);
+			return APR_EGENERAL;
+		}
 	}
 	else {
 		Dbg("create audiomicspk work thread failed.");
+		audiomicspklinux_destroy(micspk);
+		return APR_EGENERAL;
 	}
 
 	*p_micspk = micspk;

+ 42 - 41
Other/libaudioframework/audiomicspklinux.h

@@ -1,4 +1,3 @@
-
 #pragma once
 
 #ifdef __cplusplus
@@ -11,49 +10,51 @@ extern "C" {
 #define AMS_OPT_AS_STREAM	0x00
 #define AMS_OPT_AS_ENGINE	0x04
 
+#include "precompile.h"
 #include "audiostream.h"
+#include <stdbool.h>
+
+typedef struct audiomicspklinux_s
+{
+	audiostream_t base;
+	int opt;
+	int rec_dev_id;
+	int ply_dev_id;
+	int frame_samples;
+	int capture_frame_samples;
+
+	void* ply_stream;
+	void* ply_dbuf;
+	short* ply_buf;
+	unsigned ply_buf_cnt;
+
+	void* rec_stream;
+	void* rec_buf;
+	void* rec_dbuf;
+	unsigned long  rec_buf_cnt;
+
+	apr_thread_t* audio_work_threadid;
+	sem_t* audio_device_started_sem;
+	bool baudio_device_started_flag;
+
+	void* input_resample_state;
+	void* output_resample_state;
+
+	int (*on_rx_audio)(char* frame, void* user_data);
+	void* user_data;
+}audiomicspklinux_t;
+
+apr_status_t audiomicspklinux_create(apr_pool_t* pool,
+	audioengine_t* engine,
+	int opt,
+	int clock,
+	const char* rec_dev_key,
+	const char* ply_dev_key,
+	audiomicspklinux_t** p_micspk);
+
+void audiomicspklinux_destroy(audiomicspklinux_t* micspk);
 
 
-	typedef struct audiomicspklinux_s
-	{
-		audiostream_t base;
-
-		int opt;
-		int rec_dev_id;
-		int ply_dev_id;
-		int frame_samples;
-		int capture_frame_samples;
-
-		void* ply_stream;
-		void* ply_dbuf;
-		short* ply_buf;
-		unsigned ply_buf_cnt;
-
-		void* rec_stream;
-		void* rec_buf;
-		void* rec_dbuf;
-		unsigned long  rec_buf_cnt;
-
-		unsigned long int audio_work_threadid;
-
-		void* input_resample_state;
-		void* output_resample_state;
-
-		int (*on_rx_audio)(char* frame, void* user_data);
-		void* user_data;
-
-	}audiomicspklinux_t;
-
-	apr_status_t audiomicspklinux_create(apr_pool_t* pool,
-		audioengine_t* engine,
-		int opt,
-		int clock,
-		const char* rec_dev_key,
-		const char* ply_dev_key,
-		audiomicspklinux_t** p_micspk);
-
-	void audiomicspklinux_destroy(audiomicspklinux_t* micspk);
-
 #ifdef __cplusplus
 } // extern "C" {
 #endif

+ 65 - 9
Other/libaudioframework/audiortp.c

@@ -130,10 +130,18 @@ static apr_status_t read_frame(void *self, audioframe_t *frame)
 					if (digit[j] < sizeof(digitmap)) {
 						int ch = digitmap[digit[j]];
 						audiostream_raise_event(self, STREAM_EVT_RTP_DTMF, digit[j], 0);
+#ifdef _WIN32
 						EnterCriticalSection(&audiortp->m_dtmf_lock);
+#else
+						apr_thread_mutex_lock(audiortp->m_dtmf_mtx);
+#endif
 						if (audiortp->m_recv_dtmf_cnt < MAX_DTMF)
 							audiortp->m_recv_dtmf[audiortp->m_recv_dtmf_cnt++] = digit[j];
+#ifdef _WIN32 
 						LeaveCriticalSection(&audiortp->m_dtmf_lock);
+#else
+						apr_thread_mutex_unlock(audiortp->m_dtmf_mtx);
+#endif
 					}
 				}
 				if (digit_cnt > 0)
@@ -177,9 +185,14 @@ static apr_status_t write_frame(void *self, const audioframe_t *frame)
 	audiortp_t *audiortp = CONTAINING_RECORD(self, audiortp_t, base);
 	int dtmf = 0;
 
+#ifdef WIN32
 	EnterCriticalSection(&audiortp->m_dtmf_lock);
-	if (frame->dtmf && CIRC_LEN(audiortp->m_send_dtmf_rd, audiortp->m_send_dtmf_wr, MAX_DTMF) < MAX_DTMF-1) {
-		rtp_dtmf_event *dtmf = &audiortp->m_send_dtmf[audiortp->m_send_dtmf_wr];
+#else
+	apr_thread_mutex_lock(audiortp->m_dtmf_mtx);
+#endif
+
+	if (frame->dtmf && CIRC_LEN(audiortp->m_send_dtmf_rd, audiortp->m_send_dtmf_wr, MAX_DTMF) < MAX_DTMF - 1) {
+		rtp_dtmf_event* dtmf = &audiortp->m_send_dtmf[audiortp->m_send_dtmf_wr];
 		dtmf->event = (unsigned char)digit2event(frame->dtmf);
 		dtmf->e_vol = DTMF_VOLUME;
 		dtmf->p = 0;
@@ -188,7 +201,7 @@ static apr_status_t write_frame(void *self, const audioframe_t *frame)
 		audiortp->m_send_dtmf_wr = CIRC_INC(audiortp->m_send_dtmf_wr, MAX_DTMF);
 	}
 	if (!CIRC_IS_EMPTY(audiortp->m_send_dtmf_rd, audiortp->m_send_dtmf_wr)) {
-		rtp_dtmf_event *digit = &audiortp->m_send_dtmf[audiortp->m_send_dtmf_rd];
+		rtp_dtmf_event* digit = &audiortp->m_send_dtmf[audiortp->m_send_dtmf_rd];
 		send_dtmf_digit(audiortp->m_rtpsession, digit, audiortp->m_send_dtmf_pt);
 		dtmf = 1;
 		digit->duration += DTMF_DURATION_STEP;
@@ -196,12 +209,17 @@ static apr_status_t write_frame(void *self, const audioframe_t *frame)
 			if (digit->duration == DTMF_DURATION) {
 				digit->e = 1;
 			}
-		} else {
+		}
+		else {
 			audiortp->m_send_dtmf_rd = CIRC_INC(audiortp->m_send_dtmf_rd, MAX_DTMF);
 			rtp_session_advance_timestamp(audiortp->m_rtpsession, DTMF_DURATION);
 		}
 	}
+#ifdef _WIN32
 	LeaveCriticalSection(&audiortp->m_dtmf_lock);
+#else
+	apr_thread_mutex_unlock(audiortp->m_dtmf_mtx);
+#endif // WIN32
 
 	if (dtmf) {
 		/* because we send dtmf, so ignore this frame */
@@ -256,11 +274,16 @@ static audiostream_vtbl_t g_stream_vtbl = {
 void audiortp_destroy(audiortp_t *self)
 {
 	audiortp_t *audiortp = (audiortp_t *)self;
+#ifdef _WIN32
 	DeleteCriticalSection(&audiortp->m_dtmf_lock);
+#else
+	apr_thread_mutex_destroy(audiortp->m_dtmf_mtx);
+#endif // _WIN32
 }
 
 apr_status_t audiortp_create(apr_pool_t *pool, audioengine_t *engine, rtp_session_t *sess, audiortp_t **p_audiortp)
 {
+	apr_status_t status = -1;
 	audiortp_t *audiortp;
 
 	audiortp = apr_palloc(pool, sizeof(audiortp_t));
@@ -296,9 +319,16 @@ apr_status_t audiortp_create(apr_pool_t *pool, audioengine_t *engine, rtp_sessio
 	audiortp->m_on_recv_hook = NULL;
 	audiortp->m_on_send_hook = NULL;
 	audiortp->m_hook_data = NULL;
+
+#ifdef _WIN32
 	InitializeCriticalSection(&audiortp->m_dtmf_lock);
+	status = APR_SUCCESS;
+#else
+	status = apr_thread_mutex_create(&audiortp->m_dtmf_mtx, APR_THREAD_MUTEX_NESTED, pool);
+#endif // _WIN32
+
 	*p_audiortp = audiortp;
-	return APR_SUCCESS;
+	return status;
 }
 
 apr_status_t audiortp_set_param(audiortp_t *audiortp, int flag, const void *ptr)
@@ -396,6 +426,7 @@ apr_status_t audiortp_get_param(audiortp_t *audiortp, int flag, void *ptr)
 apr_status_t audiortp_init(audiortp_t *ar)
 {
 	audiortp_t *audiortp = (audiortp_t *)ar;
+	Dbg("%s : %d", __FUNCTION__, __LINE__);
 	audiortp->m_send_samplebit = pt2bitsample(audiortp->m_send_pt);
 	audiortp->m_recv_samplebit = pt2bitsample(audiortp->m_recv_pt);
 	audiortp->m_send_psize = audiortp->m_send_ptime * audiortp->m_send_clock / 1000 * audiortp->m_send_samplebit / 8;
@@ -405,6 +436,7 @@ apr_status_t audiortp_init(audiortp_t *ar)
 	jbuf_create(audiortp->m_jbuf_psize, audiortp->m_jbuf_ptime, JB_MAX, &audiortp->m_jitterbuf);
 	jbuf_set_adaptive(audiortp->m_jitterbuf, 0, 7, JB_MAX);
 	DEBUG_TRACE("audiortp init, send_psize:%d, recv_psize:%d", audiortp->m_send_psize, audiortp->m_recv_psize);
+	Dbg("%s : %d", __FUNCTION__, __LINE__);
 	return APR_SUCCESS;
 }
 
@@ -430,18 +462,30 @@ apr_status_t audiortp_send_dtmf(audiortp_t *self, const char *digits, unsigned c
 		return -1;
 	if (!(audiostream_get_direction(&audiortp->base)&STREAM_DIR_WRITE))
 		return -1;
+
+
+#ifdef _WIN32
 	EnterCriticalSection(&audiortp->m_dtmf_lock);
-	while (CIRC_LEN(audiortp->m_send_dtmf_rd, audiortp->m_send_dtmf_wr, MAX_DTMF) < MAX_DTMF-1 && count < cnt) {
-		rtp_dtmf_event *dtmf = &audiortp->m_send_dtmf[audiortp->m_send_dtmf_wr];
+#else
+	apr_thread_mutex_lock(audiortp->m_dtmf_mtx);
+#endif
+
+	while (CIRC_LEN(audiortp->m_send_dtmf_rd, audiortp->m_send_dtmf_wr, MAX_DTMF) < MAX_DTMF - 1 && count < cnt) {
+		rtp_dtmf_event* dtmf = &audiortp->m_send_dtmf[audiortp->m_send_dtmf_wr];
 		dtmf->event = (unsigned char)digit2event(digits[count]);
 		dtmf->e_vol = DTMF_VOLUME;
 		dtmf->p = 0;
 		dtmf->e = 0;
 		dtmf->duration = 0;
 		audiortp->m_send_dtmf_wr = CIRC_INC(audiortp->m_send_dtmf_wr, MAX_DTMF);
-		count ++;
+		count++;
 	}
+#ifdef _WIN32
 	LeaveCriticalSection(&audiortp->m_dtmf_lock);
+#else
+	apr_thread_mutex_unlock(audiortp->m_dtmf_mtx);
+#endif // _WIN32
+	
 
 	return APR_SUCCESS;
 }
@@ -460,15 +504,27 @@ apr_status_t audiortp_recv_dtmf(audiortp_t *self, char *digits, unsigned *cnt)
 	if (!digits)
 		return APR_BADARG;
 
+
+#ifdef _WIN32
 	EnterCriticalSection(&audiortp->m_dtmf_lock);
+#else
+	apr_thread_mutex_lock(audiortp->m_dtmf_mtx);
+#endif
 	while (count < *cnt && i < audiortp->m_recv_dtmf_cnt) {
 		digits[count++] = audiortp->m_recv_dtmf[i++];
 	}
 	if (i < audiortp->m_recv_dtmf_cnt)
-		memmove(&audiortp->m_recv_dtmf[0], &audiortp->m_recv_dtmf[i], audiortp->m_recv_dtmf_cnt-i);
+		memmove(&audiortp->m_recv_dtmf[0], &audiortp->m_recv_dtmf[i], audiortp->m_recv_dtmf_cnt - i);
 	audiortp->m_recv_dtmf_cnt -= i;
 	*cnt = count;
+
+#ifdef _WIN32
 	LeaveCriticalSection(&audiortp->m_dtmf_lock);
+#else
+	apr_thread_mutex_unlock(audiortp->m_dtmf_mtx);
+#endif // _WIN32
+	
+
 
 	return APR_SUCCESS;
 }

+ 5 - 0
Other/libaudioframework/audiortp.h

@@ -57,7 +57,12 @@ struct audiortp_t
 	int m_recv_dtmf_cnt;
 	unsigned int m_recving_dtmf_ts;
 	rtp_dtmf_event m_recving_dtmf_event;
+#ifdef _WIN32
 	CRITICAL_SECTION m_dtmf_lock;
+#else
+	apr_thread_mutex_t* m_dtmf_mtx;
+#endif
+	
 	void (*m_on_send_hook)(const char *buf, int size, void *arg);
 	void (*m_on_recv_hook)(const char *buf, int size, void *arg);
 	void *m_hook_data;

+ 65 - 16
Other/libaudioframework/other/delaybuf.c

@@ -17,6 +17,7 @@
 
 
 
+
 /* Operation types of delay buffer */
 enum OP
 {
@@ -42,7 +43,11 @@ enum OP
 struct delay_buf
 {
     /* Properties and configuration */
+#ifdef _WIN32
 	CRITICAL_SECTION lock;
+#else
+	pthread_mutex_t lock_mtx;
+#endif
     unsigned	     samples_per_frame; /**< Number of samples in one frame  */
     unsigned	     ptime;		/**< Frame time, in ms		     */
     unsigned	     channel_count;	/**< Channel count, in ms	     */
@@ -103,8 +108,11 @@ int delay_buf_create(unsigned clock_rate,
 	return status;
 
     /* Finally, create mutex */
+#ifdef _WIN32
 	InitializeCriticalSection(&b->lock);
-
+#else
+	status = pthread_mutex_init(&b->lock_mtx, NULL);
+#endif
     *p_b = b;
 
     return 0;
@@ -115,19 +123,24 @@ int delay_buf_destroy(delay_buf *b)
     int status;
 
     ASSERT_RETURN(b, -1);
-
+#ifdef _WIN32
 	EnterCriticalSection(&b->lock);
-
+#else
+	pthread_mutex_lock(&b->lock_mtx);
+#endif
     status = wsola_destroy(b->wsola);
     if (status == 0)
 		b->wsola = NULL;
 	circ_buf_destroy(b->circ_buf);
 	b->circ_buf = NULL;
 
-    LeaveCriticalSection(&b->lock);
-
-    DeleteCriticalSection(&b->lock);
-
+#ifdef _WIN32
+	LeaveCriticalSection(&b->lock);
+	DeleteCriticalSection(&b->lock);
+#else
+	pthread_mutex_unlock(&b->lock_mtx);
+	pthread_mutex_destroy(&b->lock_mtx);
+#endif
 	free(b);
 
     return status;
@@ -217,13 +230,21 @@ int delay_buf_put(delay_buf *b,
 
     ASSERT_RETURN(b && frame, -1);
 
-    EnterCriticalSection(&b->lock);
+#ifdef _WIN32
+	EnterCriticalSection(&b->lock);
+#else
+	pthread_mutex_lock(&b->lock_mtx);
+#endif
 
     update(b, OP_PUT);
     
     status = wsola_save(b->wsola, frame, FALSE);
     if (status != 0) {
-	LeaveCriticalSection(&b->lock);
+#ifdef _WIN32
+		LeaveCriticalSection(&b->lock);
+#else
+		pthread_mutex_unlock(&b->lock_mtx);
+#endif
 	return status;
     }
 
@@ -256,7 +277,11 @@ int delay_buf_put(delay_buf *b,
 
     circ_buf_write(b->circ_buf, frame, b->samples_per_frame);
 
-    LeaveCriticalSection(&b->lock);
+#ifdef _WIN32
+	LeaveCriticalSection(&b->lock);
+#else
+	pthread_mutex_unlock(&b->lock_mtx);
+#endif
     return 0;
 }
 
@@ -266,7 +291,11 @@ int delay_buf_get( delay_buf *b,short frame[])
 
     ASSERT_RETURN(b && frame, -1);
 
-    EnterCriticalSection(&b->lock);
+#ifdef _WIN32
+	EnterCriticalSection(&b->lock);
+#else
+	pthread_mutex_lock(&b->lock_mtx);
+#endif
 
     update(b, OP_GET);
 
@@ -279,7 +308,11 @@ int delay_buf_get( delay_buf *b,short frame[])
 
 	if (status == 0) {
 	    if (circ_buf_get_len(b->circ_buf) == 0) {
-		LeaveCriticalSection(&b->lock);
+#ifdef _WIN32
+			LeaveCriticalSection(&b->lock);
+#else
+			pthread_mutex_unlock(&b->lock_mtx);
+#endif
 		return 0;
 	    }
 
@@ -297,7 +330,11 @@ int delay_buf_get( delay_buf *b,short frame[])
 	    /* The buffer is empty now, reset it */
 	    circ_buf_reset(b->circ_buf);
 
-	    LeaveCriticalSection(&b->lock);
+#ifdef _WIN32
+		LeaveCriticalSection(&b->lock);
+#else
+		pthread_mutex_unlock(&b->lock_mtx);
+#endif
 
 	    return 0;
 	}
@@ -305,7 +342,11 @@ int delay_buf_get( delay_buf *b,short frame[])
 
     circ_buf_read(b->circ_buf, frame, b->samples_per_frame);
 
-    LeaveCriticalSection(&b->lock);
+#ifdef _WIN32
+	LeaveCriticalSection(&b->lock);
+#else
+	pthread_mutex_unlock(&b->lock_mtx);
+#endif
 
     return 0;
 }
@@ -315,7 +356,11 @@ int delay_buf_reset(delay_buf *b)
 {
     ASSERT_RETURN(b, -1);
 
-    EnterCriticalSection(&b->lock);
+#ifdef _WIN32
+	EnterCriticalSection(&b->lock);
+#else
+	pthread_mutex_lock(&b->lock_mtx);
+#endif
 
     b->recalc_timer = RECALC_TIME;
 
@@ -325,7 +370,11 @@ int delay_buf_reset(delay_buf *b)
     /* Reset WSOLA */
     wsola_reset(b->wsola, 0);
 
-    LeaveCriticalSection(&b->lock);
+#ifdef _WIN32
+	LeaveCriticalSection(&b->lock);
+#else
+	pthread_mutex_unlock(&b->lock_mtx);
+#endif
 
     return 0;
 }

+ 1 - 1
Other/libaudioframework/precompile.h

@@ -4,7 +4,7 @@
 #include <Mmsystem.h>
 #include <windows.h>
 #else
-#include <wtypes.h>
+//#include <wtypes.h>
 #include <semaphore.h>
 #endif // _WIN32
 

+ 0 - 14
Other/libvideoframework/CMakeLists.txt

@@ -238,20 +238,6 @@ target_link_libraries(${MODULE_NAME} PRIVATE ${${MODULE_PREFIX}_LIBS}
 
 target_compile_definitions(${MODULE_NAME} PUBLIC "_XKEYCHECK_H")
 
-if(MSVC)
-	install(TARGETS ${MODULE_NAME} 
-    RUNTIME DESTINATION "${RVC_RUNTIME_PATH}" COMPONENT libraries
-    ARCHIVE DESTINATION "${RVC_LIBRARY_PATH}" COMPONENT develops EXCLUDE_FROM_ALL
-    LIBRARY DESTINATION "${RVC_LIBRARY_PATH}" COMPONENT libraries
-    )
-else(MSVC)
-install(TARGETS ${MODULE_NAME} 
-    RUNTIME DESTINATION "${RVC_RUNTIME_PATH}"
-    ARCHIVE DESTINATION "${RVC_LIBRARY_PATH}"
-    LIBRARY DESTINATION "${RVC_RUNTIME_PATH}"
-    COMPONENT libraries)
-endif(MSVC)
-
 
 if(MSVC)
 set(OTHER_CONAN_DEP_LIBS ${OTHER_CONAN_DEP_LIBS} ${CONAN_BIN_DIRS} PARENT_SCOPE)