文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

macOS SierraでAudirvana Plus v3のDirect Modeを有効にする手順

sierraでできましたよ〜

f:id:treeapps:20170829002500p:plain

macOSでAudirvanaのDirect Modeで高音質サウンドを楽しんでいた方は結構いたと思います。それがElcapitan以降では、Direct Modeが無効になってしまいました。

Direct Modeが無効だと、mac標準のCoreAudioを経由してしまうため、どうしても音質が下がってしまい、折角のAudirvanaも残念な音になってしまいます。

これに嘆いていた方は多いと思うので、まとめておこうと思います。

macOS sierraで何が起きたのか

macOS 10.12 Sierra
Apple has just released macOS 10.12 Sierra that has a regression that breaks Direct Mode.

https://audirvana.com/?p=4048

sierraになってから、Direct Modeが使用不可になったよ〜、というアナウンスがあり、Audirvanaの設定画面でDirect Modeを有効にして再生しようとしても、エラーで再生できなくなりました。

これはAudirvanaの問題なのではなく、突如Direct Modeを使用できなくしたapple側の問題なのです。(悪いわけではないのですけどね・・・)

AppleはよほどCore Audioに自信があるのか、これから超強化するつもりなのか。Direct Modeをわざわざ無効にした理由は未だ不明です。もしかしたらシステム的にDirect Modeが有効だと困ってしまう機能が現れたのかもしれませんね。

Core Audioで音質が低下する理由

これは簡単で、音楽データが通る経路が増えるためです。

Core Audioの場合は、「ハードウェア -> Core Audio -> 音楽ソフトウェア」という経路に対し、Direct Modeの場合は「ハードウェア -> 音楽ソフトウェア」となるため、音質に差が出ます。

システム情報

この手順で上手くいった時の各種情報です。バージョンによって上手くいった・いかない等があると思うので、参考までに。

OS macOS sierra v10.12.6
ハードウェア iMac (Retina 5K, 27-inch, Late 2014)
ソフトウェア Audirvana Plus v3.1.2

SierraでDirect Modeを再び有効にする手順

必要なもの

ざっくり以下が必要になります。

  • OS X El Capitan アップデータのDL。
  • parse_pbzx2.pyのDL(pbzx形式のpkg内のPayloadをデコードしてxz形式に変換する)
  • El Capitan時代のIOAudioFamily.kextの入手。
  • SIPの無効化。
  • IOAudioFamily.kextの差し替え。
  • OnyXのインストールと権限の修復。

では順にやっていきましょう。

OS X El Capitan アップデータのダウンロード

ダウンロード - OS X El Capitan アップデート v10.11.6

ここのダウンロードボタンから「osxupd10.11.6.dmg」をダウンロードします。ファイルサイズは717.9MBあります。

ダウンロードできたらFinderからダブルクリックし、マウントします。マウントするだけでまだ何もしません。

OSXUpd10.11.6.pkgをローカルにコピー

osxupd10.11.6.dmgをマウントすると出て来る「OSXUpd10.11.6.pkg」が欲しいので、以下のコマンドでコピーします。

# 作業ディレクトリを作成
$ mkdir -pv /tmp/test-audirvana

# 作業ディレクトリに移動
$ cd /tmp/test-audirvana

# ボリュームから作業ディレクトリにコピー
$ cp -v /Volumes/OS\ X\ El\ Capitan\ Update/OSXUpd10.11.6.pkg /tmp/test-audirvana/
/Volumes/OS X El Capitan Update/OSXUpd10.11.6.pkg -> /tmp/test-audirvana/OSXUpd10.11.6.pkg

parse_pbzx2.pyのダウンロード

macの場合gitが標準インストールされているので、gitでダウンロードします。

# cloneする
$ git clone https://gist.github.com/ff412bcb29c9c1fa4b8d.git
Cloning into 'ff412bcb29c9c1fa4b8d'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 3
Unpacking objects: 100% (3/3), done.
# parse_pbzx2.pyが有るフォルダに移動
cd ff412bcb29c9c1fa4b8d

