#include #include #include #include //#include #include #include #define WIN32_LEAN_AND_MEAN #include #include "../libaudioframework/audioframework.h" #include "../libvideoframework/videoframework.h" #include #include #include #include #include #ifndef MAX_STR_LEN #define MAX_STR_LEN 512 #endif // !MAX_STR_LEN static int audio_translate_id(int in_direction, int idx) { int i, n, ii; //audio_log_set_func(NULL); n = Pa_GetDeviceCount(); for (i = 0, ii = 0; i < n; ++i) { const PaDeviceInfo *info = Pa_GetDeviceInfo(i); if (in_direction) { if (info->maxInputChannels) { if (ii == idx) { //audio_log_set_func(__audio_log_func); return i; } ii++; } } else { if (info->maxOutputChannels) { if (ii == idx) { //audio_log_set_func(__audio_log_func); return i; } ii++; } } } //audio_log_set_func(__audio_log_func); return -1; } int audio_get_dev_count(int *in_cnt, int *out_cnt) { int i; int icnt = 0, ocnt = 0; int cnt = Pa_GetDeviceCount(); printf("Pa_GetDeviceCount get device count is %d.\n", cnt); for (i = 0; i < cnt; ++i) { const PaDeviceInfo *info = Pa_GetDeviceInfo(i); if (info->maxInputChannels) icnt ++; if (info->maxOutputChannels) ocnt ++; } if (in_cnt) *in_cnt = icnt; if (out_cnt) *out_cnt = ocnt; return 0; } static char *audio_get_dev_name(char *buf, BOOL in_direction, int idx) { int cnt = Pa_GetDeviceCount(); int ii, i; for (i = 0, ii = 0; i < cnt; ++i) { const PaDeviceInfo *info = Pa_GetDeviceInfo(i); if (in_direction) { if (info->maxInputChannels) { if (idx == ii) { strcpy(buf, info->name); return buf; } ii++; } } else { if (info->maxOutputChannels) { if (idx == ii) { strcpy(buf, info->name); return buf; } ii++; } } } return NULL; } static void show_audio_dev() { int icnt, ocnt; int rc = audio_get_dev_count(&icnt, &ocnt); if (rc == 0) { int i; char tmp[128]; printf("audio input devices(%d):\n", icnt); for (i = 0; i < icnt; ++i) { audio_get_dev_name(tmp, TRUE, i); printf("%d = %s\n", i, tmp); } printf("audio output devices(%d):\n", ocnt); for (i = 0; i < ocnt; ++i) { audio_get_dev_name(tmp, FALSE, i); printf("%d = %s\n", i, tmp); } printf("\n"); } } 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 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 void show_audio_dev2() { UINT i; UINT n; AUDIO_DEVICE_INFO *pInfo = NULL; GetDeviceNum(eCapture, &n); pInfo = malloc(sizeof(AUDIO_DEVICE_INFO) * n); EnumDevice(eCapture, n, pInfo); printf("audio input devices -- win7 (%d):\n", n); for (i = 0; i < n; ++i) { printf("%d = %s\n", i, pInfo[i].szDeviceName); } free(pInfo); GetDeviceNum(eRender, &n); pInfo = malloc(sizeof(AUDIO_DEVICE_INFO) * n); EnumDevice(eRender, n, pInfo); printf("audio output devices -- win7 (%d):\n", n); for (i = 0; i < n; ++i) { printf("%d = %s\n", i, pInfo[i].szDeviceName); } free(pInfo); } static int Bin2Str(unsigned char *x, int xlen, char *str, int str_size) { static const char *hex2char = "0123456789ABCDEF"; int i, k = 0; if (str_size <= xlen * 2) return -1; for (i = 0; i < xlen; ++i) { int h = x[i] >> 4; int l = x[i] & 0xf; str[k++] = hex2char[h]; str[k++] = hex2char[l]; } str[k] = 0; return k; } static void show_video_dev() { int i, n; n = videocap_get_device_count(); printf("video devices(%d):\n", n); for (i = 0; i < n; ++i) { WCHAR tmp[256]; char t[256]; videocap_get_device_name(i, tmp, ARRAYSIZE(tmp)); WideCharToMultiByte(CP_ACP, 0, tmp, -1, t, sizeof(t), 0, NULL); printf("%d = %s;", i, t); videocap_get_device_path(i, tmp, ARRAYSIZE(tmp)); WideCharToMultiByte(CP_ACP, 0, tmp, -1, t, sizeof(t), 0, NULL); { unsigned char x[MD5_DIGESTSIZE]; md5_ctx_t ctx; md5_init(&ctx); md5(x, t, strlen(t)); Bin2Str(x, sizeof(x), t, sizeof(t)); } printf("%s\n", t); } printf("\n"); } static void __dummy_log_callback(const char *log) { } static int app_init() { HRESULT hret = CoInitialize(NULL); Pa_Initialize(); //PaUtil_SetDebugPrintFunction(&__dummy_log_callback); audioframework_init(); videoframework_init(); return 0; } static void app_term() { videoframework_term(); audioframework_term(); CoUninitialize(); Pa_Terminate(); } int main() { printf("%s\n", setlocale(LC_ALL, "chs")); { HMODULE hModule = GetModuleHandleA("MSVCR100.dll"); if (hModule) { typedef char* (*f_setlocale)(int, const char*); f_setlocale f = (f_setlocale)GetProcAddress(hModule, "setlocale"); (*f)(LC_ALL, "chs"); } } if (app_init() != 0) { printf("app init failed!\n"); return -1; } show_audio_dev(); show_video_dev(); //MessageBoxA(0,0,0,0); //show_audio_dev2(); //getchar(); app_term(); return 0; }