(二)獲取CODECs 的 信 息
ACM 的API 函 數 定 義 在 頭 文 件msacm.h 中, 除 此 之 外, 對ACM 編 程 還 必 須 包 含 頭 文 件mmsystem.h,mmreg.h, 這 兩 個 頭 文 件 定 義 了 多 媒 體 編 程 中 最 基 本 的 常 量 和 數 據 結 構;
1.ACM版本信息:為 了 避 免 有 些 高 版 本ACM 才 提 供 的 函 數 和 功 能 在 較 低 版 本 的ACM 中 上 不 可 用, 程 序 中 應 調 用acmGetVersion 函 數 查 詢 用 戶 機 器 中ACM 的 版 本 信 息;
2.查看系統CODECs信息:在 控 制 面 板 中 可 以 查 看 系 統 中CODECs 的 信 息, 而 在 應 用 程 序 中 也 常 常 需 要 知 道 某 種 音 頻CODECs 是 否 存 在, 并 獲 取 其 編 解 碼 參 數 等 信 息, 這 一 點 可 以 通 過 調 用 下 面 兩 個 函 數 來 實 現。
MMRESULT mmr = acmMetrics(NULL, ACM_METRIC_COUNT_CODECS, &dwCodecs);
mmr = acmDriverEnum(CodecsEnumProc, 0, 0);
acmMetrics函數可以獲取許多ACM對象的有用信息,例如向其中傳遞ACM_METRIC_COUNT_CODECS可以查詢系統中安裝的音頻CODECs總數;傳遞ACM_METRIC_MAX_SIZE_FORMAT獲取GSM6.10格式Format Chunk的附加數據長度;
acmDriverEnum函數的功能是枚舉所有的音頻CODECs,在acmDriverEnum() 的參數中指定回調函數CodecsEnumProc()可以進一步查詢每個CODEC的信息;
BOOL CALLBACK CodecsEnumProc(HACMDRIVERID hadid, DWORD dwInstance, DWORD fdwSupport)
{
DWORD dwSize = 0;
if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC)
printf("多格式轉換\n");
ACMDRIVERDETAILS add;
acmdd.cbStruct = sizeof(acmdd);
MMRESULT mmr = acmDriverDetails(hadid, &acmdd, 0);
if (mmr)
error_msg(mmr);
else
{
printf(" 全稱: %s\n", acmdd.szLongName);
printf(" 描述: %s\n", acmdd.szFeatures);
}
HACMDRIVER had = NULL;
mmr = acmDriverOpen(&had, hadid, 0); //打開驅動程序
if (mmr)
error_msg(mmr);
else
{
mmr = acmMetrics(had, ACM_METRIC_ MAX_SIZE_FORMAT, &dwSize);
WAVEFORMATEX* pwf = (WAVEFORMATEX*) malloc(dwSize);
memset(pwf, 0, dwSize);
pwf->cbSize = LOWORD(dwSize) - sizeof(WAVEFORMATEX);
pwf->wFormatTag = WAVE_FORMAT_UNKNOWN;
ACMFORMATDETAILS fd;
memset(&fd, 0, sizeof(fd));
fd.cbStruct = sizeof(fd);
fd.pwfx = pwf;
fd.cbwfx = dwSize;
fd.dwFormatTag = WAVE_FORMAT_UNKNOWN;
mmr = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0);
if (mmr)
error_msg(mmr);
free(pwf);
acmDriverClose(had, 0);
}
return TRUE;
}
CodecsEnumProc()共有三個參 數。 第 一 個 參 數 是 驅 動 程 序 的ID 值; 第 二 個 參 數 是 實 例 數 據, 本 文 例 子 中 未 使 用; 第 三 個 參 數 描 述 該 驅 動 程 序 所 支 持 的 功 能, 它 由 一 組 標 識 進 行 或 運 算 構 成, 例 如, 如 果 設 置 了 標 識ACMDRIVERDETAILS_SUPPORTF_CODEC, 則 說 明 該 驅 動 程 序 可 以 將 一 種 編 碼 格 式 的 音 頻 信 號 轉 換 成 另 一 種 編 碼 格 式。 通 過acmDriverDetails() 函 數 可 以 獲 得 對 該 驅 動 程 序 進 一 步 的 信 息, 如CODEC 的 名 稱、 簡 單 描 述 等。 以 上 信 息 實 際 上 是 由ACM 收 集, 并 保 存 在ACM 內 部, 所 以 查 詢 以 上 信 息 時 并 未 真 正 將 驅 動 程 序 加 載 至 內 存。 而 要 獲 得 每 一 種 驅 動 程 序 支 持 的 音 頻 格 式 信 息, 則 必 須 將 驅 動 程 序 加 載 至 內 存, 這 是 通 過acmDriverOpen() 完 成 的, 在 退 出CodecsEnumProc() 前, 還 要 用acmDriverClose() 來 關 閉 已 打 開 的 驅 動 程 序。
在 使 用 音 頻 格 式 枚 舉 函 數 前, 需 要 先 分 配 一 塊 緩 沖 區 存 置 格 式 信 息, 緩 沖 區 的 大 小 可 通 過 調 用acmMetrics() 查 詢ACM_METRIC_MAX_SIZE_FORMAT 獲 得, 格 式 信 息 中 的 音 頻 格 式 標 識 設 為WAVE_FORMAT_UNKNOWN。 在 音 頻 格 式 枚 舉 中 同 樣 使 用 了 回 調 函 數, 此 回 調 函 數 只 是 列 出 了 該 音 頻 格 式 的 名 稱 和 標 識 值。
BOOL CALLBACK FormatEnumProc (HACMDRIVERID hadid, LPACMFORMATDETAILS pafd, DWORD dwInstance, DWORD fdwSupport) { printf("%4.4lXH, %s\n", pafd- >dwFormatTag, pafd- >szFormat); return TRUE; }
上 面 介 紹 了 瀏 覽 系 統 中 所 有 音 頻CODECs 及 每 種CODEC 所 支 持 的 音 頻 格 式 的 方 法, 某 些 典 型 的 應 用 程 序 可 能 需 要 列 出 系 統 中 所 有 可 以 選 用 的CODECs, 并 由 用 戶 來 選 擇 使 用 哪 一 種CODEC 進 行 壓 縮, 此 時 就 需 要 利 用 上 面 的 編 程 方 法 來 獲 取CODECs 的 信 息。
浙公網安備 33010602011771號