OSXUpd10.11.6.pkgを解凍する

# pkgを解凍
$ xar -xf ../OSXUpd10.11.6.pkg

# 解凍されたフォルダ等を確認(OSXUpd10.11.6.pkgという名前のディレクトリができます)
$ ls -l
total 32
-rwxr-xr-x   1 tree  staff  8406  7  9  2016 Distribution
drwxr-xr-x   6 tree  staff   204  7  9  2016 FirmwareUpdate.pkg
drwxr-xr-x   6 tree  staff   204  7  9  2016 FullBundleUpdate.pkg
drwxr-xr-x   6 tree  staff   204  7  9  2016 OSXUpd10.11.6.pkg
drwxr-xr-x  36 tree  staff  1224  7  9  2016 Resources
-rw-r--r--   1 tree  wheel  2868  9  8 00:36 parse_pbzx2.py

Payloadをディレクトリに分解する

# parse_pbzx2.pyでPayloadを分解
$ python ./parse_pbzx2.py OSXUpd10.11.6.pkg/Payload
Now xz decompress the .xz chunks, then 'cat' them all together in order into a single new.cpio file

何やら.xz形式のファイルが出来たから、catしろなと言われるので、以下のコマンドでxz圧縮ファイルを解凍します。

# xzをcatしてcpioでディレクトリを取り出す
$ cat OSXUpd10.11.6.pkg/Payload.part00.cpio.xz | cpio -id
4722526 blocks

# 出てきたディレクトリを確認する
$ ls -ld *
drwxrwxr-x  12 tree  wheel   408  9  8 00:50 Applications
-rwxr-xr-x   1 tree  staff  8406  7  9  2016 Distribution
drwxr-xr-x   6 tree  staff   204  7  9  2016 FirmwareUpdate.pkg
drwxr-xr-x   6 tree  staff   204  7  9  2016 FullBundleUpdate.pkg
drwxr-xr-x  12 tree  wheel   408  9  8 00:50 Library
drwxr-xr-x   7 tree  staff   238  9  8 00:44 OSXUpd10.11.6.pkg
drwxr-xr-x  36 tree  staff  1224  7  9  2016 Resources
drwxr-xr-x   3 tree  wheel   102  9  8 00:50 System
drwxr-xr-x  18 tree  wheel   612  9  8 00:51 bin
-rw-r--r--   1 tree  wheel  2868  9  8 00:36 parse_pbzx2.py
drwxr-xr-x   4 tree  wheel   136  9  8 00:51 private
drwxr-xr-x  20 tree  wheel   680  9  8 00:51 sbin
drwxr-xr-x   7 tree  wheel   238  9  8 00:51 usr

おおお、沢山見慣れたディレクトリが出てきました。

この中に、お目当てのIOAudioFamily.kextがあります。探してみましょう。

# IOAudioFamily.kextを探す
$ find . -name "IOAudioFamily.kext"
./System/Library/Extensions/IOAudioFamily.kext

ありました。こいつを一旦デスクトップ(/tmp/等だと再起動時に消えてしまうので他の場所にする)にコピーします。

# デスクトップにIOAudioFamily.kextをコピー
tree:ff412bcb29c9c1fa4b8d tree$ cp -av ./System/Library/Extensions/IOAudioFamily.kext $HOME/Desktop
./System/Library/Extensions/IOAudioFamily.kext -> /Users/tree/Desktop/IOAudioFamily.kext
./System/Library/Extensions/IOAudioFamily.kext/Contents -> /Users/tree/Desktop/IOAudioFamily.kext/Contents
./System/Library/Extensions/IOAudioFamily.kext/Contents/_CodeSignature -> /Users/tree/Desktop/IOAudioFamily.kext/Contents/_CodeSignature
./System/Library/Extensions/IOAudioFamily.kext/Contents/_CodeSignature/CodeResources -> /Users/tree/Desktop/IOAudioFamily.kext/Contents/_CodeSignature/CodeResources
./System/Library/Extensions/IOAudioFamily.kext/Contents/Info.plist -> /Users/tree/Desktop/IOAudioFamily.kext/Contents/Info.plist
./System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS -> /Users/tree/Desktop/IOAudioFamily.kext/Contents/MacOS
./System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS/IOAudioFamily -> /Users/tree/Desktop/IOAudioFamily.kext/Contents/MacOS/IOAudioFamily
./System/Library/Extensions/IOAudioFamily.kext/Contents/version.plist -> /Users/tree/Desktop/IOAudioFamily.kext/Contents/version.plist

