您的位置:首页 > 其它

win7 系统下实现音量控制

2012-12-25 15:05 603 查看
win7对audio做了改进,除了有总音量控制, 每个程序又有自己的音量控制。通常XP下控制音量的函数只能控制自己的音量而无法控制主音量。(比如函数 :mixerGetLineInfo 、mixerGetLineControls 等). 所以使用这些函数无法实现音量控制的功能, 改进的做法是使用audio endpoint .



在win7下使用COM 获得 audio endpoint 从而实现音量控制demo code :

HRESULT hr = S_OK;

hr = CoInitialize(NULL); //保留参数,必须为NULL

GUID g_guidMyContext = GUID_NULL;

hr = CoCreateGuid(&g_guidMyContext); // 生成一个GUID码 用来识别 CLSIDs and interface 

IMMDeviceEnumerator *deviceEnumerator = NULL;
 hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);

  IMMDevice *defaultDevice = NULL;

  hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice); 

  deviceEnumerator->Release();
  deviceEnumerator = NULL;

  IAudioEndpointVolume *endpointVolume = NULL;
  hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume),CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);

  defaultDevice->Release();
  defaultDevice = NULL;

  UINT uStep = 0;
  UINT uStepCount = 0;
  endpointVolume->GetVolumeStepInfo(&uStep,&uStepCount) ; // step range from 0 to*pStepCount– 1

  endpointVolume->SetMasterVolumeLevel(fVolume,&g_guidMyContext) ; // in decibel

  endpointVolume->SetMasterVolumeLevelScalar(fVolume,&g_guidMyContext) ; 

  endpointVolume->SetMute(0,&g_guidMyContext);  //mute


下面分别解释每一步的意义:



HRESULT hr = S_OK;

hr = CoInitialize(NULL); //保留参数,必须为NULL

应用程序调用com库函数(除CoGetMalloc和内存分配函数)之前必须初始化com库。

CoInitialize 是 Windows提供的API函数,用来告诉 Windows以单线程的方式创建com对象。(CoInitializeEX是多线程方式)使用 CoInitialize 创建可以使对象直接与线程连接,得到最高的性能。CoInitialize并不装载COM 库,它只用来初始化当前线程使用什么样的套间。使用这个函数后,线程就和一个套间建立了对应关系。线程的套间模式决定了该线程如何调用COM对象,是否需要列集等。 CoInitialize ()并不会干扰客户和服务器之间的通信,它所做的事情是让线程注册一个套间,而线程运行过程中必然在此套间。
  CoInitialize
CoUninitialize 必须成对使用在每个线程函数里。

GUID g_guidMyContext = GUID_NULL;

hr = CoCreateGuid(&g_guidMyContext); // 生成一个GUID码 用来识别 CLSIDs and interface

COM中所有的类、接口、类型库都用GUID来唯一标识. GUID是一个128位的字串 .COM组件的创建,查询接口都是通过注册表进行的。有了注册表,应用程序就不需要知道组件的DLL文件名、位置,只需要根据CLSID查就可以了。

IMMDeviceEnumerator *deviceEnumerator = NULL;
 hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);

CoCreateInstance(....) // 函数内部实现

{
.......
IClassFactory*pClassFactory=NULL;
CoGetClassObject(CLSID_Object,CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&pClassFactory);   //创建类厂
pClassFactory->CreateInstance(NULL,IID_IUnknown, (void**)&pUnk);//创建com对象
pClassFactory->Release();
........
}
到这里就可以使用这个com实例了 ............
IMMDevice *defaultDevice = NULL;

  hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);


// 第一个参数代表设备 ,eRender是输出设备,eCapture是输入设备。

//第二个参数是erole ,用来指定具体设备。有三个选择 :eConsole eMultimedia eCommunications .详情看这里
http://technet.microsoft.com/zh-cn/library/dd371401

deviceEnumerator->Release();
  deviceEnumerator = NULL;

  IAudioEndpointVolume *endpointVolume = NULL;
  hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume),CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);



//生成一个指定类型的com接口实例

//___uuidof : 用来获得一个接口的ID .



defaultDevice->Release();
  defaultDevice = NULL;

  UINT uStep = 0;
  UINT uStepCount = 0;
  endpointVolume->GetVolumeStepInfo(&uStep,&uStepCount) ; // step range from 0 to*pStepCount– 1

  endpointVolume->SetMasterVolumeLevel(fVolume,&g_guidMyContext) ; // in decibel

  endpointVolume->SetMasterVolumeLevelScalar(fVolume,&g_guidMyContext) ; // The volume level is expressed as a normalized  in the range from 0.0 to 1.0.

  endpointVolume->SetMute(0,&g_guidMyContext);  //mute
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: