開發多媒體應用時,音量控制是不可或缺的功能。Windows 提供的 mixer API 雖功能強大,但介面繁雜、錯誤處理繁瑣。本文介紹一個封裝良好的 C++ 音量控制類別,提供直觀的公用介面、支援主/波形輸出與輸入線路,並內建回調通知機制,讓開發者專注於業務邏輯而非底層細節。
| 方法 | 回傳/參數 | 功能說明 |
|---|---|---|
IsAvailable() | BOOL | 檢查系統是否支援音量控制 |
Enable() / Disable() | void | 啟用/停用指定音量線路 |
GetVolumeMetric() | DWORD | 取得音量調整粒度(最小調整單位) |
GetMinimalVolume() | DWORD | 取得最小音量值 |
GetMaximalVolume() | DWORD | 取得最大音量值 |
GetCurrentVolume() | DWORD | 取得目前音量值 |
SetCurrentVolume(DWORD) | void | 設定音量(自動裁剪至合法範圍) |
RegisterNotificationSink(callback, DWORD) | void | 註冊音量變更回調函式 |
classDiagram
class IVolume { <<interface>> }
class VolumeOutMaster
class VolumeOutWave
class VolumeInBase
IVolume <|-- VolumeOutMaster
IVolume <|-- VolumeOutWave
IVolume <|-- VolumeInBase
VolumeOutMaster : +Master Volume 控制
VolumeOutWave : +Wave 輸出音量控制
VolumeInBase : +錄音/輸入音量控制
實際專案包含 VolumeOutMaster.h/.cpp、VolumeOutWave.h/.cpp 以及多個 VolumeInXXX.h/.cpp(對應不同輸入來源),皆繼承自統一介面,確保一致的操作體驗。
當使用者透過系統音量控制面板、鍵盤熱鍵或其他應用程式調整音量時,註冊的回調函式將被觸發:
// 回調函式原型
typedef void (CALLBACK *PONMICVOLUMECHANGE)(DWORD dwLineID, DWORD dwNewVolume, DWORD dwUserData);
// 註冊範例
void OnMyVolumeChange(DWORD dwLineID, DWORD dwNewVolume, DWORD dwUserData) {
CSliderCtrl* pSlider = (CSliderCtrl*)dwUserData;
pSlider->SetPos((int)dwNewVolume); // 同步 UI 滑桿
}
// 使用
m_volumeCtrl.RegisterNotificationSink(OnMyVolumeChange, (DWORD)&m_sliderCtrl);
此機制採用 Windows Mixer 的 MM_MIXM_CONTROL_CHANGE 訊息,內部以獨立執行緒監聽,不阻塞主 UI 執行緒。
#include "IVolume.h"
#include "VolumeOutWave.h" // 控制 Wave 輸出音量
CVolumeOutWave waveVol;
if (waveVol.IsAvailable()) {
waveVol.Enable();
DWORD curr = waveVol.GetCurrentVolume();
DWORD maxV = waveVol.GetMaximalVolume();
// 設為 50%
waveVol.SetCurrentVolume(maxV / 2);
// 註冊回調同步滑桿
waveVol.RegisterNotificationSink(MyVolCallback, (DWORD)&m_slider);
}
// 程式結束前
waveVol.Disable();
IVolume.h、VolumeOutMaster.h、VolumeOutWave.h、VolumeIn*.h.cpp 檔案winmm.lib,並包含 mmsystem.h此類別庫將龐雜的 Mixer API 封裝為語意清晰、型別安全的 C++ 介面,並提供回調機制解決跨元件同步難題。無論是簡單的音量滑桿,或是完整的混音器控制面板,皆可作為堅實基礎。原始碼壓縮包內附詳細使用說明與範例專案,建議下載參考。