Prechádzať zdrojové kódy

Z991239-1621 #comment 音频采集播放修改,增加重采样

胡琛80272472 4 rokov pred
rodič
commit
7854a5486c

+ 0 - 4
Module/mod_sipphone/audio_session.cpp

@@ -14,11 +14,7 @@
 #include "../../Other/rvcmediacommon/rvc_media_common.h"
 #include <string.h>
 
-#ifdef _WIN32
 #define AUDIO_CLOCK	8000
-#else
-#define AUDIO_CLOCK	44100
-#endif
 
 #define AUDIO_SHM_FRAME_TIME	20 // 20ms
 

+ 84 - 22
Other/libaudioframework/audiomicspklinux.c

@@ -11,6 +11,44 @@
 
 #define MAX_DELAY			60
 #define CLOCK_PERIOD		20
+#define AUDIO_CLOCK	8000
+#define CAPTURE_AUDIO_CLOCK	44100
+#define RESAMPLE_QUALITY	6
+
+
+static void From32To16Bit(void* input_data, int input_samples, void* output_data, int out_samples) {
+	int i = 0;
+	float f;
+	for (i = 0; i < input_samples; i++) {
+		float* pinput = (float*)input_data + i;
+		uint16_t* poutput = (uint16_t*)output_data + i;
+		//Dbg("[From32To16Bit]pinput :%f", *pinput);
+		f = *pinput;
+		f = f * 32768;
+		if (f > 32767) f = 32767;
+		if (f < -32768) f = -32768;
+		//转为正数
+		*poutput = f + 32768;
+		//Dbg("[From32To16Bit]poutput :%u, i: %d", *poutput, i);
+	}
+}
+
+static void From16ToFloat(void* input_data, int input_samples, void* output_data, int out_samples) {
+	int i = 0;
+	int input_value;
+	for (i = 0; i < input_samples; i++) {
+		uint16_t* pinput = (uint16_t*)input_data + i;
+		float* poutput = (float*)output_data + i;
+		//Dbg("[From16ToFloat]pinput :%u", *pinput);
+		input_value = *pinput;
+		//转为有符合数
+		input_value = input_value - 32768;
+		*poutput = ((float)input_value) / (float)32768;
+		if (*poutput > 1) *poutput = 1;
+		if (*poutput < -1) *poutput = -1;
+		//Dbg("[From16ToFloat]poutput :%f, i: %d", *poutput, i);
+	}
+}
 
 static int get_device_index(int indev, const char* key)
 {
@@ -41,20 +79,26 @@ 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) {
+			char* float_output;
+			int float_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);
+			float_samples = out_len;
+			float_output = malloc(float_samples * 32 / 8);
+			From16ToFloat(output, out_len, float_output, float_samples);
+			memcpy(output, float_output, float_samples * 32 / 8);
+			free(float_output);
+		}
 		audio_log_v(AUDIO_LOG_LEVEL_INFO, "audio speaker outStreamCallback.");
 	}
 	return paContinue;
@@ -72,21 +116,39 @@ static int inStreamCallback(const void* input,
 	apr_status_t status;
 
 	if (input) {
+		int in_samples = frameCount; //采集为32位float
 		if (micspk->rec_buf_cnt == 0 && frameCount == micspk->frame_samples) {
-			delay_buf_put(micspk->rec_dbuf, (short*)input);
+			int before_resample_samples = frameCount;//重采样前转为16位
+			int after_resample_samples = frameCount;
+			char before_resample_buffer[frameCount * 16 / 8];
+			char after_resample_buffer[frameCount * 16 / 8];
+			From32To16Bit(input, in_samples, before_resample_buffer, before_resample_samples);
+			speex_resampler_process_int((SpeexResamplerState*)micspk->input_resample_state, 0,
+				before_resample_buffer, &before_resample_samples, (spx_int16_t*)after_resample_buffer, &after_resample_samples);
+			delay_buf_put(micspk->rec_dbuf, (short*)after_resample_buffer);
 		}
 		else {
-			unsigned long nsamples = frameCount + micspk->rec_buf_cnt;
+			unsigned long nsamples;
+			//先转换为需要的格式
+			int before_resample_samples = frameCount;//重采样前转为16位
+			int after_resample_samples = frameCount;
+			char before_resample_buffer[frameCount * 16 / 8];
+			char after_resample_buffer[frameCount * 16 / 8];
+			From32To16Bit(input, in_samples, before_resample_buffer, before_resample_samples);
+			speex_resampler_process_int((SpeexResamplerState*)micspk->input_resample_state, 0,
+				before_resample_buffer, &before_resample_samples, (spx_int16_t*)after_resample_buffer, &after_resample_samples);
+
+			nsamples = after_resample_samples + 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;
+				memcpy(micspk->rec_buf + micspk->rec_buf_cnt, after_resample_buffer, chunk_count << 1);
+				input = (const float*)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);
+				memcpy(micspk->rec_buf + micspk->rec_buf_cnt, after_resample_buffer, nsamples << 1);
 				micspk->rec_buf_cnt += nsamples;
 			}
 		}
@@ -394,7 +456,7 @@ apr_status_t audiomicspklinux_create(apr_pool_t* pool,
 	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;
+	capture_frame_samples = FRAME_TIME * CAPTURE_AUDIO_CLOCK / 1000;
 
 	micspk->rec_dev_id = rec_dev_id;
 	micspk->ply_dev_id = ply_dev_id;
@@ -411,14 +473,14 @@ apr_status_t audiomicspklinux_create(apr_pool_t* pool,
 		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);
+		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);
 		micspk->rec_buf = (short*)apr_palloc(pool, frame_samples << 1);
 		micspk->rec_buf_cnt = 0;
-		//micspk->input_resample_state = speex_resampler_init(1, CAPTURE_AUDIO_CLOCK, AUDIO_CLOCK, RESAMPLE_QUALITY, NULL);
+		micspk->input_resample_state = speex_resampler_init(1, CAPTURE_AUDIO_CLOCK, AUDIO_CLOCK, RESAMPLE_QUALITY, NULL);
 	}
 	micspk->baudio_device_started_flag = false;
 	sem_init(micspk->audio_device_started_sem, 0, 0);