Karabiner-element&SwitchAudioSource&USBテンキーパッドでサウンド出力コントロール

薄い単体テンキーでUSB-DACの切り替えをしたい、ついでに音楽再生コントロールもしたい、Keyboard Maestroではどうしても外部USBデバイスはキー入力されてしまうのでKarabinarしかないけど、json書くのか…から始まった内容です。
なんてことはない内容だけど、メモとして。絶対忘れるから。
でははじめてのjson書いてみた、スタート。

#SwitchAudioSourceをインストール

オーディオ入力/出力を切り替えるコマンド。

```shell:
brew install SwitchAudioSource
```

オーディオデバイスをリスト出力、デバイスを特定する。

```shell:
SwitchAudioSource -a -f json
```


デバイスネームやidでも切り替えられるけれど、名前だとうまく拾えないことがあるし、idは再起動で変わるのでuidを使う。


idもuidも再起動で変わる…ので正確に名前を設定する。"FiiO K5 Pro "のように末尾のスペースも正確に…

リストから例として：

```shell:
{"name": "FOSTEX HP-A3", "type": "output", "id": "136", "uid": "AppleUSBAudioEngine:FOSTEX:32bit DAC:14210000:3"}```
```

```shell:
SwitchAudioSource -s "FOSTEX HP-A3"
```

で切り替わる。

#json書く

karabiner-elementsのmiscからフォルダを開く。不可視フォルダだし設定ウインドウひらきっぱだし。
/Users/(USER)/.config/karabiner/assets/complex_modifications/
内に、数字.jsonファイルを作る。数字じゃなくてもいいけど認識されないことがあるっぽい？変にハマりたくないから大人しく数字ファイルにする。
以下細切れだけどつなげてください。

```json:
{
  "title": "Music",
  "rules": [
    {
      "description": "Enter_to_play",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": xxxx,
                  "product_id": xxxxx
                }
              ]
            }
          ],
````
ベンダー、デバイスIDはkarabinerのデバイスから確認する。

```json:
          "from": {
            "key_code": "return_or_enter"
          },
          "to": [{
            "key_code": "play_or_pause"
          }],
          "type": "basic"
        }
      ]
    },
```
key_codeはkarabinerのイベントビューアで取得する。

```json:
     {
      "description": "Minus_to_foward",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": xxxx,
                  "product_id": xxxxx
                }
              ]
            }
          ],
          "from": {
            "key_code": "keypad_hyphen"
          },
          "to": [{
            "key_code": "fastforward"
          }],
          "type": "basic"
        }
      ]
    },
 {
      "description": "plus_to_rewind",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": xxxx,
                  "product_id": xxxxx
                }
              ]
            }
          ],
          "from": {
            "key_code": "keypad_plus"
          },
          "to": [{
            "key_code": "rewind"
          }],
          "type": "basic"
        }
      ]
    },
```
そしてここよ。karabinerのshell_commandよ。

```json:
     {
      "description": "asterisk_to_switch_bose",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": xxxx,
                  "product_id": xxxxx
                }
              ]
            }
          ],
          "from": {
            "key_code": "keypad_asterisk"
          },
          "to": [{
            "shell_command": "/usr/local/bin/SwitchAudioSource -u '14341000' ; /usr/bin/osascript -e 'tell application \"GeekTool Helper\" to refresh all'"
          }],
          "type": "basic"
        }
      ]
    },
```
geektoolにデバイス名とビットレートを、

```shell
i=`/usr/local/bin/SwitchAudioSource -c` ; echo $i | grep "TEAC"> /dev/null &&  echo "TEAC UD-505" || echo $i ; /usr/sbin/system_profiler SPAudioDataType -json | /usr/local/bin/jq '.SPAudioDataType[]._items[] | select( ._name| contains ("'"$i"'")) | .coreaudio_device_srate'
```

で表示させているので、切り替えたらリフレッシュで即更新されるようにしておく。
system_profilerの出力をjsonにして、jq（brew install jq)で項目内のビットレート部分を取得して表示。

```json:
     {
      "description": "9_to_switch_K5",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": xxxx,
                  "product_id": xxxxx
                }
              ]
            }
          ],
          "from": {
            "key_code": "page_up"
          },
          "to": [{
            "shell_command": "/usr/local/bin/SwitchAudioSource -u '14220000' ; /usr/bin/osascript -e 'tell application \"GeekTool Helper\" to refresh all'"
          }],
          "type": "basic"
        }
      ]
    },
     {
      "description": "6_to_switch_A3",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": xxxx,
                  "product_id": xxxxx
                }
              ]
            }
          ],
          "from": {
            "key_code": "right_arrow"
          },
          "to": [{
            "shell_command": "/usr/local/bin/SwitchAudioSource -u '14210000' ; /usr/bin/osascript -e 'tell application \"GeekTool Helper\" to refresh all'"
          }],
          "type": "basic"
        }
      ]
    },
```
そして、設定していないキーは全部無効にする（最後に書いておく）。
デバイスを限定すること。fromに"any": "key_code"で全部、toブロックを書かないことで葬り去る。

