浏览代码

Z991239-5614 #comment 删除多余文件

80274480 1 年之前
父节点
当前提交
6409ed0fbd

+ 1 - 1
Module/mod_sipphone/endpoint.cpp

@@ -491,7 +491,7 @@ static void endpoint_media_update_audio(endpoint_call_t *call, media_desc_t *aud
 		rc = audio_session_start_phonemedia(call->audio, &phone_conf);
 		if (rc != 0) 
 		{
-			LogWarn(Severity_Low, Error_Debug, ERROR_MOD_SIP_AUDIO_INITFAIL, CSimpleStringA::Format("start audio session failed! rc = %d.", rc).GetData());
+			LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_AUDIO_INITFAIL, CSimpleStringA::Format("start audio session failed! rc = %d.", rc).GetData());
 			audio_session_destroy(call->audio);
 			call->audio = NULL;
 			return;

+ 0 - 360
Other/unix/libaudioframework/audiomicspk.c

@@ -1,360 +0,0 @@
-#include "precompile.h"
-#include "audiomicspk.h"
-#include "audiocontext.h"
-#include "audiolog.h"
-#include "./other/delaybuf.h"
-
-#include <portaudio.h>
-#include <assert.h>
-
-#define MAX_DELAY			60
-
-static int get_device_index(int indev, const char *key)
-{
-	int i;
-	int n = Pa_GetDeviceCount();
-	for (i = 0; i < n; ++i) {
-		const PaDeviceInfo* pInfo = Pa_GetDeviceInfo(i);
-		if (indev) {
-			if (pInfo->maxInputChannels && strstr(pInfo->name, key))
-				return i;
-		} else {
-			if (pInfo->maxOutputChannels && strstr(pInfo->name, key))
-				return i;
-		}
-	}
-	return -1;
-}
-
-static int StreamCallback(const void *input, 
-						   void *output, 
-						   unsigned long frameCount, 
-						   const PaStreamCallbackTimeInfo* timeInfo, 
-						   PaStreamCallbackFlags statusFlags, 
-						   void *userData)
-{
-	audiomicspk_t *micspk = userData;
-	apr_status_t status;
-
-	if (micspk->opt & AMS_OPT_AS_ENGINE) {
-		audiostream_t *stream;
-		//EnterCriticalSection(&micspk->engine_lock);
-		stream = micspk->engine_downstream;
-		if (stream) {
-			if (input && audiostream_get_direction(stream)&STREAM_DIR_WRITE) {
-				audioframe_t frm = {(void*)input, frameCount<<1, 0};
-				stream->vtbl->write_frame(stream, &frm);
-			}
-			if (output && audiostream_get_direction(stream)&STREAM_DIR_READ) {
-				audioframe_t frm = {output, frameCount<<1, 0};
-				status = stream->vtbl->read_frame(stream, &frm);
-				if (status != APR_SUCCESS || frm.size != frameCount<<1) {
-					memset(output, 0, frameCount<<1);
-				}
-			}
-		}
-		//LeaveCriticalSection(&micspk->engine_lock);
-	} else {
-		if (input) {
-			if (micspk->rec_buf_cnt == 0 && frameCount == micspk->frame_samples) {
-				delay_buf_put(micspk->rec_dbuf, (short*)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;
-				}
-			}
-		}
-		if (output) {
-			unsigned nsamples_req = frameCount;
-			if (micspk->ply_buf_cnt == 0 && nsamples_req == micspk->frame_samples) {
-				delay_buf_get(micspk->ply_dbuf, (short*)output);
-			} else {
-				if (micspk->ply_buf_cnt > 0) {
-					memcpy(output, micspk->ply_buf, micspk->ply_buf_cnt<<1);
-					output = (short*)output + micspk->ply_buf_cnt;
-					micspk->ply_buf_cnt = 0;
-					nsamples_req -= micspk->ply_buf_cnt;
-				}
-				while (nsamples_req > 0) {
-					if (nsamples_req >= micspk->frame_samples) {
-						delay_buf_get(micspk->ply_dbuf, (short*)output);
-						output = (short*)output + micspk->frame_samples;
-						nsamples_req -= micspk->frame_samples;
-					} else {
-						delay_buf_get(micspk->ply_dbuf, micspk->ply_buf);
-						micspk->ply_buf_cnt = micspk->frame_samples;
-						memcpy(output, micspk->ply_buf, nsamples_req<<1);
-						output = (short*)output + nsamples_req;
-						memmove(micspk->ply_buf, micspk->ply_buf+nsamples_req, (micspk->frame_samples-nsamples_req)<<1);
-						nsamples_req = 0;
-					}
-				}
-			}
-		}
-	}
-
-	return paContinue;
-}
-
-static apr_status_t read_frame(void *self, audioframe_t *frame)
-{
-	audiomicspk_t *micspk = CONTAINING_RECORD(self, audiomicspk_t, base);
-	
-	frame->size = 2*micspk->frame_samples;
-	frame->dtmf = 0;
-
-	delay_buf_get(micspk->rec_dbuf, (short*)frame->buffer);
-
-	return APR_SUCCESS;	
-}
-
-static apr_status_t write_frame(void *self, const audioframe_t *frame)
-{
-	audiomicspk_t *micspk = CONTAINING_RECORD(self, audiomicspk_t, base);
-
-	assert(micspk->frame_samples*2 == frame->size);
-
-	delay_buf_put(micspk->ply_dbuf, (short*)frame->buffer);
-
-	return APR_SUCCESS;
-}
-
-static audiostream_vtbl_t g_stream_vtbl = {
-	&read_frame,
-	&write_frame,
-};
-
-apr_status_t audiomicspk_create(apr_pool_t *pool,
-								audioengine_t *engine, 
-								int opt, 
-								int clock,
-								const char *rec_dev_key,
-								const char *ply_dev_key,
-								audiomicspk_t **p_micspk)
-{
-	int rec_dev_id = -1; 
-	int ply_dev_id = -1;
-	audiomicspk_t *micspk;
-	PaStreamParameters outParam;
-	PaStreamParameters inParam;
-	PaStream *pa_stream;
-	unsigned long frame_samples;
-	PaError paError;
-
-	if (opt == 0) {
-		audio_log_v(AUDIO_LOG_LEVEL_ERROR,"audiomicspk create error, opt cannot be zero");
-		return APR_BADARG;
-	}
-
-	frame_samples = FRAME_TIME * clock / 1000;
-
-	if (opt & AMS_OPT_PLAY) {
-		if (ply_dev_key) {
-			int id = get_device_index(0, ply_dev_key);
-			if (id == -1) {
-				audio_log_v(AUDIO_LOG_LEVEL_ERROR,"invalid play dev name!");
-				return APR_BADARG;
-			}
-			ply_dev_id = id;
-		}
-	}
-	if (opt & AMS_OPT_RECORD) {
-		if (rec_dev_key) {
-			int id = get_device_index(1, rec_dev_key);
-			if (id == -1) {
-				audio_log_v(AUDIO_LOG_LEVEL_ERROR,"invalid record dev name!");
-				return APR_BADARG;
-			}
-			rec_dev_id = id;
-		}
-	}
-
-	if (opt & AMS_OPT_PLAY) {
-		const PaDeviceInfo *info;
-		if (ply_dev_id == -1) {
-			ply_dev_id = Pa_GetDefaultOutputDevice();
-			if (ply_dev_id == paNoDevice) {
-				audio_log_v(AUDIO_LOG_LEVEL_ERROR,"audiomicspk create error, cannot find output device");
-				return -1;
-			}
-		}
-		info = Pa_GetDeviceInfo(ply_dev_id);
-		outParam.device = ply_dev_id;
-		outParam.channelCount = 1;
-		outParam.sampleFormat = paInt16;
-		outParam.suggestedLatency = info->defaultLowOutputLatency;
-		outParam.hostApiSpecificStreamInfo = NULL;
-		if (Pa_IsFormatSupported(NULL, &outParam, clock) != paNoError) {
-			audio_log_v(AUDIO_LOG_LEVEL_ERROR,"audiomicspk create error, cannot open audio output device");
-			return -1;
-		}
-		audio_log_v(AUDIO_LOG_LEVEL_ERROR,"audio out suggestedLatency:%f, in:%f", info->defaultLowOutputLatency, info->defaultLowInputLatency);
-	} 
-	if (opt & AMS_OPT_RECORD) {
-		const PaDeviceInfo *info;
-		if (rec_dev_id == -1) {
-			rec_dev_id = Pa_GetDefaultInputDevice();
-			if (rec_dev_id == paNoDevice) {
-				audio_log_v(AUDIO_LOG_LEVEL_ERROR,"audiomicspk create error, cannot find input device");
-				return -1;
-			}
-		}
-		info = Pa_GetDeviceInfo(rec_dev_id);
-		inParam.device = rec_dev_id;
-		inParam.channelCount = 1;
-		inParam.sampleFormat = paInt16;
-		inParam.suggestedLatency = info->defaultLowInputLatency;
-		inParam.hostApiSpecificStreamInfo = NULL;
-		if (Pa_IsFormatSupported(&inParam, NULL, clock) != paNoError) {
-			audio_log_v(AUDIO_LOG_LEVEL_ERROR,"audiomicspk create error, cannot open audio input device");
-			return -1;
-		}
-		audio_log_v(AUDIO_LOG_LEVEL_ERROR,"audio in suggestedLatency:%f, out:%f", info->defaultLowInputLatency, info->defaultLowOutputLatency);;
-	}
-
-	micspk = apr_palloc(pool, sizeof(audiomicspk_t));
-	memset(micspk, 0, sizeof(audiomicspk_t));
-
-	paError = Pa_OpenStream(&pa_stream, 
-		(opt & AMS_OPT_RECORD) ? &inParam : NULL, 
-		(opt & AMS_OPT_PLAY) ? &outParam : NULL, 
-		clock, frame_samples, 
-		paClipOff, 
-		&StreamCallback,
-		micspk);
-	if (paError != 0) {
-		audio_log_v(AUDIO_LOG_LEVEL_ERROR,"audiomicspk create error, Pa_OpenStream function failed in dir! ");
-		return APR_EGENERAL;
-	}
-
-	audiostream_init(engine, &g_stream_vtbl, &micspk->base);
-	micspk->base.direction = 0;
-	if (opt & AMS_OPT_PLAY) {
-		delay_buf_create(clock, frame_samples, 1, MAX_DELAY, 0, (delay_buf**)&micspk->ply_dbuf);
-		micspk->base.direction |= STREAM_DIR_WRITE;
-		micspk->ply_buf = (short*)apr_palloc(pool, frame_samples<<1);
-		micspk->ply_buf_cnt = 0;
-	}
-	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;
-	}
-	if (opt & AMS_OPT_AS_ENGINE)
-		//InitializeCriticalSection(&micspk->engine_lock);
-	micspk->clock = clock;
-	micspk->opt = opt;
-	micspk->frame_samples = frame_samples;
-	micspk->rec_dev_id = rec_dev_id;
-	micspk->ply_dev_id = ply_dev_id;
-	micspk->stream = pa_stream;
-	paError = Pa_StartStream(pa_stream);
-	if (paError != 0) {
-		audio_log_v(AUDIO_LOG_LEVEL_ERROR,"audiomicspk create error, Pa_StartStream function failed in dir! ");
-		Pa_CloseStream(pa_stream);
-		micspk->stream = NULL;
-		audiomicspk_destroy(micspk);
-		return APR_EGENERAL;
-	}
-
-	*p_micspk = micspk;
-
-	return APR_SUCCESS;
-}
-
-void audiomicspk_destroy(audiomicspk_t *micspk)
-{
-	if (micspk->stream) {
-		Pa_AbortStream(micspk->stream);
-		Pa_CloseStream(micspk->stream);
-	}
-	if (micspk->ply_dbuf)
-		delay_buf_destroy(micspk->ply_dbuf);
-	if (micspk->rec_dbuf)
-		delay_buf_destroy(micspk->rec_dbuf);
-	if (micspk->opt & AMS_OPT_AS_ENGINE) {
-		//DeleteCriticalSection(&micspk->engine_lock);
-	}
-		
-}
-
-apr_status_t audiomicspk_connect_pipeline(audiomicspk_t *micspk, int direction, ...)
-{
-	va_list arg;
-	audiostream_t *p, *q;
-
-	if (micspk->opt & AMS_OPT_AS_ENGINE) {
-		//EnterCriticalSection(&micspk->engine_lock);
-	}
-
-	va_start(arg, direction);
-	for (q = NULL, p = va_arg(arg, audiostream_t*); p; q = p, p = va_arg(arg, audiostream_t*)) {
-		if (q == NULL) {
-			micspk->engine_downstream = p;
-		} else {
-			q->downstream = p;
-		}
-		p->direction = direction;
-		p->upstream = q;
-	}
-	if (q)
-		q->downstream = NULL;
-	va_end(arg);
-
-	if (micspk->opt & AMS_OPT_AS_ENGINE) {
-		//LeaveCriticalSection(&micspk->engine_lock);
-	}
-
-	return APR_SUCCESS;
-}
-
-void audiomicspk_disconnect_pipeline(audiomicspk_t *micspk, audiostream_t *stream)
-{
-	audiostream_t *p;
-
-	if (micspk->opt & AMS_OPT_AS_ENGINE) {
-		//EnterCriticalSection(&micspk->engine_lock);
-	}
-
-
-	micspk->engine_downstream = NULL;
-
-	p = stream;
-	while (p) {
-		audiostream_t *next = p->downstream;
-		p->direction = STREAM_DIR_NONE;
-		p->upstream = NULL;
-		p->downstream = NULL;
-		p = next;
-	}
-
-	if (micspk->opt & AMS_OPT_AS_ENGINE) {
-		//LeaveCriticalSection(&micspk->engine_lock);
-	}
-}
-
-
-void audiomicspk_lock(audiomicspk_t *micspk)
-{
-	if (micspk->opt & AMS_OPT_AS_ENGINE) {
-		//EnterCriticalSection(&micspk->engine_lock);
-	}
-}
-
-void audiomicspk_unlock(audiomicspk_t *micspk)
-{
-	if (micspk->opt & AMS_OPT_AS_ENGINE) {
-		//LeaveCriticalSection(&micspk->engine_lock);
-	}
-}

