乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Core Audio APIs 技術筆記一(揚聲器音量設置)

       mediatv 2019-10-29

              最近在做winsows上音頻方面的程序,用到Core Audio APIs系列API來設置相關音頻設備參數(shù),所以對用到這方面的知識做一個總結。Core Audio APIs是Windows Vista家族后提供一套新的底層API,主要有以下幾個內(nèi)容

       Multimedia Device (MMDevice) API:用來枚舉操作系統(tǒng)自帶的音頻終端設備對象。
       Windows Audio Session API (WASAPI):根據(jù)第一步枚舉處理終端設備對象創(chuàng)建和管理音頻流。
       DeviceTopology API:使用此類API可以直接訪問音頻適配器中的硬件數(shù)據(jù)通路的拓撲特性(如音量控制,多路復用器等)。
       EndpointVolume API:使用此類API可以直接訪問音頻設備的聲音控制,這類API主要是給那些毒戰(zhàn)模式管理音頻流的應用程序。

      下面讓我們用代碼事例設置麥克風和揚聲器音量大小,以及設置麥克風加強來說明相關用法:

        1. 首先我們定義相關COM接口如下,后面要用到:

      1. CComPtr<IMMDeviceEnumerator > m_pIMMEnumerator; //主要用于枚舉設備接口
      2. CComPtr<IAudioEndpointVolume> m_pRenderEndptVol; //揚聲器音量控制接口
      3. CComPtr<ISimpleAudioVolume> m_pRenderSimpleVol; //揚聲器的會話音量控制接口

       2.創(chuàng)建IMMDeviceEnumerator接口,IMMDeviceEnumerator接口是獲取后面設備對象的根本,所以先要創(chuàng)建這個接口,用常用創(chuàng)建COM接口的CoCreateInstance()來創(chuàng)建,指定相應的參數(shù),很基本用法,不做過多說明。

      1. HRESULT hr = S_OK;
      2. hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, (void**)&m_pIMMEnumerator);

      pIMMEnumerator對象創(chuàng)建好,我們可以看看這個接口可以用的方法:

      1. class IMMDeviceEnumerator : public IUnknown
      2. {
      3. public:
      4. virtual HRESULT STDMETHODCALLTYPE EnumAudioEndpoints(EDataFlow dataFlow, DWORD dwStateMask, IMMDeviceCollection **ppDevices) = 0;
      5. virtual HRESULT STDMETHODCALLTYPE GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, IMMDevice **ppEndpoint) = 0;
      6. virtual HRESULT STDMETHODCALLTYPE GetDevice(LPCWSTR pwstrId, IMMDevice **ppDevice) = 0;
      7. virtual HRESULT STDMETHODCALLTYPE RegisterEndpointNotificationCallback(IMMNotificationClient *pClient) = 0;
      8. virtual HRESULT STDMETHODCALLTYPE UnregisterEndpointNotificationCallback(IMMNotificationClient *pClient) = 0;
      9. };

      可以看到除過IUnKonwn接口方法外有屬于自己的五個方法,分別如下:

      1. //枚舉系統(tǒng)所有設備
      2. EnumAudioEndpoints(EDataFlow dataFlow, DWORD dwStateMask, IMMDeviceCollection **ppDevices);
      3. //獲取系統(tǒng)默認音頻設備,類似主音頻設備
      4. GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, IMMDevice **ppEndpoint);
      5. //根據(jù)設備ID獲取指定的設備,設備ID可以通過EnumAudioEndpoints()獲取,也可以通過DSound函數(shù)DirectSoundEnumerate()等獲取。
      6. GetDevice(LPCWSTR pwstrId, IMMDevice **ppDevice);
      7. //注冊給終端設備一些通知事件,注冊后比如當設備撥出、插入、有變化時會收到相應的通知事件。
      8. RegisterEndpointNotificationCallback(IMMNotificationClient *pClient);
      9. //注銷掉之前注冊的通知回調(diào)。
      10. UnregisterEndpointNotificationCallback();

      本次我們主要是用GetDefaultAudioEndpoint()和GetDevice()這兩個接口方法。

      4.獲取IAudioEndpointVolume揚聲器m_pRenderEndptVol接口,首先我們要定義一個IMMDevice對象,根據(jù)剛剛創(chuàng)建的m_pIMMEnumerator對象獲取相應的IMMDevice對象,然后用獲取的IMMDevice對象激活m_pRenderEndptVol接口。

      如果之前沒有獲取終端ID則可以使用

      1. //EDataFlow/有三個常用的變量:
      2. //eAll : 會列舉出系統(tǒng)中所有的音頻設備包括Render --- 揚聲器, Capture --- Microphone, Stereo Mixer;
      3. //eRender: 會列舉出系統(tǒng)中所有的音頻播放設備;
      4. //eCapture: 會列舉出系統(tǒng)中所有音頻采集設備;
      5. //ERole 設備角色,假如系統(tǒng)中有多個音頻設備,那么一個設備可能用戶是用來播放電影的,另一個可能是用來玩游戲的,因此就引入了角色的概念。
      6. //eConsole : 與計算機交互; eCommunications : 與他人的聲音交流; eMultimedia : 播放或者錄制電影和音樂,一般默認使用eConsole。
      7. //ppEndpoint:需要接收獲取設備對象指針。
      8. HRESULT GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, IMMDevice **ppEndpoint);

      如果之前已經(jīng)枚舉出設備ID,想要根據(jù)設備ID過去指定的設備對象,可以使用

      1. //pwstrId: 已經(jīng)獲取的設備ID;
      2. //ppDevice:需要接收獲取設備對象二重指針;
      3. HRESULT GetDevice(LPCWSTR pwstrId, IMMDevice **ppDevice)

      示例代碼如下:

      1. HRESULT hr = S_OK;
      2. CComPtr<IMMDevice> pIMMDeivce = NULL;
      3. if(strEndPointID.empty())
      4. {
      5. hr = m_pIMMEnumerator->GetDefaultAudioEndpoint(eRender,eConsole,&pIMMDeivce);
      6. }
      7. else
      8. {
      9. hr = m_pIMMEnumerator->GetDevice(strEndPointID.c_s(),&pIMMDeivce);
      10. }
      獲取pIMMDeivce對象后,就可以用這個對象接口激活自己想要控制的相應音量設備的接口了,先看下IMMDevice接口擁有屬于自己的方法:
      1. class IMMDevice : public IUnknown
      2. {
      3. public:
      4. virtual HRESULT STDMETHODCALLTYPE Activate(REFIID iid, DWORD dwClsCtx, PROPVARIANT *pActivationParams, void **ppInterface) = 0;
      5. virtual HRESULT STDMETHODCALLTYPE OpenPropertyStore(DWORD stgmAccess,IPropertyStore **ppProperties) = 0;
      6. virtual HRESULT STDMETHODCALLTYPE GetId(LPWSTR *ppstrId) = 0;
      7. virtual HRESULT STDMETHODCALLTYPE GetState(DWORD *pdwState) = 0;
      8. };
      簡單注釋下這個幾個函數(shù)意義:
      1. //激活這個設備下指定接口的COM對象;
      2. //iid:指定獲取接口的GUID;
      3. //dwClsCtx:執(zhí)行上下文,一般指定CLSCTX_ALL獲取所有信息;
      4. //pActivationParams:對于IID_IAudioEndpointVolume接口設置為NULL。
      5. //ppInterface:需要接收獲取設備對象二重指針;
      6. HRESULT Activate(REFIID iid, DWORD dwClsCtx, PROPVARIANT *pActivationParams, void **ppInterface)
      7. //打開一個設備的屬性存儲接口;
      8. HRESULT OpenPropertyStore(DWORD stgmAccess,IPropertyStore **ppProperties)
      9. //獲取設備ID;
      10. HRESULT GetId(LPWSTR *ppstrId)
      11. //獲取設備狀態(tài)信息; 
      12. HRESULT GetState(DWORD *pdwState)  
      我們主要用的是Activate()方法,首先我們獲取揚聲器音量控制接口m_pRenderEndptVol,如下
      1. //主聲音設備
      2. hr = pIMMDeivce->Activate(IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, (void**)&m_pRenderEndptVol);
      獲取到m_pRenderEndptVol接口后我們就可以用這個接口設置系統(tǒng)揚聲器音量了。
      5.設置系統(tǒng)揚聲器音量,也就是主音量,先看看剛剛我們獲取m_pRenderEndptVol接口擁有屬于自己的方法:
      1. class IAudioEndpointVolume : public IUnknown
      2. {
      3. public:
      4. virtual HRESULT STDMETHODCALLTYPE RegisterControlChangeNotify(IAudioEndpointVolumeCallback *pNotify) = 0;
      5. virtual HRESULT STDMETHODCALLTYPE UnregisterControlChangeNotify(IAudioEndpointVolumeCallback *pNotify) = 0;
      6. virtual HRESULT STDMETHODCALLTYPE GetChannelCount(UINT *pnChannelCount) = 0;
      7. virtual HRESULT STDMETHODCALLTYPE SetMasterVolumeLevel(float fLevelDB,LPCGUID pguidEventContext) = 0;
      8. virtual HRESULT STDMETHODCALLTYPE SetMasterVolumeLevelScalar(float fLevel,LPCGUID pguidEventContext) = 0;
      9. virtual HRESULT STDMETHODCALLTYPE GetMasterVolumeLevel(float *pfLevelDB) = 0;
      10. virtual HRESULT STDMETHODCALLTYPE GetMasterVolumeLevelScalar(float *pfLevel) = 0;
      11. virtual HRESULT STDMETHODCALLTYPE SetChannelVolumeLevel(UINT nChannel,float fLevelDB,LPCGUID pguidEventContext) = 0;
      12. virtual HRESULT STDMETHODCALLTYPE SetChannelVolumeLevelScalar(UINT nChannel,float fLevel,LPCGUID pguidEventContext) = 0;
      13. virtual HRESULT STDMETHODCALLTYPE GetChannelVolumeLevel(UINT nChannel,float *pfLevelDB) = 0;
      14. virtual HRESULT STDMETHODCALLTYPE GetChannelVolumeLevelScalar(UINT nChannel,float *pfLevel) = 0;
      15. virtual HRESULT STDMETHODCALLTYPE SetMute(BOOL bMute,LPCGUID pguidEventContext) = 0;
      16. virtual HRESULT STDMETHODCALLTYPE GetMute(BOOL *pbMute) = 0;
      17. virtual HRESULT STDMETHODCALLTYPE GetVolumeStepInfo(UINT *pnStep,UINT *pnStepCount) = 0;
      18. virtual HRESULT STDMETHODCALLTYPE VolumeStepUp(LPCGUID pguidEventContext) = 0;
      19. virtual HRESULT STDMETHODCALLTYPE VolumeStepDown(LPCGUID pguidEventContext) = 0;
      20. virtual HRESULT STDMETHODCALLTYPE QueryHardwareSupport(DWORD *pdwHardwareSupportMask) = 0;
      21. virtual HRESULT STDMETHODCALLTYPE GetVolumeRange(float *pflVolumeMindB,float *pflVolumeMaxdB,float *pflVolumeIncrementdB) = 0;
      22. };
      這個IAudioEndpointVolume接口方法很多,不仔細介紹每一個了,只介紹我們需要用到的幾個方法,大家可以根據(jù)自己的需要,顧名思義找到自己需要用的方法。
      1. /*
      2. 設置音頻終端的主音量電;
      3. fLevel:主音量數(shù)值級別,這個值范圍在0到1之間;
      4. pguidEventContext):此參數(shù)指向一個事件上下文的GUID,如果SetMasterVolumeLevelScalar調(diào)用更改端點的音量,所有已注冊客戶IAudioEndpointVolumeCallback接口與端點將接收通知。
      5. */
      6. HRESULT SetMasterVolumeLevelScalar(float fLevel,LPCGUID pguidEventContext);
      7. //獲取音頻終端的主音量電平;
      8. HRESULT GetMasterVolumeLevelScalar(float *pfLevel);
      9. //設置音頻終端是否為靜音狀態(tài);
      10. HRESULT SetMute(BOOL bMute,LPCGUID pguidEventContext);
      11. //獲取音頻終端是靜音狀態(tài);
      12. HRESULT GetMute(BOOL *pbMute);
      其余幾個參數(shù)很簡單,看名字就知道什么意思,不作過多介紹。

      設置系統(tǒng)揚聲器音量代碼示例:

      1. float level = 0.5f;//這個值可以跟進相應比例換算所得
      2. hr = m_pRenderEndptVol->SetMasterVolumeLevelScalar(level, NULL);
      獲取系統(tǒng)揚聲器音量代碼示例:
      1. float level = 0.0f;
      2. hr = m_pRenderEndptVol->GetMasterVolumeLevelScalar(&level);
      注意level這個值一般根據(jù)界面滑動條最大值按比例換算所得。
      設置系統(tǒng)揚聲器靜音示例:
      hr = m_pRenderSimpleVol->SetMute(TRUE, NULL);

      獲取系統(tǒng)揚聲器靜音狀態(tài)示例: 

      1. BOOL bMute = 0;
      2. hr = m_pRenderSimpleVol->GetMute(&bMute);
      這只是簡單的幾種參數(shù)設置,大家可以根據(jù)自己的需要來選擇不同方法達到自己目的。

      6.設置應用程序會話音量
              上面設置的都是系統(tǒng)揚聲器的音量,即相應的設置會影響系統(tǒng)上所有軟件的音量,下面我們來設置屬于應用程序本身的會話音量,所謂會話音量即時這個應用程序本身的音量,設置會話音量的大小只會影響應用程序本身的音量大小,不會影響系統(tǒng)其它程序音量的大小。首先我們要獲取IAudioSessionManager接口對象,方法是通過已經(jīng)獲取IMMDevice接口對象來激活IAudioSessionManager接口對象,然后就可以通過IAudioSessionManager接口來獲取ISimpleAudioVolume接口對象了,最后通過ISimpleAudioVolume接口對象就可以操作會話音量的大小了。示例代碼如下:

      1. //合成器界面
      2. CComPtr<IAudioSessionManager> pSessionManager = NULL;
      3. hr = pIMMDeivce->Activate(IID_IAudioSessionManager, CLSCTX_INPROC_SERVER, NULL, (void **)(&pSessionManager));
      4. if(FAILED(hr)) return;
      5. hr = pSessionManager->GetSimpleAudioVolume(NULL, FALSE, &m_pRenderSimpleVol);

      獲取到ISimpleAudioVolume接口對象后就可以使用其具有的方法操作具體的功能了,看下這個接口有的方法:

      1. class ISimpleAudioVolume : public IUnknown
      2. {
      3. public:
      4. virtual HRESULT STDMETHODCALLTYPE SetMasterVolume(float fLevel, LPCGUID EventContext) = 0;
      5. virtual HRESULT STDMETHODCALLTYPE GetMasterVolume(float *pfLevel) = 0;
      6. virtual HRESULT STDMETHODCALLTYPE SetMute(const BOOL bMute, LPCGUID EventContext) = 0;
      7. virtual HRESULT STDMETHODCALLTYPE GetMute(BOOL *pbMute) = 0;
      8. };
      所有方法和上面IAudioEndpointVolume接口方法基本一樣,直接貼代碼說明
      設置和獲取會話音量的大?。?pre>
      1. //設置揚聲器會話音量大小
      2. float fVol = 0.5f;
      3. hr = m_pRenderSimpleVol->SetMasterVolume(fVol, NULL);
      4. //獲取揚聲器會話音量大小
      5. float fVol = 0.0f;
      6. hr = m_pRenderSimpleVol->GetMasterVolume(&fVol);
      設置和獲取會話音量的靜音狀態(tài):
      1. //設置揚聲器會話音量靜音狀態(tài)
      2. BOOL bMute = TRUE;
      3. hr = m_pRenderSimpleVol->SetMute(bMute , NULL);
      4. //獲取揚聲器靜音狀態(tài)
      5. hr = m_pRenderSimpleVol->GetMute(&bMute);
              揚聲器里面的功能設置還有很多方法,介紹只是最基本的方法,大家可以根據(jù)自己需要挖掘更深層的設置方法,這一節(jié)就先介紹到這里吧,下一節(jié)介紹系統(tǒng)麥克風方面一些簡單的設置。                                      

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多