コピーできると、以下のようにFinder上でKernel Extension形式で表示されます。

f:id:treeapps:20170908010253p:plain

macのSIPを無効にする

本当は抽出したIOAudioFamily.kextでローカルのファイルを上書きしたいのですが、対象ディレクトリはSIP保護下にあるため、root権限を持ってしても上書きする事ができません。なので、SIPを無効にしてやります。

まずmacを再起動し、command + r の2つのキーを押しっぱなしにしたまま起動し、Mac OS X ユーティリティーを表示させます。

ここでメニューバーのユーティリティーからターミナルを選択し、ターミナルを起動します。

ターミナルが起動したら、おもむろに「csrutil disable」と入力してEnterキーを叩くと、SIPが無効になります。無効にできたらmacを再起動します。

IOAudioFamily.kextを差し替える

SIPを無効にしてOSが起動したら、IOAudioFamily.kextを差し替えます。

# 既存ファイルをバックアップしておく
$ mkdir -pv $HOME/Desktop/backup
$ cp -av /System/Library/Extensions/IOAudioFamily.kext $HOME/Desktop/backup
/System/Library/Extensions/IOAudioFamily.kext -> /Users/tree/Desktop/backup
/System/Library/Extensions/IOAudioFamily.kext/Contents -> /Users/tree/Desktop/backup/Contents
/System/Library/Extensions/IOAudioFamily.kext/Contents/_CodeSignature -> /Users/tree/Desktop/backup/Contents/_CodeSignature
/System/Library/Extensions/IOAudioFamily.kext/Contents/_CodeSignature/CodeResources -> /Users/tree/Desktop/backup/Contents/_CodeSignature/CodeResources
/System/Library/Extensions/IOAudioFamily.kext/Contents/Info.plist -> /Users/tree/Desktop/backup/Contents/Info.plist
/System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS -> /Users/tree/Desktop/backup/Contents/MacOS
/System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS/IOAudioFamily -> /Users/tree/Desktop/backup/Contents/MacOS/IOAudioFamily
/System/Library/Extensions/IOAudioFamily.kext/Contents/version.plist -> /Users/tree/Desktop/backup/Contents/version.plist

# デスクトップにコピーしておいたIOAudioFamily.kextを差し替える
$ sudo cp -av $HOME/Desktop/IOAudioFamily.kext /System/Library/Extensions
Password:
/Users/tree/Desktop/IOAudioFamily.kext -> /System/Library/Extensions/IOAudioFamily.kext
/Users/tree/Desktop/IOAudioFamily.kext/Contents -> /System/Library/Extensions/IOAudioFamily.kext/Contents
/Users/tree/Desktop/IOAudioFamily.kext/Contents/_CodeSignature -> /System/Library/Extensions/IOAudioFamily.kext/Contents/_CodeSignature
/Users/tree/Desktop/IOAudioFamily.kext/Contents/_CodeSignature/CodeResources -> /System/Library/Extensions/IOAudioFamily.kext/Contents/_CodeSignature/CodeResources
/Users/tree/Desktop/IOAudioFamily.kext/Contents/Info.plist -> /System/Library/Extensions/IOAudioFamily.kext/Contents/Info.plist
/Users/tree/Desktop/IOAudioFamily.kext/Contents/MacOS -> /System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS
/Users/tree/Desktop/IOAudioFamily.kext/Contents/MacOS/IOAudioFamily -> /System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS/IOAudioFamily
/Users/tree/Desktop/IOAudioFamily.kext/Contents/version.plist -> /System/Library/Extensions/IOAudioFamily.kext/Contents/version.plist