+ 0 - 60
Other/unix/libaudioframework/audiomicspk.h

@@ -1,60 +0,0 @@
-#ifndef __AUDIOMICSPK_H__
-#define __AUDIOMICSPK_H__
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define AMS_OPT_RECORD		0x01
-#define AMS_OPT_PLAY		0x02
-#define AMS_OPT_RECPLAY		0x03
-#define AMS_OPT_AS_STREAM	0x00
-#define AMS_OPT_AS_ENGINE	0x04
-
-#include "audiostream.h"
-
-typedef struct audiomicspk_t audiomicspk_t;
-
-struct audiomicspk_t
-{
-	audiostream_t base;
-	int clock; // only support 8k, 16k
-	int rec_dev_id;
-	int ply_dev_id;
-	int opt;
-	int frame_samples;
-	void *stream;
-	void *ply_dbuf;
-	void *rec_dbuf;
-	short *rec_buf;
-	unsigned rec_buf_cnt;
-	short *ply_buf;
-	unsigned ply_buf_cnt;
-	audiostream_t *engine_downstream;
-	//CRITICAL_SECTION engine_lock;
-};
-
-// note: only PCM16
-
-apr_status_t audiomicspk_create(apr_pool_t *pool,
-								audioengine_t *engine, 
-								int opt, 
-								int clock,
-								const char *rec_dev_key,
-								const char *ply_dev_key,
-								audiomicspk_t **p_micspk);
-void audiomicspk_destroy(audiomicspk_t *micspk);
-
-// act as engine
-apr_status_t audiomicspk_connect_pipeline(audiomicspk_t *micspk, int direction, ...);
-void audiomicspk_disconnect_pipeline(audiomicspk_t *micspk, audiostream_t *stream);
-void audiomicspk_lock(audiomicspk_t *micspk);
-void audiomicspk_unlock(audiomicspk_t *micspk);
-
-#ifdef __cplusplus
-} // extern "C" {
-#endif
-
-#endif //__AUDIOMICSPK_H__

+ 0 - 1015
Other/unix/libaudioframework/audiomicspk2.c

@@ -1,1015 +0,0 @@
-#include "precompile.h"
-#include "audiomicspk.h"
-#include "audiomicspk2.h"
-#include "audiocontext.h"
-
-#include <assert.h>
-
-#include "audiolog.h"
-#include "./other/delaybuf.h"
-
-#include <dmo.h>
-#include <Mmsystem.h>
-#include <objbase.h>
-#include <mediaobj.h>
-#include <uuids.h>
-#include <propidl.h>
-#include <wmcodecdsp.h>
-
-#include <audioclient.h>
-#include <MMDeviceApi.h>
-#include <AudioEngineEndPoint.h>
-#include <DeviceTopology.h>
-#include <EndpointVolume.h>
-#include <functiondiscoverykeys.h>
-
-#include <portaudio.h>
-
-#include <speex/speex_resampler.h>
-
-#include <math.h>
-#define CLOCK_PERIOD	20
-#define MAX_STR_LEN 512
-#define AUDIO_CLOCK	8000
-#define CAPTURE_AUDIO_CLOCK	16000
-#define MAX_DELAY	100
-#define MS_REF_TICK	10000
-#define RESAMPLE_QUALITY	6
-
-
-#ifndef M_PI
-#define M_PI              (3.14159265)
-#endif
-#define TWOPI             (M_PI * 2.0)
-
-// play use portaudio
-
-typedef struct tagAUDIO_DEVICE_INFO
-{
-	char szDeviceName[MAX_STR_LEN];
-	char szDeviceID[MAX_STR_LEN];
-} AUDIO_DEVICE_INFO, *PAUDIO_DEVICE_INFO;
-
-static HRESULT GetDeviceNum(EDataFlow eDataFlow, UINT *uDevCount)
-{
-	IMMDeviceEnumerator *pEnumerator = NULL;
-	IMMDeviceCollection *pEndpoints = NULL;
-	HRESULT hr;
-
-	hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&pEnumerator);
-	if (FAILED(hr))
-		goto on_error;
-	hr = pEnumerator->lpVtbl->EnumAudioEndpoints(pEnumerator, eDataFlow, DEVICE_STATE_ACTIVE, (void**)&pEndpoints);
-	if (FAILED(hr))
-		goto on_error;
-	hr = pEndpoints->lpVtbl->GetCount(pEndpoints, uDevCount);
-	if (FAILED(hr))
-		goto on_error;
-
-on_error:
-	if (pEndpoints)
-		pEndpoints->lpVtbl->Release(pEndpoints);
-	if (pEnumerator)
-		pEnumerator->lpVtbl->Release(pEnumerator);
-	return hr;
-}
-
-static HRESULT EnumDevice(EDataFlow eDataFlow, UINT uNumElements, AUDIO_DEVICE_INFO *pDevicInfo)
-{
-	IMMDeviceEnumerator *pEnumerator = NULL;
-	IMMDeviceCollection *pEndpoints = NULL;
-	HRESULT hr;
-	UINT uCount;
-	UINT uIdx;
-
-	hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&pEnumerator);
-	if (FAILED(hr))
-		goto on_error;
-	hr = pEnumerator->lpVtbl->EnumAudioEndpoints(pEnumerator, eDataFlow, DEVICE_STATE_ACTIVE, (void**)&pEndpoints);
-	if (FAILED(hr))
-		goto on_error;
-	hr = pEndpoints->lpVtbl->GetCount(pEndpoints, &uCount);
-	if (FAILED(hr))
-		goto on_error;
-
-	ZeroMemory(pDevicInfo, sizeof(AUDIO_DEVICE_INFO)*uNumElements);
-
-	for (uIdx = 0; uIdx < uCount && uIdx < uNumElements; ++uIdx) {
-		IMMDevice *pDevice = NULL;
-		IPropertyStore *pPS = NULL;
-		WCHAR* pszDeviceId = NULL;
-		PROPVARIANT value;
-		PropVariantInit(&value);
-		pEndpoints->lpVtbl->Item(pEndpoints, uIdx, &pDevice);
-		pDevice->lpVtbl->GetId(pDevice, &pszDeviceId);
-		pDevice->lpVtbl->OpenPropertyStore(pDevice, STGM_READ, &pPS);
-		pPS->lpVtbl->GetValue(pPS, &PKEY_Device_FriendlyName, &value);
-		WideCharToMultiByte(CP_ACP, 0, pszDeviceId, -1, pDevicInfo[uIdx].szDeviceID, MAX_STR_LEN-1, NULL, NULL);
-		WideCharToMultiByte(CP_ACP, 0, value.pwszVal, -1, pDevicInfo[uIdx].szDeviceName, MAX_STR_LEN-1, NULL, NULL);
-		PropVariantClear(&value);
-		CoTaskMemFree(pszDeviceId);
-		pPS->lpVtbl->Release(pPS);
-		pDevice->lpVtbl->Release(pDevice);
-	}
-
-on_error:
-	if (pEndpoints)
-		pEndpoints->lpVtbl->Release(pEndpoints);
-	if (pEnumerator)
-		pEnumerator->lpVtbl->Release(pEnumerator);
-	return hr;
-}
-
-static HRESULT DeviceBindTo(
-	EDataFlow eDataFlow,    // eCapture/eRender
-	INT iDevIdx,        // Device Index. -1 - default device. 
-	IAudioClient **ppAudioClient,    // pointer pointer to IAudioClient interface
-	IAudioEndpointVolume **ppEndpointVolume
-	)
-{
-	IMMDeviceEnumerator *pEnumerator = NULL;
-	IMMDeviceCollection *pEndpoints = NULL;
-	IMMDevice *pDevice = NULL;
-	HRESULT hr;
-
-	hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&pEnumerator);
-	if (FAILED(hr))
-		goto on_error;
-
-	if (iDevIdx < 0) {
-		hr = pEnumerator->lpVtbl->GetDefaultAudioEndpoint(pEnumerator, eDataFlow, eConsole, &pDevice);
-		if (FAILED(hr))
-			goto on_error;
-	} else {
-		hr = pEnumerator->lpVtbl->EnumAudioEndpoints(pEnumerator, eDataFlow, DEVICE_STATE_ACTIVE, (void**)&pEndpoints);
-		if (FAILED(hr))
-			goto on_error;
-		hr = pEndpoints->lpVtbl->Item(pEndpoints, iDevIdx, &pDevice);
-		if (FAILED(hr))
-			goto on_error;
-	}
-
-	hr = pDevice->lpVtbl->Activate(pDevice, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void**)ppAudioClient);
-	if (FAILED(hr))
-		goto on_error;
-
-	if (ppEndpointVolume) {
-		hr = pDevice->lpVtbl->Activate(pDevice, &IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, NULL, (void**)ppEndpointVolume);
-		if (FAILED(hr)) {
-			if (*ppAudioClient) {
-				(*ppAudioClient)->lpVtbl->Release(*ppAudioClient);
-				*ppAudioClient = NULL;
-			}
-			goto on_error;
-		}
-	}
-
-on_error:
-
-	if (pDevice) {
-		pDevice->lpVtbl->Release(pDevice);
-	}
-	if (pEndpoints) {
-		pEndpoints->lpVtbl->Release(pEndpoints);
-	}
-	if (pEnumerator) {
-		pEnumerator->lpVtbl->Release(pEnumerator);
-	}
-
-	return hr;
-}
-
-static int get_device_index(int indev, const char *key)
-{
-	EDataFlow df = indev ? eCapture : eRender;
-	UINT i;
-	UINT n;
-	AUDIO_DEVICE_INFO *pInfo = NULL;
-	GetDeviceNum(df, &n);
-	pInfo = malloc(sizeof(AUDIO_DEVICE_INFO) * n);
-	EnumDevice(df, n, pInfo);
-	for (i = 0; i < n; ++i) {
-		if (strstr(pInfo[i].szDeviceName, key)) {
-			free(pInfo);
-			return i;
-		}
-	}
-	free(pInfo);
-	return -1;
-}
-
-static int get_device_index_poartaudio(int indev, const char *key)
-{
-	int i;
-	int n = Pa_GetDeviceCount();
-	for (i = 0; i < n; ++i) {
-		const PaDeviceInfo* pInfo = Pa_GetDeviceInfo(i);
-		if (indev) {
-			if (pInfo->maxInputChannels && strstr(pInfo->name, key))
-				return i;
-		} else {
-			if (pInfo->maxOutputChannels && strstr(pInfo->name, key))
-				return i;
-		}
-	}
-	return -1;
-}
-
-static HRESULT CreateVoiceCaptureDMO(
-	int spk_dev_id,
-	int rec_dev_id,
-	BOOL bNS,
-	BOOL bAGC, 
-	IMediaObject *ppDMO)
-{
-	HRESULT hr = S_OK;
-	return hr;
-}
-
-typedef struct IMediaBufferImpl {
-	struct IMediaBufferVtbl *lpVtbl;
-	struct IMediaBufferVtbl vtbl;
-	BYTE *m_pData;
-	ULONG m_ulSize;
-	ULONG m_ulData;
-	ULONG m_cRef;
-}IMediaBufferImpl;
-
-static HRESULT STDMETHODCALLTYPE QueryInterface(IMediaBuffer * This, REFIID riid, void** ppvObject);
-static ULONG STDMETHODCALLTYPE AddRef(IMediaBuffer * This);
-static ULONG STDMETHODCALLTYPE Release(IMediaBuffer * This);
-static HRESULT STDMETHODCALLTYPE SetLength(IMediaBuffer * This, DWORD ulLength);
-static HRESULT STDMETHODCALLTYPE GetMaxLength(IMediaBuffer * This, DWORD *pcbMaxLength);
-static HRESULT STDMETHODCALLTYPE GetBufferAndLength(IMediaBuffer * This, BYTE **ppBuffer, DWORD *pcbLength);
-
-static void destroy_media_buffer(IMediaBufferImpl *pImpl)
-{
-	free(pImpl->m_pData);
-	free(pImpl);
-}
-
-static IMediaBuffer *create_media_buffer(ULONG len)
-{
-	IMediaBufferImpl *pImpl = (IMediaBufferImpl*)malloc(sizeof(IMediaBufferImpl));
-	if (pImpl) {
-		pImpl->lpVtbl = &pImpl->vtbl;
-		pImpl->lpVtbl->QueryInterface = &QueryInterface;
-		pImpl->lpVtbl->AddRef = &AddRef;
-		pImpl->lpVtbl->Release = &Release;
-		pImpl->lpVtbl->SetLength = &SetLength;
-		pImpl->lpVtbl->GetMaxLength = &GetMaxLength;
-		pImpl->lpVtbl->GetBufferAndLength = &GetBufferAndLength;
-		pImpl->m_pData = (BYTE*)malloc(len);
-		pImpl->m_ulData = 0;
-		pImpl->m_ulSize = len;
-		pImpl->m_cRef = 1;
-	}
-	return (IMediaBuffer*)pImpl;
-}
-
-static HRESULT STDMETHODCALLTYPE QueryInterface(IMediaBuffer * This, REFIID riid, void** ppvObject)
-{
-	if (This == NULL || riid == NULL || ppvObject == NULL || *ppvObject == NULL)
-		return E_POINTER;
-	if (IsEqualIID(riid, &IID_IUnknown)) {
-		*ppvObject = (void*)This;
-		return S_OK;
-	} else if (IsEqualIID(riid, &IID_IMediaBuffer)) {
-		*ppvObject = (void*)This;
-		return S_OK;
-	}
-	return E_NOTIMPL;
-}
-static ULONG STDMETHODCALLTYPE AddRef(IMediaBuffer * This)
-{
-	IMediaBufferImpl *pImpl = (IMediaBufferImpl *)This;
-	return InterlockedIncrement(&pImpl->m_cRef);
-}
-static ULONG STDMETHODCALLTYPE Release(IMediaBuffer * This)
-{
-	IMediaBufferImpl *pImpl = (IMediaBufferImpl *)This;
-	ULONG lRet = InterlockedDecrement(&pImpl->m_cRef);
-	if (lRet == 0) {
-		destroy_media_buffer(pImpl);
-	}
-	return lRet;
-}
-static HRESULT STDMETHODCALLTYPE SetLength(IMediaBuffer * This, DWORD ulLength) 
-{
-	IMediaBufferImpl *pImpl = (IMediaBufferImpl *)This;
-	pImpl->m_ulData = ulLength; 
-	return NOERROR;
-}
-static HRESULT STDMETHODCALLTYPE GetMaxLength(IMediaBuffer * This, DWORD *pcbMaxLength) 
-{
-	IMediaBufferImpl *pImpl = (IMediaBufferImpl *)This;
-	*pcbMaxLength = pImpl->m_ulSize; 
-	return NOERROR;
-}
-static HRESULT STDMETHODCALLTYPE GetBufferAndLength(IMediaBuffer * This, BYTE **ppBuffer, DWORD *pcbLength) 
-{
-	IMediaBufferImpl *pImpl = (IMediaBufferImpl *)This;
-	if (ppBuffer) *ppBuffer = pImpl->m_pData;
-	if (pcbLength) *pcbLength = pImpl->m_ulData;
-	return NOERROR;
-}
-
-
-
-static int load_data(audiomicspk2_t *micspk, BYTE *pData, UINT32 nCount, UINT32 *pReturnedCount)
-{
-	UINT32 frame_samples = AUDIO_CLOCK * FRAME_TIME / 1000;
-	UINT32 frame_offset = 0;
-	while (nCount >= frame_samples) {
-		delay_buf_get(micspk->ply_dbuf, (SHORT*)(pData+frame_offset*2));
-		frame_offset += frame_samples;
-		nCount -= frame_samples;
-	}
-	*pReturnedCount = frame_offset;
-	return 0;
-}
-
-static int save_data(audiomicspk2_t *micspk, IMediaBuffer *pBuffer)
-{
-	UINT32 frame_samples = AUDIO_CLOCK * FRAME_TIME / 1000;
-	UINT32 capture_frame_samples = CAPTURE_AUDIO_CLOCK * FRAME_TIME / 1000;
-	UINT32 frame_offset = 0;
-	BYTE *pData;
-	DWORD dwLength;
-	pBuffer->lpVtbl->GetBufferAndLength(pBuffer, &pData, &dwLength);
-	//AUDIO_LOG_INFO("micspk2 rec samples:%d", dwLength>>1);
-	while (dwLength >= capture_frame_samples*2) {
-		spx_uint32_t in_len = capture_frame_samples;
-		spx_uint32_t out_len = frame_samples;
-		SHORT *pFrameData = (SHORT*)(pData+frame_offset*2);
-		SHORT outData[160];
-		speex_resampler_process_int((SpeexResamplerState*)micspk->input_resample_state, 0, 
-			pFrameData, &in_len, outData, &out_len);
-		delay_buf_put((delay_buf*)micspk->rec_dbuf, outData);
-		frame_offset += capture_frame_samples;
-		dwLength -= capture_frame_samples*2;
-	}
-	return 0;
-}
-
-typedef struct paTestData
-{
-	int    sleepFor;
-	double phase;
-}
-paTestData;
-static int StreamCallback(const void *input, 
-	void *output, 
-	unsigned long frameCount, 
-	const PaStreamCallbackTimeInfo* timeInfo, 
-	PaStreamCallbackFlags statusFlags, 
-	void *userData)
-{
-	audiomicspk2_t *micspk = (audiomicspk2_t*)userData;
-	apr_status_t status;
-				//double phase = 0;
-				//int i=0;
-	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/*&&strlen(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);
-		}
-	}
-	//paTestData *data = (paTestData*)userData;
-	//float *out = (float*)output;
-	//unsigned long i;
-	//int finished = 0;
-	//double phaseInc = 0.02;
-	//double phase = data->phase;
-
-	//(void) input; /* Prevent unused argument warning. */
-
-	//for( i=0; i<frameCount; i++ )
-	//{
-	//	phase += phaseInc;
-	//	if( phase > TWOPI ) phase -= TWOPI;
-	//	/* This is not a very efficient way to calc sines. */
-	//	*out++ = (float) sin( phase )*2; /* mono */
-	//}
-	//write_log("output=%d",(spx_int16_t*)output);
-	//if( data->sleepFor > 0 )
-	//{
-	//	Pa_Sleep(1000 );
-	//}
-
-	//data->phase = phase;
-	return paContinue;
-}
-
-static int initialize_spk(audiomicspk2_t *micspk)
-{
-	UINT32 capture_frame_samples = CAPTURE_AUDIO_CLOCK * FRAME_TIME / 1000;
-	UINT32 frame_samples = AUDIO_CLOCK * FRAME_TIME / 1000;
-	const PaDeviceInfo *info;
-	PaStreamParameters outParam;
-	PaError paError;
-	int ply_dev_id = micspk->ply_dev_id_portaudio;
-
-	if (ply_dev_id == -1) {
-		ply_dev_id = Pa_GetDefaultOutputDevice();
-		if (ply_dev_id == paNoDevice) {
-			audio_log_v(AUDIO_LOG_LEVEL_ERROR,"audiomicspk create error, cannot find output device");
-			return APR_EGENERAL;
-		}
-	}
-	info = Pa_GetDeviceInfo(ply_dev_id);
-	outParam.device = ply_dev_id;
-	outParam.channelCount = 1;
-	outParam.sampleFormat = paInt16;
-	outParam.suggestedLatency = info->defaultLowOutputLatency;
-	outParam.hostApiSpecificStreamInfo = NULL;
-	if (Pa_IsFormatSupported(NULL, &outParam, AUDIO_CLOCK) != paNoError) {
-		audio_log_v(AUDIO_LOG_LEVEL_ERROR,"audiomicspk create error, cannot open audio output device");
-		return APR_EGENERAL;
-	}
-
-	paError = Pa_OpenStream(&micspk->ply_stream, NULL, &outParam, CAPTURE_AUDIO_CLOCK, capture_frame_samples, paClipOff, &StreamCallback, micspk);
-	if (paError != 0) {
-		audio_log_v(AUDIO_LOG_LEVEL_ERROR,"audiomicspk create error, Pa_OpenStream function failed in dir! ");
-		return APR_EGENERAL;
-	}
-	paError = Pa_StartStream(micspk->ply_stream);
-	if (paError != 0) {
-		audio_log_v(AUDIO_LOG_LEVEL_ERROR,"Pa_StartStream function failed in dir! ");
-		Pa_CloseStream(micspk->ply_stream);
-		micspk->ply_stream = NULL;
-		return APR_EGENERAL;
-	}
-
-	return 0;
-}
-
-static int initialize_rec(audiomicspk2_t *micspk)
-{
-	IMediaObject *pDMO = NULL;
-	IPropertyStore *pPS = NULL;
-	HRESULT hr;
-	UINT32 capture_frame_samples = CAPTURE_AUDIO_CLOCK * FRAME_TIME / 1000;
-	UINT32 frame_samples = AUDIO_CLOCK * FRAME_TIME / 1000;
-
-	hr = CoCreateInstance(&CLSID_CWMAudioAEC, NULL, CLSCTX_INPROC_SERVER, &IID_IMediaObject, (void**)&pDMO);
-
-	if (SUCCEEDED(hr)) {
-		hr = pDMO->lpVtbl->QueryInterface(pDMO, &IID_IPropertyStore, (void**)&pPS);
-	}
-
-	if (FAILED(hr)) {
-		if (pDMO) {
-			pDMO->lpVtbl->Release(pDMO);
-		}
-		return -1;
-	}
-
-	// sys mode
-	{
-		PROPVARIANT pvSysMode;
-		PropVariantInit(&pvSysMode);
-		pvSysMode.vt = VT_I4;
-		//pvSysMode.lVal = micspk->opt & AMS2_OPT_AEC ? SINGLE_CHANNEL_AEC : SINGLE_CHANNEL_NSAGC;
-		pvSysMode.lVal = micspk->opt & AMS2_OPT_AEC ? OPTIBEAM_ARRAY_AND_AEC : SINGLE_CHANNEL_NSAGC;
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_SYSTEM_MODE, &pvSysMode);
-		PropVariantClear(&pvSysMode);
-	}
-
-#if 1
-	// feature mode
-	{
-		PROPVARIANT pvFeatMode;
-		PropVariantInit(&pvFeatMode);
-		pvFeatMode.vt = VT_BOOL;
-		pvFeatMode.boolVal = VARIANT_TRUE;		
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_FEATURE_MODE, &pvFeatMode);
-		PropVariantClear(&pvFeatMode);
-	}
-#endif
-
-	// set device index
-	{
-		PROPVARIANT pvDeviceId;
-		PropVariantInit(&pvDeviceId);
-		pvDeviceId.vt = VT_I4;
-		pvDeviceId.lVal = (unsigned long)(micspk->ply_dev_id<<16) + (unsigned long)(0x0000ffff & micspk->rec_dev_id);
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_DEVICE_INDEXES, &pvDeviceId);
-		PropVariantClear(&pvDeviceId);
-	}
-
-	// echo length
-#if 0
-	if (micspk->opt & AMS2_OPT_AEC)
-	{
-		PROPVARIANT pvEchoLength;
-		PropVariantInit(&pvEchoLength);
-		pvEchoLength.vt = VT_I4;
-		pvEchoLength.lVal = 128;
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_FEATR_ECHO_LENGTH, &pvEchoLength);
-		PropVariantClear(&pvEchoLength);
-	}
-#endif
-
-	// echo supress times
-#if 1
-	if (micspk->opt & AMS2_OPT_AEC)
-	{
-		PROPVARIANT pvAESTimes;
-		PropVariantInit(&pvAESTimes);
-		pvAESTimes.vt = VT_I4;
-		pvAESTimes.lVal = 1; // 0, 1, 2
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_FEATR_AES, &pvAESTimes);
-		PropVariantClear(&pvAESTimes);
-	}
-#endif
-
-	// center clip
-#if 0
-	if (micspk->opt & AMS2_OPT_AEC) 
-	{
-		PROPVARIANT pvCenterClip;
-		PropVariantInit(&pvCenterClip);
-		pvCenterClip.vt = VT_BOOL;
-		pvCenterClip.boolVal = VARIANT_TRUE;		
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_FEATR_CENTER_CLIP, &pvCenterClip);
-		PropVariantClear(&pvCenterClip);
-	}
-#endif
-
-#if 1
-
-	// noise fill
-	if (micspk->opt & AMS2_OPT_AEC)
-	{
-		PROPVARIANT pvNSFill;
-		PropVariantInit(&pvNSFill);
-		pvNSFill.vt = VT_BOOL;
-		pvNSFill.boolVal = VARIANT_TRUE;		
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_FEATR_NOISE_FILL, &pvNSFill);
-		PropVariantClear(&pvNSFill);
-	}
-
-	// retreive TS
-	if (micspk->opt & AMS2_OPT_AEC) 
-	{
-		PROPVARIANT pvTS;
-		PropVariantInit(&pvTS);
-		pvTS.vt = VT_BOOL;
-		pvTS.boolVal = VARIANT_TRUE;		
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_RETRIEVE_TS_STATS, &pvTS);
-		PropVariantClear(&pvTS);
-	}
-#endif
-
-	// noise suppression
-	{
-		PROPVARIANT pvNoiseSup;
-		PropVariantInit(&pvNoiseSup);
-		pvNoiseSup.vt = VT_I4;
-		pvNoiseSup.lVal = micspk->opt & AMS2_OPT_NS;
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_FEATR_NS, &pvNoiseSup);
-		PropVariantClear(&pvNoiseSup);
-	}
-
-#if 1
-	// Turn on/off AGC
-	{
-		PROPVARIANT pvAGC;
-		PropVariantInit(&pvAGC);
-		pvAGC.vt = VT_BOOL;
-		pvAGC.boolVal = micspk->opt & AMS2_OPT_AGC ? VARIANT_TRUE : VARIANT_FALSE;
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_FEATR_AGC, &pvAGC);
-		PropVariantClear(&pvAGC);
-	}
-#endif
-
-	// set output format
-	{
-		DMO_MEDIA_TYPE mt = {0};
-		WAVEFORMATEX wfxOut = {WAVE_FORMAT_PCM, 1, CAPTURE_AUDIO_CLOCK, CAPTURE_AUDIO_CLOCK<<1, 2, 16, 0};
-		MoInitMediaType(&mt, sizeof(WAVEFORMATEX));
-		mt.majortype = MEDIATYPE_Audio;
-		mt.subtype = MEDIASUBTYPE_PCM;
-		mt.lSampleSize = 0;
-		//mt.lSampleSize = 2;
-		mt.bFixedSizeSamples = TRUE;
-		mt.bTemporalCompression = FALSE;
-		mt.formattype = FORMAT_WaveFormatEx;
-		memcpy(mt.pbFormat, &wfxOut, sizeof(WAVEFORMATEX));
-		pDMO->lpVtbl->SetOutputType(pDMO, 0, &mt, 0); 
-		micspk->rec_buf_size = wfxOut.nSamplesPerSec * wfxOut.wBitsPerSample / 8;
-		MoFreeMediaType(&mt);
-	}
-
-	pDMO->lpVtbl->AllocateStreamingResources(pDMO);
-
-	pPS->lpVtbl->Release(pPS);
-
-	micspk->rec_dmo = pDMO;
-
-	return 0;
-}
-
-static void dump_aec_config(audiomicspk2_t *micspk)
-{
-	IMediaObject *pDMO = (IMediaObject*)micspk->rec_dmo;
-	IPropertyStore *pPS = NULL;
-	HRESULT hr;
-	int echo_length = 0;
-	int frame_size = 0;
-	int aes_times = 0;
-
-	hr = pDMO->lpVtbl->QueryInterface(pDMO, &IID_IPropertyStore, (void**)&pPS);
-
-	//if (micspk->opt & AMS2_OPT_AEC)
-	{
-		PROPVARIANT pvEchoLength;
-		PropVariantInit(&pvEchoLength);
-		pvEchoLength.vt = VT_I4;
-		//pvEchoLength.lVal = 128;
-		pPS->lpVtbl->GetValue(pPS, &MFPKEY_WMAAECMA_FEATR_ECHO_LENGTH, &pvEchoLength);
-		echo_length = pvEchoLength.lVal;
-		PropVariantClear(&pvEchoLength);
-	}
-
-	//if (micspk->opt & AMS2_OPT_AEC)
-	{
-		PROPVARIANT pvFrameSize;
-		PropVariantInit(&pvFrameSize);
-		pvFrameSize.vt = VT_I4;
-		//pvEchoLength.lVal = 128;
-		pPS->lpVtbl->GetValue(pPS, &MFPKEY_WMAAECMA_FEATR_FRAME_SIZE, &pvFrameSize);
-		frame_size = pvFrameSize.lVal;
-		PropVariantClear(&pvFrameSize);
-	}
-
-	//if (micspk->opt & AMS2_OPT_AEC)
-	{
-		PROPVARIANT pvAESTimes;
-		PropVariantInit(&pvAESTimes);
-		pvAESTimes.vt = VT_I4;
-		//pvAESTimes.lVal = 1; // 0, 1, 2
-		pPS->lpVtbl->GetValue(pPS, &MFPKEY_WMAAECMA_FEATR_AES, &pvAESTimes);
-		aes_times = pvAESTimes.lVal;
-		PropVariantClear(&pvAESTimes);
-	}
-
-	if (0)
-	{
-		AecQualityMetrics_Struct *pAECQuality;
-		PROPVARIANT pvAECQuality;
-		PropVariantInit(&pvAECQuality);
-		hr = pPS->lpVtbl->GetValue(pPS, &MFPKEY_WMAAECMA_QUALITY_METRICS, &pvAECQuality);
-		if (SUCCEEDED(hr)) {
-			pAECQuality = (AecQualityMetrics_Struct *)pvAECQuality.blob.pBlobData;
-			AUDIO_LOG_INFO("i64Timestamp:%lld, ConvergenceFlag:%d, MicClippedFlag:%d, MicSilenceFlag:%d,"
-				"PstvFeadbackFlag:%d, SpkClippedFlag:%d, SpkMuteFlag:%d, GlitchFlag:%d, DoubleTalkFlag:%d,"
-				"uGlitchCount:%d,uMicClipCount:%d,fDuration:%f,fTSVariance:%f,fTSDriftRate:%f"
-				"fVoiceLevel:%f,fNoiseLevel:%f,fERLE:%f,fAvgERLE:%f,dwReserved:%d",
-				pAECQuality->i64Timestamp, pAECQuality->ConvergenceFlag, pAECQuality->MicClippedFlag, 
-				pAECQuality->MicSilenceFlag, pAECQuality->PstvFeadbackFlag, pAECQuality->SpkClippedFlag, 
-				pAECQuality->SpkMuteFlag, pAECQuality->GlitchFlag, pAECQuality->DoubleTalkFlag, 
-				pAECQuality->uGlitchCount, pAECQuality->uMicClipCount, pAECQuality->fDuration, pAECQuality->fTSVariance,
-				pAECQuality->fTSDriftRate, pAECQuality->fVoiceLevel, pAECQuality->fNoiseLevel, pAECQuality->fERLE, 
-				pAECQuality->fAvgERLE, pAECQuality->dwReserved);
-			if (!pAECQuality->ConvergenceFlag) {
-				pAECQuality->ConvergenceFlag = 1;
-				pAECQuality->uMicClipCount = 4;
-				pAECQuality->fERLE = 0.009828;
-				pAECQuality->fAvgERLE = 0.172231;
-				hr = pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_QUALITY_METRICS, &pvAECQuality);
-				if (SUCCEEDED(hr)) {
-					AUDIO_LOG_INFO("set MFPKEY_WMAAECMA_QUALITY_METRICS ok!");
-				} else {
-					AUDIO_LOG_INFO("set MFPKEY_WMAAECMA_QUALITY_METRICS failed!");
-				}
-			}
-#if 0
-			if (pAECQuality->ConvergenceFlag) {
-				hr = pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_QUALITY_METRICS, &pvAECQuality);
-				if (SUCCEEDED(hr)) {
-					AUDIO_LOG_INFO("set MFPKEY_WMAAECMA_QUALITY_METRICS ok!");
-				} else {
-					AUDIO_LOG_INFO("set MFPKEY_WMAAECMA_QUALITY_METRICS failed!");
-				}
-			}
-#endif
-		}
-		PropVariantClear(&pvAECQuality);
-	}
-
-	AUDIO_LOG_INFO("echo_length:%d, frame_size:%d, aes_times:%d", echo_length, frame_size, aes_times);
-
-	if (pPS) {
-		pPS->lpVtbl->Release(pPS);
-	}
-}
-
-static void set_aec_config(audiomicspk2_t *micspk)
-{
-	IMediaObject *pDMO = (IMediaObject*)micspk->rec_dmo;
-	IPropertyStore *pPS = NULL;
-	HRESULT hr;
-	int echo_length = 0;
-	int frame_size = 0;
-
-	hr = pDMO->lpVtbl->QueryInterface(pDMO, &IID_IPropertyStore, (void**)&pPS);
-
-	// config AEC runtime state
-	{
-		AecQualityMetrics_Struct AECQuality = {0};
-		PROPVARIANT pvAECQuality;
-		PropVariantInit(&pvAECQuality);
-		pvAECQuality.vt = VT_BLOB;
-		pvAECQuality.blob.cbSize = sizeof(AECQuality);
-		pvAECQuality.blob.pBlobData = &AECQuality;
-		AECQuality.ConvergenceFlag = 1;
-		AECQuality.uMicClipCount = 371;
-		AECQuality.fDuration = 134.690002;
-		AECQuality.fTSVariance = 0.167386;
-		AECQuality.fTSDriftRate = 0.000002;
-		AECQuality.fVoiceLevel  =0.106498;
-		AECQuality.fNoiseLevel = 0.004691;
-		AECQuality.fERLE = 6.605908;
-		AECQuality.fAvgERLE = 3.306793;
-		hr  = pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_QUALITY_METRICS, &pvAECQuality);
-		PropVariantClear(&pvAECQuality);
-		if (SUCCEEDED(hr)) {
-			AUDIO_LOG_INFO("set MFPKEY_WMAAECMA_QUALITY_METRICS ok!");
-		}
-	}
-
-	if (pPS) {
-		pPS->lpVtbl->Release(pPS);
-	}
-}
-
-static void uninitialize_spk(audiomicspk2_t *micspk)
-{
-	if (micspk->ply_stream) {
-		Pa_AbortStream(micspk->ply_stream);
-		Pa_CloseStream(micspk->ply_stream);
-	}
-
-	if (micspk->ply_dbuf) {
-		delay_buf_destroy(micspk->ply_dbuf);
-		micspk->ply_dbuf = NULL;
-	}
-}
-
-static void uninitialize_rec(audiomicspk2_t *micspk)
-{
-	IMediaObject *pDMO = (IMediaObject *)micspk->rec_dmo;
-
-	if (pDMO) {
-		pDMO->lpVtbl->Flush(pDMO);
-		pDMO->lpVtbl->FreeStreamingResources(pDMO);
-		pDMO->lpVtbl->Release(pDMO);
-	}
-	
-	if (micspk->rec_dbuf) {
-		delay_buf_destroy(micspk->rec_dbuf);
-		micspk->rec_dbuf = NULL;
-	}
-	
-	micspk->rec_dmo = NULL;
-}
-
-static void on_clock_rec(audiomicspk2_t *micspk)
-{
-	IMediaObject *pDMO = (IMediaObject*)micspk->rec_dmo;
-	DWORD dwStatus = 0;
-	HRESULT hr;
-	DWORD cOutputBufLen = micspk->rec_buf_size;
-	DMO_OUTPUT_DATA_BUFFER bufferStruct = {0};
-
-	do {
-		bufferStruct.pBuffer = create_media_buffer(cOutputBufLen);
-		bufferStruct.dwStatus = 0;
-
-		hr = pDMO->lpVtbl->ProcessOutput(pDMO, 0, 1, &bufferStruct, &dwStatus);
-
-		if (SUCCEEDED(hr)) {
-			if (hr == S_FALSE) {
-				//....
-			} else {
-				save_data(micspk, bufferStruct.pBuffer);
-#if 0
-				if (micspk->opt & AMS2_OPT_AEC) {
-					dump_aec_config(micspk);
-				}
-#endif
-			}
-
-			bufferStruct.pBuffer->lpVtbl->Release(bufferStruct.pBuffer);
-		} else {
-			bufferStruct.pBuffer->lpVtbl->Release(bufferStruct.pBuffer);
-			break;
-		}
-
-	} while (bufferStruct.dwStatus & DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE);
-	
-}
-
-static unsigned int __stdcall work_proc(void *arg)
-{
-	audiomicspk2_t *micspk = (audiomicspk2_t *)arg;
-	int rc;
-
-	// set a higher priority because of audio is very sensitive about timing
-	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
-
-	CoInitialize(NULL);
-
-	//
-	// record need play because of AEC, so 
-	// record <---> record and play
-	// play   <---> play
-	// record and play <---> record and play
-	//
-	if (micspk->opt & AMS_OPT_RECORD) { 
-		rc = initialize_spk(micspk);
-		if (rc != 0){
-			audio_log_v(AUDIO_LOG_LEVEL_ERROR,"record mode initialize speak louder param failed!");
-			goto on_error;
-		}
-		Sleep(100); // play before record
-		rc = initialize_rec(micspk);
-		if (rc != 0){
-			audio_log_v(AUDIO_LOG_LEVEL_ERROR,"initialize micro capture param failed!");
-			goto on_error;
-		}
-	} else if (micspk->opt & AMS_OPT_PLAY) {
-		rc = initialize_spk(micspk);
-		if (rc != 0){
-			audio_log_v(AUDIO_LOG_LEVEL_ERROR,"play mode initialize speak louder param failed!");
-			goto on_error;
-		}
-	}
-
-	micspk->evt_exit = CreateEventA(NULL, FALSE, FALSE, NULL);
-
-	for (;;) {
-		DWORD dwRet = WaitForSingleObject(micspk->evt_exit, CLOCK_PERIOD);
-		if (dwRet == WAIT_OBJECT_0) { // exit
-			break;
-		} else { // timeout
-			if (micspk->opt & AMS_OPT_RECORD) {
-				on_clock_rec(micspk);
-			} else if (micspk->opt & AMS_OPT_PLAY) {
-				//on_clock_spk(micspk);
-			}
-		}
-	}
-
-on_error:
-
-	if (micspk->opt & AMS_OPT_RECORD) {
-		uninitialize_rec(micspk);
-		uninitialize_spk(micspk);
-	} else if (micspk->opt & AMS_OPT_PLAY) {
-		uninitialize_spk(micspk);
-	}
-
-	CoUninitialize();
-
-	return 0;
-}
-
-static apr_status_t read_frame(void *self, audioframe_t *frame)
-{
-	audiomicspk2_t *micspk = CONTAINING_RECORD(self, audiomicspk2_t, base);
-	UINT32 frame_samples = AUDIO_CLOCK * FRAME_TIME / 1000;
-
-	frame->size = 2*frame_samples;
-	frame->dtmf = 0;
-
-	delay_buf_get(micspk->rec_dbuf, (short*)frame->buffer);
-
-	return APR_SUCCESS;	
-}
-
-static apr_status_t write_frame(void *self, const audioframe_t *frame)
-{
-	audiomicspk2_t *micspk = CONTAINING_RECORD(self, audiomicspk2_t, base);
-
-	delay_buf_put(micspk->ply_dbuf, (short*)frame->buffer);
-
-	return APR_SUCCESS;
-}
-
-static audiostream_vtbl_t g_stream_vtbl = {
-	&read_frame,
-	&write_frame,
-};
-
-apr_status_t audiomicspk2_create(apr_pool_t *pool,
-	audioengine_t *engine, 
-	int opt, 
-	int clock,
-	const char *rec_dev_key,
-	const char *ply_dev_key,
-	audiomicspk2_t **p_micspk)
-{
-	int rec_dev_id = -1; 
-	int ply_dev_id = -1;
-	int ply_dev_id_portaudio = -1;
-	audiomicspk2_t *micspk;
-	unsigned long frame_samples;
-	unsigned long capture_frame_samples;
-
-	ply_dev_id_portaudio = get_device_index_poartaudio(0, ply_dev_key);
-	ply_dev_id = get_device_index(0, ply_dev_key);
-	rec_dev_id = get_device_index(1, rec_dev_key);
-
-	if (rec_dev_id < 0 || ply_dev_id < 0 || ply_dev_id_portaudio < 0)
-		return APR_EGENERAL;
-
-	//opt |= AMS2_OPT_AGC | AMS2_OPT_NS;
-
-	micspk = apr_palloc(pool, sizeof(audiomicspk2_t));
-	memset(micspk, 0, sizeof(audiomicspk2_t));
-
-	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;
-	micspk->ply_dev_id_portaudio = ply_dev_id_portaudio;
-	micspk->opt = opt;
-	micspk->frame_samples = frame_samples;
-	micspk->capture_frame_samples = capture_frame_samples;
-
-	audiostream_init(engine, &g_stream_vtbl, &micspk->base);
-	micspk->base.direction = 0;
-
-	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);
-		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);
-		micspk->input_resample_state = speex_resampler_init(1, CAPTURE_AUDIO_CLOCK, AUDIO_CLOCK, RESAMPLE_QUALITY, NULL);
-	}
-
-	micspk->worker_thread = (HANDLE)_beginthreadex(NULL, 0, &work_proc, micspk, 0, NULL);
-
-	if (micspk->worker_thread) {
-		BOOL bThreadExited = FALSE;
-		do {
-			DWORD dwRet = WaitForSingleObject(micspk->worker_thread, 10);
-			if (dwRet == WAIT_TIMEOUT) {
-				volatile HANDLE hExit = micspk->evt_exit;
-				if (hExit)
-					break;
-			} else if (dwRet == WAIT_OBJECT_0) {
-				bThreadExited = TRUE;
-			}
-		} while (!bThreadExited);
-		if (bThreadExited) {
-			audiomicspk2_destroy(micspk);
-			return APR_EGENERAL;
-		}
-	} else {
-		audiomicspk2_destroy(micspk);
-		return APR_EGENERAL;
-	}
-
-	*p_micspk = micspk;
-
-	return APR_SUCCESS;
-}
-
-void audiomicspk2_destroy(audiomicspk2_t *micspk)
-{
-	if (micspk->evt_exit) {
-		SetEvent(micspk->evt_exit);
-		WaitForSingleObject(micspk->worker_thread, INFINITE);
-		CloseHandle(micspk->worker_thread);
-		CloseHandle(micspk->evt_exit);
-	}
-	if (micspk->input_resample_state) {
-		speex_resampler_destroy((SpeexResamplerState*)micspk->input_resample_state);
-		micspk->input_resample_state = NULL;
-	}
-	if (micspk->output_resample_state) {
-		speex_resampler_destroy((SpeexResamplerState*)micspk->output_resample_state);
-		micspk->output_resample_state = NULL;
-	}
-}
-
- 

