zoukankan      html  css  js  c++  java
  • 基于OpenCV的视频图像组态 (14):音量控制

    实现代码

    播放软件,慢慢地有了声音控制的需求,在网上找了一下,用Core Audio APIS 音频应用开发即可。入门稍慢,不过用起来很简单。整理了一个类供调用。

    class TCbwAudioEndpointVolumeCallback;

    typedef void __fastcall (__closure * TOnVoiceNotifyEvent)(bool bMuted, int fMasterVolume);

    class TCbwVolumeControl {

    private:

        TCbwAudioEndpointVolumeCallback * EPVolEvents;

        TOnVoiceNotifyEvent FOnVoiceNotify;

        bool FValid;

        bool __fastcall HRStatus(HRESULT hr, UnicodeString info);

        void __fastcall Prework();

        void __fastcall AfterWork();

        int __fastcall GetMasterVolume();

        void __fastcall SetMasterVolume(int value);

        bool __fastcall GetMuted();

        void __fastcall SetMuted(bool value);

    public:

        __fastcall TCbwVolumeControl();

        __fastcall ~TCbwVolumeControl();

        __property bool IsValid = { read = FValid };

        __property int MasterVolume = { read = GetMasterVolume, write = SetMasterVolume };

        __property bool Muted = { read = GetMuted, write = SetMuted };

        __property TOnVoiceNotifyEvent OnVoiceNotify = { read = FOnVoiceNotify, write = FOnVoiceNotify };

        void __fastcall OnNotifyFromCallback(bool bMuted, float fMasterVolume);

    };

    extern TCbwVolumeControl * GlobalVolumeControl;

    TCbwVolumeControl * GlobalVolumeControl = NULL;

    IMMDeviceEnumerator *pEnumerator = NULL;

    IMMDevice *pDevice = NULL;

    IAudioEndpointVolume *g_pEndptVol = NULL;

    #define SAFE_RELEASE(punk)

    if ((punk) != NULL)

    { (punk)->Release(); (punk) = NULL; }

    #define EXIT_ON_ERROR(hr)

    if (FAILED(hr)) return;

    __fastcall TCbwVolumeControl::TCbwVolumeControl() {

        EPVolEvents = new TCbwAudioEndpointVolumeCallback;

        FOnVoiceNotify = NULL;

        EPVolEvents->ParentControl = this;

        Prework();

    }

    __fastcall TCbwVolumeControl::~TCbwVolumeControl() {

        AfterWork();

        delete EPVolEvents;

    }

    bool __fastcall TCbwVolumeControl::HRStatus(HRESULT hr, UnicodeString info) {

        if (FAILED(hr)) {

            DRGRAPH_DEBUG(THelper::FormatString(L"CALL %s FAILED!", info));

            return false;

        }

        return true;

    }

    void __fastcall TCbwVolumeControl::Prework() {

        FValid = false;

        pEnumerator = NULL;

        pDevice = NULL;

        g_pEndptVol = NULL;

        GUID g_guidMyContext = GUID_NULL;

        CoInitialize(NULL);

        if (HRStatus(CoCreateGuid(&g_guidMyContext),

            L"CoCreateGuid(&g_guidMyContext)"))

            if (HRStatus(CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,

                CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator),

                (void**)&pEnumerator), L"CoCreateInstance"))

                if (HRStatus(pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole,

                    &pDevice), L"pEnumerator->GetDefaultAudioEndpoint"))

                    if (HRStatus(pDevice->Activate(__uuidof(IAudioEndpointVolume),

                        CLSCTX_ALL, NULL, (void**)&g_pEndptVol),

                        L"pDevice->Activate"))

                        if (HRStatus(g_pEndptVol->RegisterControlChangeNotify

                            ((IAudioEndpointVolumeCallback*)EPVolEvents),

                            L"g_pEndptVol->RegisterControlChangeNotify"))

                            FValid = true;

    }

    void __fastcall TCbwVolumeControl::AfterWork() {

        if (pEnumerator != NULL) {

            HRStatus(g_pEndptVol->UnregisterControlChangeNotify

                ((IAudioEndpointVolumeCallback*) EPVolEvents),

                L"g_pEndptVol->UnregisterControlChangeNotify");

        }

        SAFE_RELEASE(pEnumerator);

        SAFE_RELEASE(pDevice);

        SAFE_RELEASE(g_pEndptVol);

        CoUninitialize();

    }

    int __fastcall TCbwVolumeControl::GetMasterVolume() {

        float pfLevel = 0;

        HRStatus(g_pEndptVol->GetMasterVolumeLevelScalar(&pfLevel),

            L"g_pEndptVol->GetMasterVolumeLevel");

        return pfLevel * 100 + 0.5;

    }

    void __fastcall TCbwVolumeControl::SetMasterVolume(int value) {

        float fVolume = value / 100.0;

        HRStatus(g_pEndptVol->SetMasterVolumeLevelScalar(fVolume,

            &GUID_NULL), L"pAudioEndpointVolume->SetMasterVolumeLevelScalar");

    }

    void __fastcall TCbwVolumeControl::OnNotifyFromCallback(bool bMuted,

        float fMasterVolume) {

        if (FOnVoiceNotify)

            FOnVoiceNotify(bMuted, fMasterVolume * 100 + 0.5);

    }

    bool __fastcall TCbwVolumeControl::GetMuted() {

        int muted = false;

        g_pEndptVol->GetMute(&muted);

        return muted;

    }

    void __fastcall TCbwVolumeControl::SetMuted(bool value) {

        HRStatus(g_pEndptVol->SetMute(value,

            &GUID_NULL), L"pAudioEndpointVolume->SetMute");

    }

    演示效果

    简单做了一个测试界面。


    void __fastcall TMainForm::OnVoiceNotify(bool bMuted, int fMasterVolume) {
        Button_Mute->EditValue = bMuted;
        Button_Volume->EditValue = fMasterVolume;
    }

    void __fastcall TMainForm::Button_MutePropertiesEditValueChanged(TObject *Sender) {
        bool muted = Button_Mute->CurEditValue;
        int volume = Button_Volume->CurEditValue;
        ShowStatus(THelper::FormatString(L"%d, %s", volume, muted ? L"Muted" : L"Sound"));
        FVolumeControl->MasterVolume = volume;
        FVolumeControl->Muted = muted;
    }

  • 相关阅读:
    error:undefined reference to 'net_message_processor::net_message_processor()'
    android 网络检测
    eclipse 安装 ndk 组件
    eclipse下编译cocos2dx 3.0
    Cocos2dx3.0 TextField 输入中文的问题
    记录与骗子进行的一次交锋. 与技术无关
    关于继承的设计
    kubernetes1.5.2--部署dashboard服务
    kubernetes1.5.2--部署DNS服务
    kubernetes1.5.2集群部署过程--安全模式
  • 原文地址:https://www.cnblogs.com/drgraph/p/8080383.html
Copyright © 2011-2022 走看看