ファイルが上書きされてしばらくすると、不意に以下の警告が表示されます。

f:id:treeapps:20170908011730p:plain

権限等が誤っているのでしょうか。ちょっと見てましょう。

$ ls -lR /System/Library/Extensions/IOAudioFamily.kext
total 0
drwxr-xr-x  6 tree  staff  204  9  7 23:00 Contents

/System/Library/Extensions/IOAudioFamily.kext/Contents:
total 16
-rw-r--r--  1 tree  staff  1999  9  7 23:00 Info.plist
drwxr-xr-x  3 tree  staff   102  9  7 23:00 MacOS
drwxr-xr-x  3 tree  staff   102  9  7 23:00 _CodeSignature
-rw-r--r--  1 tree  staff   465  9  7 23:00 version.plist

/System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS:
total 536
-rwxr-xr-x  1 tree  staff  270656  9  7 23:00 IOAudioFamily

/System/Library/Extensions/IOAudioFamily.kext/Contents/_CodeSignature:
total 8
-rw-r--r--  1 tree  staff  2534  9  7 23:00 CodeResources

うーん、解りません。。。

どうやらこの状態はOnyXのアクセス権限の修復を行うと治るようです。

OnyXのダウンロードとインストール

OnyXはAppStoreで配布されていないので、公式サイトからダウンロードし、普通にインストールして下さい。

www.titanium-software.fr

日本語化されているので、解りやすいソフトだと思います。

OnyXでアクセス権限の修復をする

OnyXを起動すると管理者パスワードを聞かれるので入力して起動します。

起動後、メニューの「メンテナンス」をクリック、実行ボタンをクリックすると、アクセス権限の修復が行われます。

f:id:treeapps:20170908012228p:plain

結構時間がかかる(15〜30分くらい?)ので、気長に待ちます。

修復が完了するとログが表示されます。

volume_arg = /
Starting argv pass #2...
Processing files from package com.apple.pkg.EmbeddedOSFirmware...
Processing files from package com.apple.update.fullbundleupdate.16G29...
Processing files from package com.apple.pkg.FirmwareUpdate...
Processing files from package com.apple.pkg.update.os.10.12.6Patch.16G29...
	User differs on "System/Library/Extensions/IOAudioFamily.kext", should be 0, user is 501.
	Group differs on "System/Library/Extensions/IOAudioFamily.kext", should be 0, group is 20.
	Repaired "System/Library/Extensions/IOAudioFamily.kext".
	User differs on "System/Library/Extensions/IOAudioFamily.kext/Contents", should be 0, user is 501.
	Group differs on "System/Library/Extensions/IOAudioFamily.kext/Contents", should be 0, group is 20.
	Repaired "System/Library/Extensions/IOAudioFamily.kext/Contents".
	User differs on "System/Library/Extensions/IOAudioFamily.kext/Contents/Info.plist", should be 0, user is 501.
	Group differs on "System/Library/Extensions/IOAudioFamily.kext/Contents/Info.plist", should be 0, group is 20.
	Repaired "System/Library/Extensions/IOAudioFamily.kext/Contents/Info.plist".
	User differs on "System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS", should be 0, user is 501.
	Group differs on "System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS", should be 0, group is 20.
	Repaired "System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS".
	User differs on "System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS/IOAudioFamily", should be 0, user is 501.
	Group differs on "System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS/IOAudioFamily", should be 0, group is 20.
	Repaired "System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS/IOAudioFamily".
	User differs on "System/Library/Extensions/IOAudioFamily.kext/Contents/_CodeSignature", should be 0, user is 501.
	Group differs on "System/Library/Extensions/IOAudioFamily.kext/Contents/_CodeSignature", should be 0, group is 20.
	Repaired "System/Library/Extensions/IOAudioFamily.kext/Contents/_CodeSignature".
	User differs on "System/Library/Extensions/IOAudioFamily.kext/Contents/_CodeSignature/CodeResources", should be 0, user is 501.
	Group differs on "System/Library/Extensions/IOAudioFamily.kext/Contents/_CodeSignature/CodeResources", should be 0, group is 20.
	Repaired "System/Library/Extensions/IOAudioFamily.kext/Contents/_CodeSignature/CodeResources".
	User differs on "System/Library/Extensions/IOAudioFamily.kext/Contents/version.plist", should be 0, user is 501.
	Group differs on "System/Library/Extensions/IOAudioFamily.kext/Contents/version.plist", should be 0, group is 20.
	Repaired "System/Library/Extensions/IOAudioFamily.kext/Contents/version.plist".