+ 0 - 68
Other/unix/libaudioframework/audiomicspk2.h

@@ -1,68 +0,0 @@
-#ifndef __AUDIOMICSPK2_H__
-#define __AUDIOMICSPK2_H__
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define AMS_OPT_RECORD		0x01
-#define AMS_OPT_PLAY		0x02
-#define AMS_OPT_RECPLAY		0x03
-#define AMS_OPT_AS_STREAM	0x00
-#define AMS_OPT_AS_ENGINE	0x04
-
-#include "audiostream.h"
-
-typedef struct audiomicspk2_t audiomicspk2_t;
-
-struct audiomicspk2_t
-{
-	audiostream_t base;
-	
-	int opt;
-	int rec_dev_id;
-	int ply_dev_id;
-	int ply_dev_id_portaudio;
-	int frame_samples;
-	int capture_frame_samples;
-
-	HANDLE evt_exit;
-
-	void *ply_stream;
-	void *ply_dbuf;
-	short *ply_buf;
-	unsigned ply_buf_cnt;
-
-	void *rec_dmo;
-	void *rec_dbuf;
-	DWORD rec_buf_size;
-
-	void *input_resample_state;
-	void *output_resample_state;
-
-	HANDLE worker_thread;
-	int (*on_rx_audio)(char *frame,void*user_data);
-	int (*on_tx_audio)(void* audiodata, void* user_data);
-	int (*on_audio_ns)(void* pdst, size_t udstlen, void* psrc, size_t usrclen, void* user_data);
-	int (*on_audio_play_ns)(void* pdst, size_t udstlen, void* psrc, size_t usrclen, void* user_data);
-	int (*on_audio_playing)(void* pdata, size_t ulen, void* user_data);
-	void (*on_audio_device_event)(bool bopen, int iret, bool bmicro, int idev, const char* strmessage, void* user_data);
-	void*user_data;
-};
-
-apr_status_t audiomicspk2_create(apr_pool_t *pool,
-	audioengine_t *engine, 
-	int opt, 
-	int clock,
-	const char *rec_dev_key,
-	const char *ply_dev_key, 
-	audiomicspk2_t **p_micspk);
-void audiomicspk2_destroy(audiomicspk2_t *micspk);
-
-#ifdef __cplusplus
-} // extern "C" {
-#endif
-
-#endif //__AUDIOMICSPK2_H__

