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;
    }

  • 相关阅读:
    部署基于.netcore5.0的ABP框架后台Api服务端,以及使用Nginx部署Vue+Element前端应用
    20年就GPT3+ AlphaFold——21年机器学习的风向
    自由软件的真正意义——要么用户控制程序,要么程序控制用户。如果程序控制了用户,开发者控制了程序,那么程序就是一种不公正的权力工具。
    SSL代理——见图,利用SSL代理证书替换加密Web网站的数字证书,并将SSL代理证书发送到客户端的Web浏览器,中间代理以此获得加密通信的明文内容进行和真实服务器的交互转发
    深度森林gcForest模型
    网络安全相关证书有哪些?——就实战型看,OSCP、CISP-PTE (国家注册渗透测试工程师)最好
    CISP-PTE 注册渗透测试工程师考试 总结&&经验分享——TODO 待参加考试
    SLS机器学习最佳实战:日志聚类+异常告警 —— 这个就是splunk SQL+机器学习结合产物啊
    linux修改文件或目录的所有者(chown)和用户组
    linux修改用户id,组id
  • 原文地址:https://www.cnblogs.com/drgraph/p/8080383.html
Copyright © 2011-2022 走看看