・・・略・・・

IOAudioFamily.kextを修復した旨のログが表示されていますね。これでもう大丈夫です。

OSを再起動する

このままではIOAudioFamily.kextはまだOSに読み込まれていないので、OSを再起動して読み込ませます。

AudirvanaでDirect Modeを有効にする

f:id:treeapps:20170908012641p:plain

Direct Modeにチェックを付けて、早速音楽を再生してみて下さい。これで元のDirect Modeの音質に戻ります。

トラブルシューティング

作業時にちょっと嵌った点があったので、それもまとめておきます。

Error while extracting archive

最初のxarで解答時に以下のエラーが出ました。

$ xar -xf ./OSXUpd10.11.6.pkg

Error while extracting archive:(OSXUpd10.11.6.pkg/Bom): io: Could not create file (Not a directory) - ignored
Error while extracting archive:(OSXUpd10.11.6.pkg/PackageInfo): io: Could not create file (Not a directory) - ignored
Error while extracting archive:(OSXUpd10.11.6.pkg/Payload): io: Could not create file (Not a directory) - ignored
Error while extracting archive:(OSXUpd10.11.6.pkg/Scripts): io: Could not create file (Not a directory) - ignored

この原因は簡単で、xarで「OSXUpd10.11.6.pkg」を解凍すると、「OSXUpd10.11.6.pkg」というディレクトリ(完全に同じ名前のディレクトリ)が解凍される筈なのですが、既に「OSXUpd10.11.6.pkg」というファイルが存在してしまっているので「OSXUpd10.11.6.pkg」というフォルダが解凍できなかった、という事です。

なので、「OSXUpd10.11.6.pkg」ファイルが有る場所以外でxarで解凍する必要があります。

IOAudioFamily.kextをコピーしたらContentsディレクトリがコピーされたよ?

既存のIOAudioFamily.kextのバックアップをしておこうと以下のコマンドを叩きました。

$ cp -av /System/Library/Extensions/IOAudioFamily.kext $HOME/Desktop/backup
/System/Library/Extensions/IOAudioFamily.kext -> /Users/tree/Desktop/backup
/System/Library/Extensions/IOAudioFamily.kext/Contents -> /Users/tree/Desktop/backup/Contents
/System/Library/Extensions/IOAudioFamily.kext/Contents/_CodeSignature -> /Users/tree/Desktop/backup/Contents/_CodeSignature
/System/Library/Extensions/IOAudioFamily.kext/Contents/_CodeSignature/CodeResources -> /Users/tree/Desktop/backup/Contents/_CodeSignature/CodeResources
/System/Library/Extensions/IOAudioFamily.kext/Contents/Info.plist -> /Users/tree/Desktop/backup/Contents/Info.plist
/System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS -> /Users/tree/Desktop/backup/Contents/MacOS
/System/Library/Extensions/IOAudioFamily.kext/Contents/MacOS/IOAudioFamily -> /Users/tree/Desktop/backup/Contents/MacOS/IOAudioFamily
/System/Library/Extensions/IOAudioFamily.kext/Contents/version.plist -> /Users/tree/Desktop/backup/Contents/version.plist

すると・・・

f:id:treeapps:20170908013332p:plain