+ 0 - 788
Other/unix/libaudioframework/audiomicspk3.c

@@ -1,788 +0,0 @@
-#include "precompile.h"
-#include "audiomicspk.h"
-#include "audiomicspk3.h"
-#include "audiocontext.h"
-
-#include <assert.h>
-
-#include "audiolog.h"
-#include "./other/delaybuf.h"
-
-#include <dmo.h>
-#include <Mmsystem.h>
-#include <objbase.h>
-#include <mediaobj.h>
-#include <uuids.h>
-#include <propidl.h>
-#include <wmcodecdsp.h>
-
-#include <audioclient.h>
-#include <MMDeviceApi.h>
-#include <AudioEngineEndPoint.h>
-#include <DeviceTopology.h>
-#include <EndpointVolume.h>
-#include <functiondiscoverykeys.h>
-
-#include <portaudio.h>
-
-#define CLOCK_PERIOD	30
-#define MAX_STR_LEN 512
-#define AUDIO_CLOCK	8000
-#define MAX_DELAY	100
-#define MS_REF_TICK	10000
-
-// play use portaudio
-
-typedef struct tagAUDIO_DEVICE_INFO
-{
-	char szDeviceName[MAX_STR_LEN];
-	char szDeviceID[MAX_STR_LEN];
-} AUDIO_DEVICE_INFO, *PAUDIO_DEVICE_INFO;
-
-static HRESULT GetDeviceNum(EDataFlow eDataFlow, UINT *uDevCount)
-{
-	IMMDeviceEnumerator *pEnumerator = NULL;
-	IMMDeviceCollection *pEndpoints = NULL;
-	HRESULT hr;
-
-	hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&pEnumerator);
-	if (FAILED(hr))
-		goto on_error;
-	hr = pEnumerator->lpVtbl->EnumAudioEndpoints(pEnumerator, eDataFlow, DEVICE_STATE_ACTIVE, (void**)&pEndpoints);
-	if (FAILED(hr))
-		goto on_error;
-	hr = pEndpoints->lpVtbl->GetCount(pEndpoints, uDevCount);
-	if (FAILED(hr))
-		goto on_error;
-
-on_error:
-	if (pEndpoints)
-		pEndpoints->lpVtbl->Release(pEndpoints);
-	if (pEnumerator)
-		pEnumerator->lpVtbl->Release(pEnumerator);
-	return hr;
-}
-
-static HRESULT EnumDevice(EDataFlow eDataFlow, UINT uNumElements, AUDIO_DEVICE_INFO *pDevicInfo)
-{
-	IMMDeviceEnumerator *pEnumerator = NULL;
-	IMMDeviceCollection *pEndpoints = NULL;
-	HRESULT hr;
-	UINT uCount;
-	UINT uIdx;
-
-	hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&pEnumerator);
-	if (FAILED(hr))
-		goto on_error;
-	hr = pEnumerator->lpVtbl->EnumAudioEndpoints(pEnumerator, eDataFlow, DEVICE_STATE_ACTIVE, (void**)&pEndpoints);
-	if (FAILED(hr))
-		goto on_error;
-	hr = pEndpoints->lpVtbl->GetCount(pEndpoints, &uCount);
-	if (FAILED(hr))
-		goto on_error;
-
-	ZeroMemory(pDevicInfo, sizeof(AUDIO_DEVICE_INFO)*uNumElements);
-
-	for (uIdx = 0; uIdx < uCount && uIdx < uNumElements; ++uIdx) {
-		IMMDevice *pDevice = NULL;
-		IPropertyStore *pPS = NULL;
-		WCHAR* pszDeviceId = NULL;
-		PROPVARIANT value;
-		PropVariantInit(&value);
-		pEndpoints->lpVtbl->Item(pEndpoints, uIdx, &pDevice);
-		pDevice->lpVtbl->GetId(pDevice, &pszDeviceId);
-		pDevice->lpVtbl->OpenPropertyStore(pDevice, STGM_READ, &pPS);
-		pPS->lpVtbl->GetValue(pPS, &PKEY_Device_FriendlyName, &value);
-		WideCharToMultiByte(CP_ACP, 0, pszDeviceId, -1, pDevicInfo[uIdx].szDeviceID, MAX_STR_LEN-1, NULL, NULL);
-		WideCharToMultiByte(CP_ACP, 0, value.pwszVal, -1, pDevicInfo[uIdx].szDeviceName, MAX_STR_LEN-1, NULL, NULL);
-		PropVariantClear(&value);
-		CoTaskMemFree(pszDeviceId);
-		pPS->lpVtbl->Release(pPS);
-		pDevice->lpVtbl->Release(pDevice);
-	}
-
-on_error:
-	if (pEndpoints)
-		pEndpoints->lpVtbl->Release(pEndpoints);
-	if (pEnumerator)
-		pEnumerator->lpVtbl->Release(pEnumerator);
-	return hr;
-}
-
-static HRESULT DeviceBindTo(
-	EDataFlow eDataFlow,    // eCapture/eRender
-	INT iDevIdx,        // Device Index. -1 - default device. 
-	IAudioClient **ppAudioClient,    // pointer pointer to IAudioClient interface
-	IAudioEndpointVolume **ppEndpointVolume
-	)
-{
-	IMMDeviceEnumerator *pEnumerator = NULL;
-	IMMDeviceCollection *pEndpoints = NULL;
-	IMMDevice *pDevice = NULL;
-	HRESULT hr;
-
-	hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&pEnumerator);
-	if (FAILED(hr))
-		goto on_error;
-
-	if (iDevIdx < 0) {
-		hr = pEnumerator->lpVtbl->GetDefaultAudioEndpoint(pEnumerator, eDataFlow, eConsole, &pDevice);
-		if (FAILED(hr))
-			goto on_error;
-	} else {
-		hr = pEnumerator->lpVtbl->EnumAudioEndpoints(pEnumerator, eDataFlow, DEVICE_STATE_ACTIVE, (void**)&pEndpoints);
-		if (FAILED(hr))
-			goto on_error;
-		hr = pEndpoints->lpVtbl->Item(pEndpoints, iDevIdx, &pDevice);
-		if (FAILED(hr))
-			goto on_error;
-	}
-
-	hr = pDevice->lpVtbl->Activate(pDevice, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void**)ppAudioClient);
-	if (FAILED(hr))
-		goto on_error;
-
-	if (ppEndpointVolume) {
-		hr = pDevice->lpVtbl->Activate(pDevice, &IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, NULL, (void**)ppEndpointVolume);
-		if (FAILED(hr)) {
-			if (*ppAudioClient) {
-				(*ppAudioClient)->lpVtbl->Release(*ppAudioClient);
-				*ppAudioClient = NULL;
-			}
-			goto on_error;
-		}
-	}
-
-on_error:
-
-	if (pDevice) {
-		pDevice->lpVtbl->Release(pDevice);
-	}
-	if (pEndpoints) {
-		pEndpoints->lpVtbl->Release(pEndpoints);
-	}
-	if (pEnumerator) {
-		pEnumerator->lpVtbl->Release(pEnumerator);
-	}
-
-	return hr;
-}
-
-static int get_device_index(int indev, const char *key)
-{
-	EDataFlow df = indev ? eCapture : eRender;
-	UINT i;
-	UINT n;
-	AUDIO_DEVICE_INFO *pInfo = NULL;
-	GetDeviceNum(df, &n);
-	pInfo = malloc(sizeof(AUDIO_DEVICE_INFO) * n);
-	EnumDevice(df, n, pInfo);
-	for (i = 0; i < n; ++i) {
-		if (strstr(pInfo[i].szDeviceName, key)) {
-			free(pInfo);
-			return i;
-		}
-	}
-	free(pInfo);
-	return -1;
-}
-
-static int get_device_index_poartaudio(int indev, const char *key)
-{
-	int i;
-	int n = Pa_GetDeviceCount();
-	for (i = 0; i < n; ++i) {
-		const PaDeviceInfo* pInfo = Pa_GetDeviceInfo(i);
-		if (indev) {
-			if (pInfo->maxInputChannels && strstr(pInfo->name, key))
-				return i;
-		} else {
-			if (pInfo->maxOutputChannels && strstr(pInfo->name, key))
-				return i;
-		}
-	}
-	return -1;
-}
-
-static HRESULT CreateVoiceCaptureDMO(
-	int spk_dev_id,
-	int rec_dev_id,
-	BOOL bNS,
-	BOOL bAGC, 
-	IMediaObject *ppDMO)
-{
-	HRESULT hr = S_OK;
-	return hr;
-}
-
-typedef struct IMediaBufferImpl {
-	struct IMediaBufferVtbl *lpVtbl;
-	struct IMediaBufferVtbl vtbl;
-	BYTE *m_pData;
-	ULONG m_ulSize;
-	ULONG m_ulData;
-	ULONG m_cRef;
-}IMediaBufferImpl;
-
-static HRESULT STDMETHODCALLTYPE QueryInterface(IMediaBuffer * This, REFIID riid, void** ppvObject);
-static ULONG STDMETHODCALLTYPE AddRef(IMediaBuffer * This);
-static ULONG STDMETHODCALLTYPE Release(IMediaBuffer * This);
-static HRESULT STDMETHODCALLTYPE SetLength(IMediaBuffer * This, DWORD ulLength);
-static HRESULT STDMETHODCALLTYPE GetMaxLength(IMediaBuffer * This, DWORD *pcbMaxLength);
-static HRESULT STDMETHODCALLTYPE GetBufferAndLength(IMediaBuffer * This, BYTE **ppBuffer, DWORD *pcbLength);
-
-static void destroy_media_buffer(IMediaBufferImpl *pImpl)
-{
-	free(pImpl->m_pData);
-	free(pImpl);
-}
-
-static IMediaBuffer *create_media_buffer(ULONG len)
-{
-	IMediaBufferImpl *pImpl = (IMediaBufferImpl*)malloc(sizeof(IMediaBufferImpl));
-	if (pImpl) {
-		pImpl->lpVtbl = &pImpl->vtbl;
-		pImpl->lpVtbl->QueryInterface = &QueryInterface;
-		pImpl->lpVtbl->AddRef = &AddRef;
-		pImpl->lpVtbl->Release = &Release;
-		pImpl->lpVtbl->SetLength = &SetLength;
-		pImpl->lpVtbl->GetMaxLength = &GetMaxLength;
-		pImpl->lpVtbl->GetBufferAndLength = &GetBufferAndLength;
-		pImpl->m_pData = (BYTE*)malloc(len);
-		pImpl->m_ulData = 0;
-		pImpl->m_ulSize = len;
-		pImpl->m_cRef = 1;
-	}
-	return (IMediaBuffer*)pImpl;
-}
-
-static HRESULT STDMETHODCALLTYPE QueryInterface(IMediaBuffer * This, REFIID riid, void** ppvObject)
-{
-	if (This == NULL || riid == NULL || ppvObject == NULL || *ppvObject == NULL)
-		return E_POINTER;
-	if (IsEqualIID(riid, &IID_IUnknown)) {
-		*ppvObject = (void*)This;
-		return S_OK;
-	} else if (IsEqualIID(riid, &IID_IMediaBuffer)) {
-		*ppvObject = (void*)This;
-		return S_OK;
-	}
-	return E_NOTIMPL;
-}
-static ULONG STDMETHODCALLTYPE AddRef(IMediaBuffer * This)
-{
-	IMediaBufferImpl *pImpl = (IMediaBufferImpl *)This;
-	return InterlockedIncrement(&pImpl->m_cRef);
-}
-static ULONG STDMETHODCALLTYPE Release(IMediaBuffer * This)
-{
-	IMediaBufferImpl *pImpl = (IMediaBufferImpl *)This;
-	ULONG lRet = InterlockedDecrement(&pImpl->m_cRef);
-	if (lRet == 0) {
-		destroy_media_buffer(pImpl);
-	}
-	return lRet;
-}
-static HRESULT STDMETHODCALLTYPE SetLength(IMediaBuffer * This, DWORD ulLength) 
-{
-	IMediaBufferImpl *pImpl = (IMediaBufferImpl *)This;
-	pImpl->m_ulData = ulLength; 
-	return NOERROR;
-}
-static HRESULT STDMETHODCALLTYPE GetMaxLength(IMediaBuffer * This, DWORD *pcbMaxLength) 
-{
-	IMediaBufferImpl *pImpl = (IMediaBufferImpl *)This;
-	*pcbMaxLength = pImpl->m_ulSize; 
-	return NOERROR;
-}
-static HRESULT STDMETHODCALLTYPE GetBufferAndLength(IMediaBuffer * This, BYTE **ppBuffer, DWORD *pcbLength) 
-{
-	IMediaBufferImpl *pImpl = (IMediaBufferImpl *)This;
-	if (ppBuffer) *ppBuffer = pImpl->m_pData;
-	if (pcbLength) *pcbLength = pImpl->m_ulData;
-	return NOERROR;
-}
-
-
-
-static int load_data(audiomicspk3_t *micspk, BYTE *pData, UINT32 nCount, UINT32 *pReturnedCount)
-{
-	UINT32 frame_samples = AUDIO_CLOCK * FRAME_TIME / 1000;
-	UINT32 frame_offset = 0;
-	while (nCount >= frame_samples) {
-		delay_buf_get(micspk->ply_dbuf, (SHORT*)(pData+frame_offset*2));
-		frame_offset += frame_samples;
-		nCount -= frame_samples;
-	}
-	*pReturnedCount = frame_offset;
-	return 0;
-}
-
-static int save_data(audiomicspk3_t *micspk, IMediaBuffer *pBuffer)
-{
-	UINT32 frame_samples = AUDIO_CLOCK * FRAME_TIME / 1000;
-	UINT32 frame_offset = 0;
-	BYTE *pData;
-	DWORD dwLength;
-	pBuffer->lpVtbl->GetBufferAndLength(pBuffer, &pData, &dwLength);
-	//AUDIO_LOG_INFO("micspk2 rec samples:%d", dwLength>>1);
-	while (dwLength >= frame_samples*2) {
-		delay_buf_put(micspk->rec_dbuf, (SHORT*)(pData+frame_offset*2));
-		frame_offset += frame_samples;
-		dwLength -= frame_samples*2;
-	}
-	return 0;
-}
-
-static int StreamCallback(const void *input, 
-	void *output, 
-	unsigned long frameCount, 
-	const PaStreamCallbackTimeInfo* timeInfo, 
-	PaStreamCallbackFlags statusFlags, 
-	void *userData)
-{
-	audiomicspk3_t *micspk = (audiomicspk3_t*)userData;
-	apr_status_t status;
-
-	if (output) {
-		unsigned nsamples_req = frameCount;
-		if (micspk->ply_buf_cnt == 0 && nsamples_req == micspk->frame_samples) {
-			delay_buf_get(micspk->ply_dbuf, (short*)output);
-		} else {
-			if (micspk->ply_buf_cnt > 0) {
-				memcpy(output, micspk->ply_buf, micspk->ply_buf_cnt<<1);
-				output = (short*)output + micspk->ply_buf_cnt;
-				micspk->ply_buf_cnt = 0;
-				nsamples_req -= micspk->ply_buf_cnt;
-			}
-			while (nsamples_req > 0) {
-				if (nsamples_req >= micspk->frame_samples) {
-					delay_buf_get(micspk->ply_dbuf, (short*)output);
-					output = (short*)output + micspk->frame_samples;
-					nsamples_req -= micspk->frame_samples;
-				} else {
-					delay_buf_get(micspk->ply_dbuf, micspk->ply_buf);
-					micspk->ply_buf_cnt = micspk->frame_samples;
-					memcpy(output, micspk->ply_buf, nsamples_req<<1);
-					output = (short*)output + nsamples_req;
-					memmove(micspk->ply_buf, micspk->ply_buf+nsamples_req, (micspk->frame_samples-nsamples_req)<<1);
-					nsamples_req = 0;
-				}
-			}
-		}
-	}
-
-	return paContinue;
-}
-
-static int initialize_spk(audiomicspk3_t *micspk)
-{
-	UINT32 frame_samples = AUDIO_CLOCK * FRAME_TIME / 1000;
-	const PaDeviceInfo *info;
-	PaStreamParameters outParam;
-	PaError paError;
-	int ply_dev_id = micspk->ply_dev_id_portaudio;
-
-	if (ply_dev_id == -1) {
-		ply_dev_id = Pa_GetDefaultOutputDevice();
-		if (ply_dev_id == paNoDevice) {
-			audio_log_v(AUDIO_LOG_LEVEL_ERROR,"audiomicspk create error, cannot find output device");
-			return APR_EGENERAL;
-		}
-	}
-	info = Pa_GetDeviceInfo(ply_dev_id);
-	outParam.device = ply_dev_id;
-	outParam.channelCount = 1;
-	outParam.sampleFormat = paInt16;
-	outParam.suggestedLatency = info->defaultLowOutputLatency;
-	outParam.hostApiSpecificStreamInfo = NULL;
-	if (Pa_IsFormatSupported(NULL, &outParam, AUDIO_CLOCK) != paNoError) {
-		audio_log_v(AUDIO_LOG_LEVEL_ERROR,"audiomicspk create error, cannot open audio output device");
-		return APR_EGENERAL;
-	}
-
-	paError = Pa_OpenStream(&micspk->ply_stream, NULL, &outParam, AUDIO_CLOCK, frame_samples, paClipOff, &StreamCallback, micspk);
-	if (paError != 0) {
-		audio_log_v(AUDIO_LOG_LEVEL_ERROR,"audiomicspk create error, Pa_OpenStream function failed in dir! ");
-		return APR_EGENERAL;
-	}
-	paError = Pa_StartStream(micspk->ply_stream);
-	if (paError != 0) {
-		audio_log_v(AUDIO_LOG_LEVEL_ERROR,"Pa_StartStream function failed in dir! ");
-		Pa_CloseStream(micspk->ply_stream);
-		micspk->ply_stream = NULL;
-		return APR_EGENERAL;
-	}
-
-	return 0;
-}
-
-static int initialize_rec(audiomicspk3_t *micspk)
-{
-	IMediaObject *pDMO = NULL;
-	IPropertyStore *pPS = NULL;
-	HRESULT hr;
-	UINT32 frame_samples = AUDIO_CLOCK * FRAME_TIME / 1000;
-
-	hr = CoCreateInstance(&CLSID_CWMAudioAEC, NULL, CLSCTX_INPROC_SERVER, &IID_IMediaObject, (void**)&pDMO);
-
-	if (SUCCEEDED(hr)) {
-		hr = pDMO->lpVtbl->QueryInterface(pDMO, &IID_IPropertyStore, (void**)&pPS);
-	}
-
-	if (FAILED(hr)) {
-		if (pDMO) {
-			pDMO->lpVtbl->Release(pDMO);
-		}
-		return -1;
-	}
-
-	// sys mode
-	{
-		PROPVARIANT pvSysMode;
-		PropVariantInit(&pvSysMode);
-		pvSysMode.vt = VT_I4;
-		pvSysMode.lVal = micspk->opt & AMS2_OPT_AEC ? SINGLE_CHANNEL_AEC : SINGLE_CHANNEL_NSAGC;
-		//pvSysMode.lVal = micspk->opt & AMS2_OPT_AEC ? OPTIBEAM_ARRAY_AND_AEC : SINGLE_CHANNEL_NSAGC;
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_SYSTEM_MODE, &pvSysMode);
-		PropVariantClear(&pvSysMode);
-	}
-
-	// feature mode
-	{
-		PROPVARIANT pvFeatMode;
-		PropVariantInit(&pvFeatMode);
-		pvFeatMode.vt = VT_BOOL;
-		pvFeatMode.boolVal = VARIANT_TRUE;		
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_FEATURE_MODE, &pvFeatMode);
-		PropVariantClear(&pvFeatMode);
-	}
-
-	// set device index
-	{
-		PROPVARIANT pvDeviceId;
-		PropVariantInit(&pvDeviceId);
-		pvDeviceId.vt = VT_I4;
-		pvDeviceId.lVal = (unsigned long)(micspk->ply_dev_id<<16) + (unsigned long)(0x0000ffff & micspk->rec_dev_id);
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_DEVICE_INDEXES, &pvDeviceId);
-		PropVariantClear(&pvDeviceId);
-	}
-
-	// echo length
-#if 1
-	if (micspk->opt & AMS2_OPT_AEC)
-	{
-		PROPVARIANT pvEchoLength;
-		PropVariantInit(&pvEchoLength);
-		pvEchoLength.vt = VT_I4;
-		pvEchoLength.lVal = 128;
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_FEATR_ECHO_LENGTH, &pvEchoLength);
-		PropVariantClear(&pvEchoLength);
-	}
-#endif
-
-	// echo supress times
-#if 1
-	if (micspk->opt & AMS2_OPT_AEC)
-	{
-		PROPVARIANT pvAESTimes;
-		PropVariantInit(&pvAESTimes);
-		pvAESTimes.vt = VT_I4;
-		pvAESTimes.lVal = 1; // 0, 1, 2
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_FEATR_AES, &pvAESTimes);
-		PropVariantClear(&pvAESTimes);
-	}
-#endif
-
-	// retreive TS
-	if (micspk->opt & AMS2_OPT_AEC) 
-	{
-		PROPVARIANT pvTS;
-		PropVariantInit(&pvTS);
-		pvTS.vt = VT_BOOL;
-		pvTS.boolVal = VARIANT_TRUE;		
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_RETRIEVE_TS_STATS, &pvTS);
-		PropVariantClear(&pvTS);
-	}
-
-	// noise suppression
-	{
-		PROPVARIANT pvNoiseSup;
-		PropVariantInit(&pvNoiseSup);
-		pvNoiseSup.vt = VT_I4;
-		pvNoiseSup.lVal = micspk->opt & AMS2_OPT_NS;
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_FEATR_NS, &pvNoiseSup);
-		PropVariantClear(&pvNoiseSup);
-	}
-
-	// Turn on/off AGC
-	{
-		PROPVARIANT pvAGC;
-		PropVariantInit(&pvAGC);
-		pvAGC.vt = VT_BOOL;
-		pvAGC.boolVal = micspk->opt & AMS2_OPT_AGC ? VARIANT_TRUE : VARIANT_FALSE;
-		pPS->lpVtbl->SetValue(pPS, &MFPKEY_WMAAECMA_FEATR_AGC, &pvAGC);
-		PropVariantClear(&pvAGC);
-	}
-
-	// set output format
-	{
-		DMO_MEDIA_TYPE mt = {0};
-		WAVEFORMATEX wfxOut = {WAVE_FORMAT_PCM, 1, 8000, 16000, 2, 16, 0};
-		MoInitMediaType(&mt, sizeof(WAVEFORMATEX));
-		mt.majortype = MEDIATYPE_Audio;
-		mt.subtype = MEDIASUBTYPE_PCM;
-		mt.lSampleSize = 0;
-		//mt.lSampleSize = 2;
-		mt.bFixedSizeSamples = TRUE;
-		mt.bTemporalCompression = FALSE;
-		mt.formattype = FORMAT_WaveFormatEx;
-		memcpy(mt.pbFormat, &wfxOut, sizeof(WAVEFORMATEX));
-		pDMO->lpVtbl->SetOutputType(pDMO, 0, &mt, 0); 
-		micspk->rec_buf_size = wfxOut.nSamplesPerSec * wfxOut.wBitsPerSample / 8;
-		MoFreeMediaType(&mt);
-	}
-
-	delay_buf_create(AUDIO_CLOCK, frame_samples, 1, MAX_DELAY, 0, (delay_buf**)&micspk->rec_dbuf);
-
-	pDMO->lpVtbl->AllocateStreamingResources(pDMO);
-
-	pPS->lpVtbl->Release(pPS);
-
-	micspk->rec_dmo = pDMO;
-
-	return 0;
-}
-
-static void uninitialize_spk(audiomicspk3_t *micspk)
-{
-	if (micspk->ply_stream) {
-		Pa_AbortStream(micspk->ply_stream);
-		Pa_CloseStream(micspk->ply_stream);
-	}
-
-	if (micspk->ply_dbuf) {
-		delay_buf_destroy(micspk->ply_dbuf);
-		micspk->ply_dbuf = NULL;
-	}
-}
-
-static void uninitialize_rec(audiomicspk3_t *micspk)
-{
-	IMediaObject *pDMO = (IMediaObject *)micspk->rec_dmo;
-
-	if (pDMO) {
-		pDMO->lpVtbl->Release(pDMO);
-	}
-	
-	if (micspk->rec_dbuf) {
-		delay_buf_destroy(micspk->rec_dbuf);
-		micspk->rec_dbuf = NULL;
-	}
-	
-	micspk->rec_dmo = NULL;
-}
-
-static void on_clock_rec(audiomicspk3_t *micspk)
-{
-	IMediaObject *pDMO = (IMediaObject*)micspk->rec_dmo;
-	DWORD dwStatus = 0;
-	HRESULT hr;
-	DWORD cOutputBufLen = micspk->rec_buf_size;
-	DMO_OUTPUT_DATA_BUFFER bufferStruct = {0};
-
-	do {
-		bufferStruct.pBuffer = create_media_buffer(cOutputBufLen);
-		bufferStruct.dwStatus = 0;
-
-		hr = pDMO->lpVtbl->ProcessOutput(pDMO, 0, 1, &bufferStruct, &dwStatus);
-
-		if (SUCCEEDED(hr)) {
-			if (hr == S_FALSE) {
-				//....
-			} else {
-				save_data(micspk, bufferStruct.pBuffer);
-			}
-
-			bufferStruct.pBuffer->lpVtbl->Release(bufferStruct.pBuffer);
-		} else {
-			bufferStruct.pBuffer->lpVtbl->Release(bufferStruct.pBuffer);
-			break;
-		}
-
-	} while (bufferStruct.dwStatus & DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE);
-	
-}
-
-static unsigned int __stdcall work_proc(void *arg)
-{
-	audiomicspk3_t *micspk = (audiomicspk3_t *)arg;
-	int rc;
-
-	// set a higher priority because of audio is very sensitive about timing
-	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
-
-	CoInitialize(NULL);
-
-	//
-	// record need play because of AEC, so 
-	// record <---> record and play
-	// play   <---> play
-	// record and play <---> record and play
-	//
-	if (micspk->opt & AMS_OPT_RECORD) { 
-		rc = initialize_spk(micspk);
-		if (rc != 0)
-			goto on_error;
-		rc = initialize_rec(micspk);
-		if (rc != 0)
-			goto on_error;
-	} else if (micspk->opt & AMS_OPT_PLAY) {
-		rc = initialize_spk(micspk);
-		if (rc != 0)
-			goto on_error;
-	}
-
-	micspk->evt_exit = CreateEventA(NULL, FALSE, FALSE, NULL);
-
-	for (;;) {
-		DWORD dwRet = WaitForSingleObject(micspk->evt_exit, CLOCK_PERIOD);
-		if (dwRet == WAIT_OBJECT_0) { // exit
-			break;
-		} else { // timeout
-			if (micspk->opt & AMS_OPT_RECORD) {
-				on_clock_rec(micspk);
-			} else if (micspk->opt & AMS_OPT_PLAY) {
-				//on_clock_spk(micspk);
-			}
-		}
-	}
-
-on_error:
-
-	if (micspk->opt & AMS_OPT_RECORD) {
-		uninitialize_spk(micspk);
-		uninitialize_rec(micspk);
-	} else if (micspk->opt & AMS_OPT_PLAY) {
-		uninitialize_spk(micspk);
-	}
-
-	CoUninitialize();
-
-	return 0;
-}
-
-static apr_status_t read_frame(void *self, audioframe_t *frame)
-{
-	audiomicspk3_t *micspk = CONTAINING_RECORD(self, audiomicspk3_t, base);
-	UINT32 frame_samples = AUDIO_CLOCK * FRAME_TIME / 1000;
-
-	frame->size = 2*frame_samples;
-	frame->dtmf = 0;
-
-	delay_buf_get(micspk->rec_dbuf, (short*)frame->buffer);
-
-	return APR_SUCCESS;	
-}
-
-static apr_status_t write_frame(void *self, const audioframe_t *frame)
-{
-	audiomicspk3_t *micspk = CONTAINING_RECORD(self, audiomicspk3_t, base);
-
-	delay_buf_put(micspk->ply_dbuf, (short*)frame->buffer);
-
-	return APR_SUCCESS;
-}
-
-static audiostream_vtbl_t g_stream_vtbl = {
-	&read_frame,
-	&write_frame,
-};
-
-apr_status_t audiomicspk3_create(apr_pool_t *pool,
-	audioengine_t *engine, 
-	int opt, 
-	int clock,
-	const char *rec_dev_key,
-	const char *ply_dev_key,
-	audiomicspk3_t **p_micspk)
-{
-	int rec_dev_id = -1; 
-	int ply_dev_id = -1;
-	int ply_dev_id_portaudio = -1;
-	audiomicspk3_t *micspk;
-	unsigned long frame_samples;
-
-	ply_dev_id_portaudio = get_device_index_poartaudio(0, ply_dev_key);
-	ply_dev_id = get_device_index(0, ply_dev_key);
-	rec_dev_id = get_device_index(1, rec_dev_key);
-
-	if (rec_dev_id < 0 || ply_dev_id < 0 || ply_dev_id_portaudio < 0)
-		return APR_EGENERAL;
-
-	//opt |= AMS2_OPT_AGC | AMS2_OPT_NS;
-
-	micspk = apr_palloc(pool, sizeof(audiomicspk3_t));
-	memset(micspk, 0, sizeof(audiomicspk3_t));
-
-	frame_samples = FRAME_TIME * clock / 1000;
-
-	micspk->rec_dev_id = rec_dev_id;
-	micspk->ply_dev_id = ply_dev_id;
-	micspk->ply_dev_id_portaudio = ply_dev_id_portaudio;
-	micspk->opt = opt;
-	micspk->frame_samples = frame_samples;
-
-	audiostream_init(engine, &g_stream_vtbl, &micspk->base);
-	micspk->base.direction = 0;
-
-	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);
-		micspk->ply_buf = (short*)apr_palloc(pool, frame_samples<<1);
-		micspk->ply_buf_cnt = 0;
-	}
-	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->worker_thread = (HANDLE)_beginthreadex(NULL, 0, &work_proc, micspk, 0, NULL);
-
-	if (micspk->worker_thread) {
-		BOOL bThreadExited = FALSE;
-		do {
-			DWORD dwRet = WaitForSingleObject(micspk->worker_thread, 10);
-			if (dwRet == WAIT_TIMEOUT) {
-				volatile HANDLE hExit = micspk->evt_exit;
-				if (hExit)
-					break;
-			} else if (dwRet == WAIT_OBJECT_0) {
-				bThreadExited = TRUE;
-			}
-		} while (!bThreadExited);
-		if (bThreadExited) {
-			audiomicspk3_destroy(micspk);
-			return APR_EGENERAL;
-		}
-	} else {
-		audiomicspk3_destroy(micspk);
-		return APR_EGENERAL;
-	}
-
-	*p_micspk = micspk;
-
-	return APR_SUCCESS;
-}
-
-void audiomicspk3_destroy(audiomicspk3_t *micspk)
-{
-	if (micspk->evt_exit) {
-		SetEvent(micspk->evt_exit);
-		WaitForSingleObject(micspk->worker_thread, INFINITE);
-		CloseHandle(micspk->worker_thread);
-		CloseHandle(micspk->evt_exit);
-	}
-}
-
- 

