DirectSound---輸出設備基本操作(枚舉、查詢等)

来源:https://www.cnblogs.com/lgxZJ/archive/2018/01/13/8279193.html
-Advertisement-
Play Games

DirectSound是DirectX組件之一,提供了對音頻設備的捕獲和播放能力,同時它也是唯一幾個支持Xp系統的音頻技術之一。 DirectSound主要有以下特點: 優點: 播放音頻 低延遲 。 硬體資源控制 。 同時 播放 多個 聲音。 控制硬體緩衝區的使用 優先順序 (DirectSound使 ...


DirectSound是DirectX組件之一,提供了對音頻設備的捕獲和播放能力,同時它也是唯一幾個支持Xp系統的音頻技術之一。 DirectSound主要有以下特點:

優點:

  • 播放音頻低延遲
  • 硬體資源控制
  • 同時播放多個聲音。
  • 控制硬體緩衝區的使用優先順序(DirectSound使用緩衝區來播放音頻)。
  • 模擬3D音頻環境。
  • 動態更改音效(回聲、和聲等)。
  • 捕獲音頻輸入設備聲音位wav(多為PCM數據,未經壓縮)。

缺點:

  • 只能播放wav音頻文件。

這裡我們說說設備操作這一塊兒。

1. 輸出設備操作

在DirectSound中,一個設備對象就代表一個音頻設備,播放設備對象對應播放設備,輸入設備對象對應輸入設備。因為DirectSound使用COM協議,因此每個設備對象都用介面來表示。這裡IDirectSound8這個介面就代表了一個輸出設備對象,應用程式可以對同一個音頻設備創建多個設備對象來進行音頻輸出操作。舊版本的DirectSound使用的是IDirectSound介面,相比前者少了一些功能。

1.1 枚舉

HRESULT WINAPI DirectSoundEnumerateW(In LPDSENUMCALLBACKW pDSEnumCallback, In_opt LPVOID pContext);
typedef BOOL (CALLBACK *LPDSENUMCALLBACKW)(LPGUID, LPCWSTR, LPCWSTR, LPVOID);

我們通過DirectSoundEnumerateW這個函數來枚舉,該函數需要傳入一個回調函數(原型見上),當枚舉到一個設備時該回調會被調用。如果我們想繼續枚舉,需要在這個回調用中返回TRUE來告訴系統,否則返回FALSE。另一個參數pContext允許用戶傳入額外的參數,傳入回調函數的最後一個實參就是這個pContext。枚舉時,DirectSound會將預設也認作一個單獨的設備來對待,因此預設設備會被重覆枚舉一次。當設備被作為預設設備枚舉時,它的GUID和設備描述字元串都為空,需要小心處理,這裡我直接跳過了該次枚舉:

if (DirectSoundEnumerateW(enumerateCallback, nullptr) != DS_OK) {
    ...
}

BOOL CALLBACK DirectSoundBasic::enumerateCallback(LPGUID guid,
                                              LPCWSTR deviceDescription,
                                              LPCWSTR deviceDriverModule,
                                              LPVOID context)
{
    Q_UNUSED(context);

    //  if primary device, skip it
    if (guid == nullptr)        return TRUE;

    ...
}

1.2 創建設備對象

HRESULT WINAPI DirectSoundCreate8(In_opt LPCGUID pcGuidDevice, Outptr LPDIRECTSOUND8 *ppDS8, Pre_null LPUNKNOWN pUnkOuter);

調用DirectSoundCreate8函數,我們可以創建一個設備對象,通過傳入一個枚舉設備時獲得的GUID,函數會返給我們一個IDirectSound8介面代表設備對象:

IDirectSound8* directSound8;
if (DirectSoundCreate8(guid, &directSound8, NULL) != DS_OK) {
    std::wcout << L"[error] DirectSoundCreate8 call error!";
    return TRUE;    //  if error, skip this device
}

1.3 設置設備對象優先順序

HRESULT IDirectSound8::SetCooperativeLevel(HWND hwnd, DWORD dwLevel)

在使用設備對象創建緩衝區(用來捕獲、播放音頻)之前,我們需要設置設備對象的協作級別。這個協作級別相當於用戶對設備進行操作的優先順序,分為:

  • DSSCL_EXCLUSIVE: 互斥級別。對於DirectX8.0以前版本,僅播放當前應用的音頻數據,其他應用的聲音不會被播放;對於DirectX8.0級以後版本,同DSSCL_PRIORITY版本。

  • DSSCL_NORMAL: 普通級別,這種級別下的應用程式具有最平滑的多任務和資源共用表現,但是這種應用不能更改主緩衝區音頻數據格式,輸出音頻格式被限製為8位數據。在DirectSound中,次緩衝區用來填充應用程式需要播放的聲音,主緩衝區會對多個次緩衝區(可能是本應用的,也可能是其他應用的)進行混音,然後用音效卡輸出播放。
  • DSSCL_PRIORITY: 優先順序別,可以更改主緩衝區數據格式。
  • DSSCL_WRITEPRIMARY:寫主緩衝區級別,應用可以直接寫入主緩衝區,此時所有次緩衝區不會被播放(如果設備的驅動是DirectSound模擬出來的,則不能設置該級別)。

註意該函數需要傳入一個視窗句柄,因為我們今天只介紹DirectSound的基本操作,我直接傳入桌面視窗的句柄並設定位DSSCL_NORMAL優先順序:

if (directSound8->SetCooperativeLevel(GetDesktopWindow(), DSSCL_NORMAL) != DS_OK) {
    std::wcout << L"[error] SetCooperativeLevel call error!";
    return TRUE;
}

1.4 設備能力

HRESULT IDirectSound8::GetCaps(LPDSCAPS pDSCaps)

不同的音頻播放設備具有不同的能力,DirectSound允許我們查詢設備的能力:

  • 是否經過Microsoft認證。
  • 知否支持最小最大採樣率之間的所有採樣率。
  • 當沒有DirectSound驅動時模擬驅動。
  • 主次緩衝區格式(16位、8位)。
  • 主次緩衝區聲道支持(單聲道、立體聲即多聲道)。
  • 不精準的數據(某些音效卡不支持):
    • 緩衝區(靜態緩衝區、流緩衝區、3D緩衝區)最大數、空閑數。
    • 音效卡上的總記憶體數量、空閑記憶體數量、最大空閑塊大小,

我們傳給GetCaps一個DSCAPS結構體地址,然後系統就幫我們填充相應的數據,調用GetCaps前需要將DSCAPS結構體的dwSize設置為DSCAPS的大小:

DSCAPS deviceCapability = { sizeof(deviceCapability) };
if (directSound8->GetCaps(&deviceCapability) != DS_OK) {
    std::wcout << L"[error] GetCaps call error!";
    return TRUE;
}

1.5 播放器配置

HRESULT IDirectSound8::GetSpeakerConfig(LPDWORD pdwSpeakerConfig)
HRESULT IDirectSound8::SetSpeakerConfig(LPDWORD pdwSpeakerConfig)

播放器配置只能是以下之一:

  • DSSPEAKER_5POINT1_SURROUNDDSSPEAKER_5POINT1_BACK: 家庭影院配置,5個環繞揚聲器,1個低音炮。
  • DSSPEAKER_DIRECTOUT:直接播放。
  • DSSPEAKER_HEADPHONE:頭戴式耳機。
  • DSSPEAKER_MONO:單聲道揚聲器。
  • DSSPEAKER_QUAD:4聲道播放器。
  • DSSPEAKER_STEREO:立體聲播放器。
  • DSSPEAKER_SURROUND:環繞播放器。
  • DSSPEAKER_7POINT1_WIDEDSSPEAKER_7POINT1_SURROUND:家庭影院配置,7個環繞揚聲器,1個低音炮。

雖然MSDN文檔沒有寫清楚,但是通過查以上巨集定義我們發現它們是按大小順序定義的,因此不可能通過OR|來包含多種可能,例子中如果調用出錯直接返回TRUE表示我們繼續枚舉設備並繼續查詢那些設備能力:

DWORD deviceSpeakerConfiguration;
if (directSound8->GetSpeakerConfig(&deviceSpeakerConfiguration) != DS_OK) {
    std::wcout << L"[error] GetSpeakerConfig call error!";
    return TRUE;
}

2. 運行結果

這次我們用GUI界面來顯示實例運行的結果(出於方便考慮,以後我會用控制台來顯示示例),為防止用戶誤操作更改顯示的數據我將大部分控制項都disable了:

result-img

完整代碼見鏈接


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 目前開發的所有代碼都已經上傳到了GitHub。歡迎大家來Star https://github.com/GiantLiu/AutoJump 目前程式分為“全自動版本”和“半自動版本” 全自動版本 WeChat.AutoJump.CMDApp 當手機連接好後,打開微信跳一跳 點擊"開始游戲"後。運行此 ...
  • 【轉】最近用Timer踩了一個坑,分享一下避免別人繼續踩 最近做一個小項目,項目中有一個定時服務,需要向對方定時發送數據,時間間隔是1.5s,然後就想到了用C#的Timer類,我們知道Timer 確實非常好用,因為裡面有非常人性化的start和stop功能,在Timer裡面還有一個Interval, ...
  • 一. 準備工作 1. 點擊此訪問 RestSharp 官網,可作參考 2. VS2012 中安裝支持.Net4.0的最新版 RestSharp 插件 工具 NuGet程式包管理器 程式包管理器控制台,輸入如下命令 二. 相關代碼介紹 1. 消費REST服務方法,以Json作為數據格式 /// <su ...
  • mac install m2Crypto === error solution ...
  • 其實現在網路上supervisor的教程有很多,比較雜,我找了幾個對我來說是有幫助的教程,再結合自己的理解做一些筆記,可以供自己以後翻看。 鏈接:https://www.cnblogs.com/Hai--D/p/5820718.html http://blog.csdn.net/xyang81/ar ...
  • 先占位置,以後補充 ...
  • 預留位置,以後補充 ...
  • 本文介紹在RedHat7環境下安裝使用PostGIS的流程。 1. PostgreSQL 1.1 yum安裝PostgreSQL 這個比較簡單,直接使用yum安裝即可。 順便安裝postgresql devel、libxml2 devel,後邊編譯安裝PostGIS會用到。 然後切換到postgre ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...