あれ?IOAudioFamily.kextじゃなくてContentsディレクトリがコピーされている(IOAudioFamily.kextが展開されてしまっている)ぞ?と。

これはcpコマンドの特性っぽいのですが、今回の場合はデスクトップに「backup」という名前のディレクトリが無い状態でコピーすると、正常にコピーされずディレクトリに展開されてしまうようなのです。

なので、backupディレクトリを作成してからコピーすると、正常にコピーできます。

$ mkdir -pv $HOME/Desktop/backup
$ cp -av /System/Library/Extensions/IOAudioFamily.kext $HOME/Desktop/backup

OSのアップデート後にまたDirect Modeが無効になってしまう問題

まだ私は未経験ですが、IOAudioFamily.kextを差し替えた後にOSのマイナーバージョンアップ等が発生すると、IOAudioFamily.kextがDirect Mode無効なファイルで上書きされる事があるようです。

なので、SIPはそのまま無効にしてバージョンアップ毎にIOAudioFamily.kextを上書きするか、OSのバージョンアップを停止する等で対応可能です。

OSのマイナーバージョンアップはセキュリティ対応等を含むので、私はおすすめしません。

IOAudioFamily.kextの復元手順で入手した、El CapitanのIOAudioFamily.kext をいつでも上書きできるようにバックアップしておいて、面倒ですが都度上書きした方が安全かと思います。

/tmp/test-audirvanaはどうするの?

手動で削除してもよいのですが、/tmpなので、OSの再起動後に勝手に削除されます。

xarコマンドってなに?

developer.apple.com

だそうです(丸投げ)。

cpioコマンドってなに?

cpio (コピーインとコピーアウト) コマンドを使用して、個々のファイル、ファイルグループ、またはファイルシステム全体をコピーできます。この節では、cpio コマンドを使用してファイルシステム全体をコピーする方法について説明します。

cpio コマンドは、ファイルのリストを取り出して 1 つの大型出力ファイルにコピーするアーカイブプログラムです。また、復元しやすいように、個々のファイルの間にヘッダーを挿入します。cpio コマンドを使用すると、ファイルシステム全体を別のスライス、別のシステム、またはテープやフロッピーディスクなどの媒体デバイスにコピーできます。

cpio コマンドは、媒体の終りを認識し、別のボリュームを挿入するように促すプロンプトを表示するので、複数のテープやフロッピーディスクが必要なアーカイブを作成するには最も (ufsdump よりも) 効率のよいコマンドです。

cpio の使用時には、しばしば ls や find などのコマンドを使用してコピーしたいファイルを選択し、その出力を cpio コマンドにパイプします。

https://docs.oracle.com/cd/E19455-01/806-2717/6jbtqlek3/index.html

だそうです(丸投げ)。

参考サイト

scrap.hateblo.jp

こちらのサイトを参考に、少し嵌った部分(トラブルシューティング)を追記する形でまとめてみました。まあ、上記記事とほぼ同じ内容になってしまったのですけどね・・・

雑感

DAC(HTPC/MY435-ES9018v3)

  • > ヘッドホンアンプ(luxman p-700u)
  • > USBケーブル
  • > mac
  • > ゼンハイザーのHD800(バランス接続)

という環境で聞いてるので、ちょっとした音質劣化が結構はっきり解ってしまうのですよね。

sierraにした後くらいからハイレゾ音源がちょっとアレ?と思ってたら、調べてみると実はDirect Modeがオフになっていた、という事なのでした。

まあ、Direct Modeを有効にしたからといっても、ソース音源が16bit/44khzのようにショボかったり、mp3だったり、ニセレゾだったりすると残念な結果になりますが、32bit/96khzの真のハイレゾだと流石に違いは解ってしまいます。なんだか宗教チックですが、それなりの環境だと違いでるよ〜、という事ですね。

とりあえずこの手順でDirect Modeを有効にし、更にIntegerモードにして音楽データの転送の手助けをしてあげると、最適な状態になりそうです。