Sound関数

適用:

Other sound-related functions:

Endpoint Devices

SoundGet関数とSoundSet関数が参照する "デバイス"は、オーディオエンドポイントデバイスである。1つのデバイスドライバや物理デバイスが、異なるタイプの出力や入力など、複数のエンドポイントを持つことはよくある。事例:

名前説明
Speakers (Example HD Audio)本機の主なアナログ出力端子(サラウンド・サウンドの場合は複数の端子を使用)。
デジタル出力(HDオーディオの例)光または同軸デジタル出力。
マイク(HDオーディオの例)マイク端子から音声を取り込む。
ステレオ・ミックス(HDオーディオの例)Speakersエンドポイントに出力されている音声をキャプチャする。

デバイス名は通常、"Speakers"のようなエンドポイント名と、括弧内のオーディオドライバ名で構成される。スクリプトは、完全な名前を使用することも、"Mic"や "Microphone"のように名前の先頭部分だけを使用することもできる。オーディオドライバの名前は固定されていますが、エンドポイント名は管理者がサウンドコントロールパネルからいつでも変更することができます。

デバイスはサウンドコントロールパネルに一覧表示され、コマンドラインから mmsys.cpl を実行するか、ファイル名を指定して実行ダイアログ(Win+R)または Run 機能で開くことができます。デフォルトでは、コントロールパネルは有効でプラグインされているデバイス(該当する場合)のみをリストアップしますが、これは右クリックメニューで変更できます。AutoHotkeyは、プラグインされていないデバイスは検出しますが、無効になっているデバイスは検出しません。

コンポーネント

コンポーネントは、サウンドデバイスのプロパティダイアログのLevelsタブに表示されている通りです。

Levels

この例では、マスターコントロールが一番上にあり、その後に最初の4つのコンポーネントが続きます:マイク、フロントマイク、ライン入力、サイド。第4のコンポーネントを除き、すべてにボリュームとミュートのコントロールがある。

サウンドデバイスのプロパティダイアログは、サウンドコントロールパネルから開くことができます。

オーディオドライバーは、低音や高音など、他のコントロールを露出させることができる。しかし、一般的なオーディオ・ドライバーには、ボリュームとミュート・コントロールしかないか、コンポーネントがまったくないことが多い。ボリュームとミュートのコントロールは、SoundGetVolumeSoundSetVolumeSoundGetMuteSoundSetMuteを通じて直接サポートされます。その他のコントロールは、SoundGetInterfaceComCallを通じて間接的にのみサポートされる。

詳細

コンポーネントは、コネクターサブユニットのグラフを公開するDeviceTopology APIを通じて発見される。上に示した各コンポーネントにはConnectorがあり、コンポーネントの名前を定義するのはConnectorである。各コントロール(ボリュームやミュートなど)は、コネクタとエンドポイントの間に位置するサブユニットによって表される。データはコネクタから、またはコネクタへ「流れ」、各サブユニットを流れる際に、音量を調整したり、すべての音を抑制(ミュート)するなど、変更される。

SoundGet関数とSoundSet関数は、デバイスのトポロジーグラフをウォーキングし、指定された名前を持つコネクター(名前がない場合は全てのコネクター)をカウントすることでコンポーネントを特定します。一致する Connector が見つかると、Connector に最も近いところから、グラフのその特定のブランチ上の各 Subunit にクエリを実行して、コントロールインターフェース(IAudioVolumeLevel や IAudioMute など)を検索する。

マスターボリュームやミュートコントロールに対応するサブユニットなど、複数のコネクターに適用されるサブユニットは除外されます。コネクタは、それ自身のサブユニットが少なくとも1つあれば(ある場合のみ)、そのサブユニットが要求されたタイプでなくてもカウントされる。

実際には、最終的に利用可能なコンポーネントは、「レベル」タブにリストされたとおりで、同じ順番となる。ただし、このプロセスは観察、試行錯誤に基づいているため、100%正確とは限らない。

Common Parameters

Component

型:文字列または整数

以下のいずれか:

インデックスのみが指定された場合、表示名は無視される。例えば、1"1"":1"は、名前に関係なく最初のコンポーネントを使用するが、""はマスターコントロールを使用する。

サウンドデバイスに指定されたコンポーネントがない場合、TargetErrorがスローされます。

Device

型:文字列または整数

以下のいずれか:

サウンドカード解析スクリプトは、使用する名前や番号を決定するのに役立つかもしれません。

サウンドカードの分析。以下のスクリプトを使用して、使用可能なオーディオデバイスとコンポーネント名、および各デバイスまたはコンポーネントがボリュームおよび/またはミュートコントロールをサポートしているかどうかを検出します。結果はシンプルなListViewに表示されます。現在の音量とミュートの設定が取得できる場合は表示されますが、リアルタイムで更新されるわけではありません。

scGui := Gui(, "Sound Components")
scLV := scGui.Add('ListView', "w600 h400"
    , ["Component", "#", "Device", "Volume", "Mute"])

devMap := Map()

loop
{
    ; For each loop iteration, try to get the corresponding device.
    try
        devName := SoundGetName(, dev := A_Index)
    catch  ; No more devices.
        break
    
    ; Qualify names with ":index" where needed.
    devName := Qualify(devName, devMap, dev)
    
    ; Retrieve master volume and mute setting, if possible.
    vol := mute := ""
    try vol := Round(SoundGetVolume( , dev), 2)
    try mute := SoundGetMute( , dev)
    
    ; Display the master settings only if at least one was retrieved.
    if vol != "" || mute != ""
        scLV.Add("", "", dev, devName, vol, mute)
    
    ; For each component, first query its name.
    cmpMap := Map()
    
    loop
    {
        try
            cmpName := SoundGetName(cmp := A_Index, dev)
        catch
            break
        ; Retrieve this component's volume and mute setting, if possible.
        vol := mute := ""
        try vol := Round(SoundGetVolume(cmp, dev), 2)
        try mute := SoundGetMute(cmp, dev)
        ; Display this component even if it does not support volume or mute,
        ; since it likely supports other controls via SoundGetInterface().
        scLV.Add("", Qualify(cmpName, cmpMap, A_Index), dev, devName, vol, mute)
    }
}

loop 5
    scLV.ModifyCol(A_Index, 'AutoHdr Logical')
scGui.Show()

; Qualifies full names with ":index" when needed.
Qualify(name, names, overallIndex)
{
    if name = ''
        return overallIndex
    key := StrLower(name)
    index := names.Has(key) ? ++names[key] : (names[key] := 1)
    return (index > 1 || InStr(name, ':') || IsInteger(name)) ? name ':' index : name
}