+ 0 - 56
Other/unix/libaudioframework/audiomicspk3.h

@@ -1,56 +0,0 @@
-#ifndef __AUDIOMICSPK3_H__
-#define __AUDIOMICSPK3_H__
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define AMS2_OPT_AGC			0x04
-#define AMS2_OPT_NS				0x08
-#define AMS2_OPT_AEC			0x10
-
-#include "audiostream.h"
-
-typedef struct audiomicspk3_t audiomicspk3_t;
-
-struct audiomicspk3_t
-{
-	audiostream_t base;
-	
-	int opt;
-	int rec_dev_id;
-	int ply_dev_id;
-	int ply_dev_id_portaudio;
-	int frame_samples;
-
-	HANDLE evt_exit;
-
-	void *ply_stream;
-	void *ply_dbuf;
-	short *ply_buf;
-	unsigned ply_buf_cnt;
-
-	void *rec_dmo;
-	void *rec_dbuf;
-	DWORD rec_buf_size;
-
-
-	HANDLE worker_thread;
-};
-
-apr_status_t audiomicspk3_create(apr_pool_t *pool,
-	audioengine_t *engine, 
-	int opt, 
-	int clock,
-	const char *rec_dev_key,
-	const char *ply_dev_key, 
-	audiomicspk3_t **p_micspk);
-void audiomicspk3_destroy(audiomicspk3_t *micspk);
-
-#ifdef __cplusplus
-} // extern "C" {
-#endif
-
-#endif //__AUDIOMICSPK3_H__