```json:
     {
      "description": "そのほか全部無効",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": xxxx,
                  "product_id": xxxxx
                }
              ]
            }
          ],
          "from": {
            "any": "key_code"
          },
          "type": "basic"
        }
      ]
    }
    ]
}
```

保存したらkarabinerのComplex modificationsタブから Add rule
descriptionが全部出てくればjsonは正しく書けている。出てこないならカッコの対応やスペルチェック。
必要なルールを追加して動作チェック！
以上！

##メディアキー動作をiTunes（Music.app）に限定させたいとき
keycode:playpause等で指定すると、Keynoteなどが前面にあるときはそちらにフォーカスしてしまう。
Music.appなどに操作を限定したいときは、toのKeycodeを

```
"shell_command": "/usr/bin/osascript -e 'tell application \"Music\" to playpause' "
```

とosascriptでアプリを限定する。
ちなみにMusic.appの場合、スクリプトの指定を
playpause：再生/一時停止
next track：次の曲
previous track：前の曲/先頭へ
とする。

現在の設定はこちら
※brightnessコマンドはbrewでインストール
※Keyboard MaestroでBlu-ray Player起動をトリガーにし、モニタ移動してフルスクリーンを仕込んでます

```json
{
  "title": "Music",
  "rules": [
    {
      "description": "Music.app_Enter_to_play",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1444,
                  "product_id": 12290
                }
              ]
            }
          ],
          "from": {
            "key_code": "return_or_enter"
          },
          "to": [{
            "shell_command": "/usr/bin/osascript -e 'tell application \"Music\" to playpause' "
          }],
          "type": "basic"
        }
      ]
    },
     {
      "description": "Music.app_Minus_to_foward",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1444,
                  "product_id": 12290
                }
              ]
            }
          ],
          "from": {
            "key_code": "keypad_hyphen"
          },
          "to": [{
            "shell_command": "/usr/bin/osascript -e 'tell application \"Music\" to next track' "
          }],
          "type": "basic"
        }
      ]
    },
     {
      "description": "Music.app_plus_to_rewind",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1444,
                  "product_id": 12290
                }
              ]
            }
          ],
          "from": {
            "key_code": "keypad_plus"
          },
          "to": [{
            "shell_command": "/usr/bin/osascript -e 'tell application \"Music\" to previous track' "
          }],
          "type": "basic"
        }
      ]
    },
     {
      "description": "All_play_or_pause",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1444,
                  "product_id": 12290
                }
              ]
            }
          ],
          "from": {
            "key_code": "delete_or_backspace"
          },
          "to": [{
            "key_code": "play_or_pause"
          }],
          "type": "basic"
        }
      ]
    },
      {
      "description": "asterisk_to_switch_bose",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1444,
                  "product_id": 12290
                }
              ]
            }
          ],
          "from": {
            "key_code": "keypad_asterisk"
          },
          "to": [{
            "shell_command": "/usr/local/bin/SwitchAudioSource -s 'Bose USB Audio' ; /usr/bin/osascript -e 'tell application \"GeekTool Helper\" to refresh all' ; /usr/bin/afplay /System/Library/Sounds/Hero.aiff"
          }],
          "type": "basic"
        }
      ]
    },
     {
      "description": "9_to_switch_TEAC",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1444,
                  "product_id": 12290
                }
              ]
            }
          ],
          "from": {
            "key_code": "page_up"
          },
          "to": [{
            "shell_command": "/usr/local/bin/SwitchAudioSource -s 'TEAC USB AUDIO DEVICE'; /usr/bin/osascript -e 'tell application \"GeekTool Helper\" to refresh all' ; /usr/bin/afplay /System/Library/Sounds/Hero.aiff"
          }],
          "type": "basic"
        }
      ]
    },
      {
      "description": "TAB_to_Eject_tray",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1444,
                  "product_id": 12290
                }
              ]
            }
          ],
          "from": {
            "key_code": "tab"
          },
          "to": [{
            "shell_command": "/usr/bin/drutil eject"
          }],
          "type": "basic"
        }
      ]
    },
          {
      "description": "ins_to_BritnessUP&Blu-rayPLAY",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1444,
                  "product_id": 12290
                }
              ]
            }
          ],
          "from": {
            "key_code": "insert"
          },
          "to": [{
            "shell_command": "/usr/local/bin/brightness -d 1 -v 1 ; osascript -e 'tell application \"Mac Blu-ray Player PRO\" to activate' ; /usr/bin/afplay /System/Library/Sounds/Blow.aiff"
          }],
          "type": "basic"
        }
      ]
    },
              {
      "description": "end_to_Brightness01",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1444,
                  "product_id": 12290
                }
              ]
            }
          ],
          "from": {
            "key_code": "end"
          },
          "to": [{
            "shell_command": "/usr/local/bin/brightness -d 1 -v 0.2 ; osascript -e 'tell application \"Mac Blu-ray Player PRO\" to quit' ; /usr/bin/afplay /System/Library/Sounds/Bottle.aiff"
          }],
          "type": "basic"
        }
      ]
    },
     {
      "description": "そのほか全部無効",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1444,
                  "product_id": 12290
                }
              ]
            }
          ],
          "from": {
            "any": "key_code"
          },
          "type": "basic"
        }
      ]
    }
    ]
}
```