reTONE
開発中・近日公開無料 ・ Android 4.0 以降

技術ノート

仕様、変換と出力の仕組み、動作を確認した端末など、細かい話をまとめています。機能と仕様の続きです。

主な仕様

対応 Android4.0 以降
CPUARM(armeabi-v7a、arm64-v8a)
権限ストレージの読み取りなど。インターネットは、設定の「ネットワーク機能」をオンにしたときだけ使います
reTONE のエンジンが読む形式WAV、AIFF/AIFC、DSF、DFF(非圧縮)、FLAC
reTONE が変換する曲Android 4.x は FLAC と WAV の全部。5〜9 は、レートが出力と違う、または 16 bit を超える FLAC と WAV
サンプルレート変換カイザー窓を使った FIR フィルター(ポリフェーズ構成)。20 kHz まで ±0.001 dB 未満(設計値。44.1 kHz 以上の変換)
エンジンから Android へ渡す形式Android 5 以降は 32 bit float、4.x は 16 bit(ディザーあり)。端末の出口のビット数は端末によります
USB DACUSB Audio Class 2(Class 1 は未確認)。DAC が対応するレートはそのまま。32 bit の枠を優先(ない場合は 24・16 bit)。ネイティブ DSD は条件つき
署名配布するバージョンは、すべて同じ鍵で署名

再生できる形式

端末の Android が再生できる形式は、端末のデコーダーと音響処理で再生します。Android が読めない DSD、AIFF、ハイレゾの FLAC と WAV は、reTONE のエンジンで再生します。

Android が再生する形式FLAC、AAC、MP3、Ogg Vorbis、WAV など(Opus は Android 5 以降)
reTONE のエンジンが再生する形式DSD(DSF、DFF)、AIFF、32 bit の WAV、ALAC(端末が再生できない場合。0.68.0 から)。Android 4.x では FLAC と WAV の全部
再生できない形式DST 圧縮の DFF、APE、WMA ロスレス

技術的な詳細

可逆圧縮や非圧縮の曲は、正しく作られたデコーダーであれば、どれで再生しても同じデータに戻ります。端末の音響効果を除くと、音が変わるのは主に「サンプルレートの変換」「ビット数の切り詰め」「音量の計算とミキサー」の 3 か所で、reTONE はそこを受け持ちます。

読みもの:音質を左右するもの

FLAC などの可逆圧縮や WAV などの非圧縮の曲は、正しく作られたデコーダーであれば、どのアプリで再生しても元とまったく同じデータに戻ります。音が変わりうるのは、デコードのあとの処理(下の 3 つと、端末の音響効果)です。

サンプルレートの変換

多くの Android 端末は、音の出口を 48 kHz などに固定しています。CD 音源やハイレゾ音源など、出口と違うレートの曲は、再生のたびに変換されます。変換の品質は端末によって異なります。

ビット数の切り詰め

古い Android では、24 bit の曲が 16 bit に切り詰められます。

音量の計算とミキサー

音量の計算や、ほかのアプリの音との混ぜ合わせも、出口の手前で行われます。

reTONE は、この部分に手を入れています。変換が必要な場面では reTONE が自身で変換し、変換しなくて済む場面では変換しません。USB DAC では、Android の音声処理を通さずに DAC へ送ります。ただし、端末が実際に出力した信号を確かめる手段はないため、ビットパーフェクトであることは保証できません。

音の通り道

端末の出口のレートが 48 kHz などに決まっている場合、root なしでは出口のレートを変えられないため、出口と違うレートの曲(44.1 kHz の CD 音源や、88.2・96・192 kHz のハイレゾ音源など)を変換せずに鳴らすことはできません。Android 4.x〜9 では、reTONE のエンジンで再生する曲を、Android に渡す前に自分で高品質に変換しておくことで、Android の変換が動かないようにしています(変換の品質は、下の「変換フィルター」をご覧ください)。USB DAC や、ダイレクト出力に対応する端末では、変換そのものをしません。

Android 4.xFLAC・WAV・DSD・AIFF
曲ファイル reTONE のエンジンAndroid の代わりに変換(必要なときだけ) Android16 bit で受け取り、変換しない スピーカー・イヤホン
Android 5〜9DSD・AIFF と、変換が必要な FLAC・WAV
曲ファイル reTONE のエンジンAndroid の代わりに変換 Androidfloat で受け取り、レートは変換しない(出口が 16 bit の端末では、ここで 16 bit に) スピーカー・イヤホン
Android 10 以降ダイレクト出力に対応する端末
曲ファイル reTONE16 bit の可逆音源は 24 bit に詰め直す Androidダイレクト出力 スピーカー・イヤホン曲のレートのまま
USB DACOTG でつないだとき(すべての曲)
曲ファイル reTONEDAC が対応するレートはそのまま、それ以外は変換Android を通らない USB DAC

reTONE が受け持つところAndroid が受け持つところ

曲のサンプルレートが端末の出力と同じ曲は、変換が要らないため、Android の標準の再生で鳴らしても変換は起きません。MP3・AAC など reTONE のエンジンを通らない形式は Android の標準の再生を使い、レートが端末の出力と違う場合は Android が変換します(USB DAC で再生するときは、これらも reTONE が送ります)。DSD・AIFF は、Android 10 以降でも reTONE のエンジンで再生します。

詳しい説明

reTONE は、曲の形式・Android のバージョン・出力先によって「reTONE が受け持つ範囲」を変えます。PCM の曲では、どの経路でもサンプルレートの変換は多くて 1 回です(DSD を PCM にする場合は、PCM にする段のあとに 1 回)。Bluetooth では、このあとに端末とコーデックの処理が加わります。再生の土台は Android の MediaPlayer と AudioTrack で、reTONE のエンジン(C で記述)はその手前でデコードと変換を受け持ちます。

Android 4.x:Android 4.x の多くの端末は、音楽の出力スレッドを 48 kHz などの決まったレートで開いており、44.1 kHz や 96 kHz など出力と違うレートの曲は Android のミキサーの中で変換されてから鳴ります。アプリからこの変換を止める手段はありません。また 4.x 標準のデコーダーは、24 bit の FLAC を 16 bit に落とす、または 192 kHz の FLAC を開けないことがあります。そこで 4.x では、FLAC と WAV をすべて、DSF・DFF・AIFF も reTONE のエンジンで読み、端末の出力レート(AudioTrack.getNativeOutputSampleRate の値)へ一度だけ変換して、16 bit で渡します。Android のミキサーは同じレートの 16 bit をそのまま受けるので、Android 側のサンプルレート変換は起きません。16 bit に落とすときは TPDF ディザーをかけ、出力が 44.1 kHz または 48 kHz のときは誤差帰還型のノイズシェーピング(Lipshitz・Vanderkooy・Wannamaker の 5 タップ E 重み付け)で量子化雑音を聞こえにくい帯域へ寄せます。クリップしたときは帰還する誤差を ±4 LSB に制限し、発振しないようにしています。係数は 44.1 kHz 向けに設計されたもので、48 kHz にも使っています。雑音の総量は増えますが、耳の感度が低い高域に寄せます。ただし、Android の音量を最大より下げると、Android のミキサーが音量を掛けたあとで改めて 16 bit に丸めるため、ノイズシェーピングの効果は薄れます(サンプルレートの変換は起きません。音量を端末の部品の側で調整する端末では、この限りではありません)。MP3・AAC などは 4.x でも Android の標準の経路で再生します。

Android 5〜9:この世代の Android のミキサーは float で受け取れるため、reTONE のエンジンは float のまま AudioTrack に渡し、ディザーはかけません。出口が 16 bit の端末では、Android がそのあと 16 bit に丸めます(このとき Android はディザーをかけません)。曲のサンプルレートが端末の出力レートと違う FLAC・WAV は、そのまま渡すと Android のミキサーが変換し、16 bit を超える曲は 16 bit に切り詰められます。AOSP の既定の変換器は、品質の設定(af.resampler.quality)が未設定なら中程度の動的品質(DYN_MED)で、同時に使われる変換器の見積もりの負荷が上限を超えると、さらに低い品質へ下がります。確認した端末ではこの設定が未設定でした。reTONE はこの条件に当たる曲だけを自身のエンジンで変換し、設定「reTONE による変換」でオフにできます。端末の出力レートと同じで 16 bit の曲(CD 音源を 44.1 kHz の端末で鳴らす場合など)は、変換が起きないので Android の標準の経路で再生します。

ダイレクト出力(Android 10 以降。使用可否は端末による):曲のレートのままミキサーを通さず出力する「ダイレクト出力」と、圧縮音源をチップ側でデコードする「オフロード」は、使用可否が端末と出力先によって異なります。Android 10 以降では、AudioTrack.isDirectPlaybackSupported で「今の出力先で、この形式・レート・ビット数を直接出せるか」を端末に尋ねられるので、reTONE は「出せる」と答えたときだけこの経路を使い、それ以外は Android の標準の経路で再生します。答えは出力先ごとに変わるため、イヤホンや USB の抜き差しのたびに聞き直します。確認した端末では、直接出力できないのは 16 bit の PCM のうち 44.1・48・88.2 kHz のもの(CD 音源もこれに当たります)だけで、24 bit や float は曲のレートのまま直接出力でき、MP3・AAC(60 秒以上の曲)はオフロードに乗りました。そこで reTONE は、16 bit の可逆音源(FLAC・ALAC・WAV)を端末のデコーダーで PCM にし、下位 8 bit を 0 で埋めた 24 bit の WAV として MediaDataSource 経由で MediaPlayer に渡します。上位 16 bit は変化しません。渡す前に最初の 1 ブロックを実際にデコードし、本当に 16 bit の PCM が出ることを確かめてから切り替え、確かめられなければ標準の経路に戻ります。24 bit や高レートの可逆音源、MP3・AAC は、もともと直接出力・オフロードに乗るのでそのまま渡します。なお、端末が実際にどの出力に乗せたかをアプリから読む手段はないため、再生画面の「DIRECT」は端末の答えに基づく見込みです(確認した端末では、システム側の記録と一致しました)。オフロードでは、チップの中でサンプルレートが変わるかどうかも確かめられません。この経路では端末のソフトウェアの音響効果(DTS など)はかからず、DAC のハードウェア側の設定(フィルターなど)は効きます。設定でオン・オフできます。

USB DAC への直接出力:USB ホスト機能(OTG)のある端末に USB DAC をつなぐと、reTONE は Android の音声の経路を通さず、DAC へ直接データを送ります。確認した端末では、Android の標準の経路は USB DAC へ 48 kHz/16 bit に変換して出力していました(192 kHz/32 bit 用の出力も開かれていましたが、音楽には使われていませんでした)。reTONE の直接出力の流れは次のとおりです。

  • 端末の USB ホスト API で DAC を見つけ、利用者の許可を得て、USB の記述子を読みます(USB Audio Class 2.0。クロックの ID、再生用インターフェースの代替設定、出力エンドポイント、フィードバックエンドポイント)。
  • Android のドライバーから DAC を引き取り(claimInterface)、PCM・2 ch・32 bit の代替設定を優先して選びます(ない場合は 24 bit、16 bit)。
  • 対応するサンプルレートはクロックソースの GET RANGE で読み、曲のレートがその中にあれば SET CUR で設定し、GET CUR で反映を確かめます。対応しないレートの曲だけ、reTONE が一度だけ変換します。DAC が対応するレートの曲には、サンプルレートの変換とディザーはかけません。24 bit までの曲は、元のデータをそのまま 32 bit の語の上位に入れて送ります(0.69.0 から。DAC の音量を使う場合、または DAC 本体で音量を調整する場合)。16 bit の DAC では、元が 16 bit ちょうどの曲にはディザーをかけず、それより細かい値を持つ曲にだけ TPDF ディザーをかけます。
  • 転送は C 側で、usbdevfs のアイソクロナス転送を使い、High Speed の DAC のうち、0.125 ms ごとに受け取る多くの DAC では、1 ms 分(8 マイクロフレーム)を 1 つの転送にまとめ、それを 64 本先に積んで送り続けます。受け取る間隔がもっと長い DAC では、1 つの転送を 32 パケットにし、先に積む量が約 64 ms になるよう本数を減らします。非同期モードの DAC は、フィードバックエンドポイントから「1 マイクロフレームあたりのフレーム数」を返すので、それに合わせて送る量を決めます。値の桁の取り方は DAC によって違うため、届いた値から自動で見分けます。音量は送る直前に掛けるため、すぐに反映されます。
  • この間は、MP3・AAC も端末のデコーダー(MediaCodec)で PCM にしてから送り、すべての曲を reTONE が再生します。DAC を抜くと一時停止します。強制終了などで DAC が Android に返らなかった場合は、アップデートの直後と、「USB DAC の直接出力」がオフの状態で reTONE を開いたときに、Android に返します。

Android 4.1 世代の多くの端末は USB DAC を音声出力として扱えませんが、reTONE の直接出力は USB ホスト機能だけを使うため送れます。検証に使っている端末(2012 年、Android 4.1)と電池式の DAC の組み合わせで、24 bit/192 kHz を変換なしで再生できました。確認したのは USB Audio Class 2.0 の DAC で、Class 1.0 の DAC は未確認です。古い端末は USB に流せる電流が小さいため、バスパワーの DAC が認識されないことがあります。また、Wi-Fi の電波が USB ケーブル経由で DAC に入り、断続的なノイズになった例があります。再生に通信は要らないので、USB DAC で聴くときは機内モードにすることをおすすめします。

変換フィルター

0-20-40-60-80-100-120-1400102030 周波数(kHz) dB 20 kHz まで平ら 24.1 kHz から阻止域
44.1 kHz → 48 kHz の変換で使うフィルターの特性(アプリと同じ式で計算)。float で出す端末(目標 120 dB) 16 bit で出す端末(目標 100 dB)
  • 20 kHz まで平ら20 kHz までのずれは 0.001 dB 未満(計算値)。聞こえる範囲の音を減らしません。
  • 阻止域は 120 dB/100 dB 以上float で出す端末と 16 bit で出す端末での計算値です(44.1 kHz → 48 kHz で約 −122 dB/約 −102 dB)。30 kHz の信号を入れて測った折り返し(0〜20 kHz に現れる量、16 bit に丸める前)は、元の信号より 104.6 dB 以上小さい値でした。
  • 変換するときだけ −1 dB変換で 0 dBFS を超える点に備えます(手元の市販音源で測った最大は +0.59 dB)。変換しない曲より 1 dB 小さくなります。
詳しい説明

サンプルレート変換は、元のサンプルの間の波形を計算し直す処理で、フィルターの出来がそのまま音に出ます。reTONE のフィルターは、sinc 関数にカイザー窓(Kaiser window)をかけて作る FIR フィルターです。変換の比率に合わせて係数を組み分け、必要な分だけ計算するポリフェーズ構成にしています。設計の基準は「聞こえる範囲の音を減らさない」「変換で生じる折り返しを十分に抑える」の 2 つです。

  • 通過域:20 kHz まで平ら(設計値で ±0.001 dB 未満。44.1 kHz 以上の変換)。
  • 阻止域:「低いほうのレート − 20 kHz」から。44.1 kHz と 48 kHz の間なら 24.1 kHz から。この間に落ちる折り返しは 20 kHz より上に現れ、可聴帯域(20 kHz まで)には入りません。
  • 減衰(設計の目標):float で出す端末(Android 5 以降)は 120 dB、16 bit で出す端末(Android 4.x)は 100 dB。どの変換でも計算値が目標を上回るよう、フィルターの長さと窓を目標より 2 dB 余裕をもって設計しています(44.1 → 48 kHz の計算値は約 122 dB と約 102 dB)。16 bit の量子化雑音(ディザーを含め、全帯域で −93 dBFS 前後)より十分に下なので、100 dB の減衰で聞こえ方は変わりません。
  • タップ数:カイザー窓の式から減衰と遷移帯域で決めます(44.1 ↔ 48 kHz・120 dB で 86 タップ)。
  • 2 : 1 の段:96 → 48 kHz のようにちょうど半分にする段は、係数の半分が 0 で残りが左右対称な半帯域(ハーフバンド)フィルターを使い、掛け算を通常の約 4 分の 1 に減らします。192 → 48 kHz は半帯域を 2 段、88.2 → 48 kHz のような残りの比はポリフェーズ構成のフィルターで処理します。

測定では、1 kHz・19 kHz・19.9 kHz の信号は 0.01 dB 以内で同じ大きさでした。30 kHz の信号を入れたときに 0〜20 kHz に現れる折り返しは、44.1 kHz・48 kHz 出力で元の信号より 104.6 dB 以上、192 kHz からの変換では 116 dB 以上小さい値でした(16 bit に丸める前の測定)。これは 1 つの周波数での値で、阻止域全体は設計上、上の減衰の目標以上に抑えます。

変換は元のサンプルの間に新しい点を作るため、音圧の高い曲では 0 dBFS を超える点ができます。手元の複数の市販音源を 48 kHz に変換して測ると、超える点は全体の 0.0001〜0.001% で、最大 +0.38〜+0.59 dB でした。16 bit の出力や端末のミキサーでそこが頭打ちになるので、reTONE は測った最大値に余裕を持たせて、変換するときだけ 1 dB 下げます。変換しない曲はそのままなので、同じ端末では変換する曲が 1 dB 小さくなります。

音量は reTONE のエンジンの中では掛けず、Android のミキサー(AudioTrack の音量)で掛けます。エンジンの中で掛けると、AudioTrack にためてある約 500 ms 分が流れ終わるまで変化が届かず、音量キーの反応が鈍るためです。なお、出口が 16 bit の端末では、音量を下げると Android がもう一度 16 bit に丸めます(このとき Android はディザーをかけません)。

計算は C で書き、ARM の NEON 命令で左右のチャンネルを同時に処理します。フィルターの内側のループは係数をベクトルで読み、4 本の累積で遅延を隠します。ディザーも乱数・丸め・クリップ・誤差の帰還まで NEON の中で行い、古いコア(Cortex-A9)で遅い NEON と汎用レジスタの行き来をなくしています。

豆知識Android の変換の品質は、メーカーが選んでいます

Android の中でサンプルレートを変換する部品には、品質の段階がいくつか用意されています。簡単な計算で済ませる段階から、計算を多く使って精度を上げる段階までがあり、どれを使うかは端末の設定で決まります。この設定を決めるのは、端末を作るメーカーです。

Android 5 以降でメーカーが設定していない端末では、中くらいの DYN_MED が使われます(Android 4.4 では、いちばん簡単な LOW が使われます)。また、同時に使われる変換器の見積もりの負荷が上限を超えると、超えた分は 1 段下の段階に下がります(実際の CPU の負荷を測っているわけではありません)。確認した端末では、Android 4.4 の 2 台の設定値が 4(VERY_HIGH)で、Android 9 の 1 台は設定がなく、DYN_MED でした。同じ曲でも、端末によって変換の品質が違うことになります。

設定の値段階変換のしかた(Android 本体の場合)折り返しの抑え
1LOW前後の 2 点を直線でつなぐだけの、いちばん軽い計算。Android 4.4 で設定がないときはこれ専用のフィルターなし
2MED前後の数点を曲線でつなぐ計算専用のフィルターなし
3HIGHsinc 関数のフィルターを使う計算ソースに記載なし
4VERY_HIGHHIGH より長いフィルターを使う計算。係数は端末の部品(libaudio-resampler.so)から読み込み、ない場合は HIGH と同じソースに記載なし
5DYN_LOW変換の比率に合わせてフィルターをその場で作る計算80 dB
6DYN_MED同上。DYN_LOW より長いフィルター84 dB
7DYN_HIGH同上。いちばん長いフィルター98 dB
設定なし—Android 5 以降は DYN_MED を使う(Android 4.4 は LOW)。同時に多く使われると、1 段下の段階に下がる84 dB
reTONE—端末の設定に左右されない設計。20 kHz まで平ら(減衰の目標は出力の形式で異なる)100 dB(16 bit 出力)
120 dB(float 出力)

設定の名前は af.resampler.quality です。表は Android 13 の Android 本体のソースによるもので(Android 4.4 の欄は Android 4.4 のソースによる)、メーカーが手を加えている場合は、この表のとおりとは限りません。「折り返しの抑え」は、どれもフィルターの設計の目標値です。reTONE は、どの変換でも計算値が目標を上回るように設計しています。

reTONE が変換を受け持つ場面では、この設定にかかわらず、reTONE の変換が使われます。

USB DAC の音量

音量を下げる場所は 3 つあります。どこで下げるかは、DAC の作りと、最初につないだときの選択で決まります。

reTONE の中デジタルDAC のデジタル音量USB 経由で操作DAC 本体つまみ・ボタン
USB 経由で音量を操作できる DAC最大で送る音量キーで動く—
操作できない DAC音量キーで動く——
「DAC 本体で調整」を選んだとき最大で送る最大本体で調整
詳しい説明

音量を下げる場所は 3 つあります。① reTONE の中でデータに掛ける(デジタル)、② DAC の中のデジタル音量を USB 経由で動かす、③ DAC 本体のつまみやボタンです。①と②は reTONE が自動で選び、③の有無だけ利用者に尋ねます。

② USB 経由の音量:USB Audio Class には Feature Unit という音量の仕組みがあり、GET RANGE で最小・最大・刻み(単位は 1/256 dB)を読めます。reTONE の音量(Android の段階と細かい音量を合わせた 1 つのゲイン)を dB に直し、この範囲の中なら DAC に送って、reTONE 側は最大のまま送ります。範囲より下に下げるときだけ、足りない分を①で PCM に掛けます。0 はミュートです。

① reTONE の中:Feature Unit の音量がない DAC では、32 bit のデータに reTONE が音量を掛けてから送ります。送る直前に掛けるので、音量キーの反応はすぐです。

③ DAC 本体:本体に音量があるかは USB から読めません。そこで DAC を初めてつないだときに「DAC の音量の調整方法」(DAC 本体で調整/スマホの音量キーで調整/わからない)を 1 回だけ尋ねます。「DAC 本体で調整」を選ぶと、②も①も最大に固定し、音量キーを押しても変化しません(その旨を表示します)。アナログボリュームの DAC では、デジタルで絞らないぶん DAC の性能を活かせます。選択は DAC の機種(USB のベンダー ID と製品 ID)ごとに記憶し、設定の「DAC の音量」で変更できます。

「DAC 本体で調整」のとき、または DAC の音量を使う場合(DAC の音量の範囲内)は、DAC が対応するレートなら、曲のデータを変えずに送ります。DAC の音量の範囲より小さい音量にしたときだけ、残りを reTONE が掛けます。ただし端末や DAC の側で何が起きるかまでは確かめられないため、ビットパーフェクトであることは保証できません。

ネイティブ DSD

DSF・DFF の曲
DAC が ネイティブ DSD に対応
かつ USB 経由で音量を操作できる
かつ「DSD の送り方」が「DSD のまま送る」
はいDSD のまま送る例:DSD64 → USB AUDIO • DSD64 DIRECT
いいえPCM に変換して送るDSD64 なら 88.2 kHz の PCM

reTONE の中では DSD の音量を変えられないため、DAC 側で音量を操作できることが条件です。DSD の曲で音が途切れる場合は、設定の「DSD の送り方」で「PCM に変換して送る」を選んでください。DoP には対応していません。

詳しい説明

DSF・DFF の曲は、DAC が「ネイティブ DSD に対応し、かつ USB 経由で音量を操作できる」ときだけ、PCM に変換せず DSD のまま送ります。reTONE の中では DSD の音量を変えられないので、音量を DAC 側で操作できることが条件です。再生画面には「DSD64 → USB AUDIO • DSD64 DIRECT」のように表示されます。

送り方は次のとおりです。

  • ネイティブ DSD は、USB の記述子で生データ用(TYPE I の RAW DATA)の代替設定を持つ DAC で使えます。
  • 1 ch あたり 32 bit の語に DSD のビットを 4 バイトずつ詰め、古いビットを上位に置きます。DSF はファイル内のビット順が LSB 先頭なので、ビットを反転してから詰めます。語はビッグエンディアンで送ります(Linux の DSD_U32_BE と同じ想定)。この詰め替えは C で行い、転送のリングバッファは約 500 ms です。
  • DAC のクロックは「DSD のレート ÷ 32」に設定します(DSD64 なら 88.2 kHz、DSD128 なら 176.4 kHz)。
  • 無音・一時停止中・曲の終わりは、DSD の無音パターン 0x69 で埋めます。

このバイト順・ビット順は、確認した DAC で正しく鳴ることで確かめました。ほかの DAC での確認はまだなく、DoP(DSD over PCM)には対応していません。DST 圧縮の DFF も読めません。

DSD の送り方(設定):ネイティブ DSD を使える DAC をつないでいるときだけ、設定の「音」に「DSD の送り方」が出ます。「DSD のまま送る(DAC が DSD を直接再生します)」が初期値で、「PCM に変換して送る(reTONE が PCM に変換します)」に切り替えられます。DSD の曲で音が途切れる場合や、PCM での再生を好む場合は、PCM に変換して送ってください。選択は DAC の機種ごとに記憶し、切り替えると今の曲を同じ位置で開き直します。規格の目安(50%)を超える振れ幅の DSD 音源で、一瞬音が途切れる DAC がありました(転送は正常で、DAC 側の設計によるものとみられます)。その場合も PCM に変換すれば途切れません。

DSD → PCM の変換:ネイティブ DSD を使わないとき(条件を満たさない DAC、「PCM に変換して送る」を選んだとき、Bluetooth・イヤホン・スピーカーへの出力)は、reTONE が DSD を PCM に変換します。2 段階です。

  • 1 段目:DSD のビット列を 1/32、1/64…に間引いて、約 88.2 kHz かそれ以上の PCM にします(DSD64 は 1/32 で 88.2 kHz、DSD128 は 1/64 で 88.2 kHz)。フィルターはカイザー窓を使った FIR フィルターで、通過域は 20 kHz と「出力レートの 1/4」の大きいほう、阻止域は「出力レート − 通過域」から、減衰は 16 bit 出力で 100 dB、float・USB で 110 dB です。タップ数は カイザー窓の式で決めます。計算は 16 bit 単位の表引きで、表は設定ごとに 1 回作って使い回します。測定では 20 kHz で 0.000 dB、20 kHz 以下への折り返しは −101 dB(100 dB 設計)/−110〜−117 dB(110 dB 設計)でした。
  • 2 段目:必要なら、変換フィルターの節と同じリサンプラーで端末の出力レートへ一度だけ変換します(本体の 44.1 kHz・48 kHz 出力など)。
  • 大きさ:SACD の 0 dB(変調 50%)が −6 dBFS になるように変換します(一般的な換算。0.69.0 から。それより前のバージョンでは −12 dBFS で、6 dB 小さく鳴っていました)。

USB DAC に PCM で送るときは、「DSD のレート ÷ 32」(DSD64 なら 88.2 kHz、DSD128 なら 176.4 kHz、DSD256 なら 352.8 kHz)の PCM を、DAC が対応していれば 2 段目の変換なしでそのまま送ります。この場合は DSD から PCM への変換があるので、DIRECT とは表示しません。

負荷

検証に使っている端末(2012 年、Android 4.1、2 コア)での、1 コアに対する reTONE の CPU 使用率です。

再生画面の描き直し(実際の再生中)約 2%
CD 音源をそのまま出力(最高クロック換算)約 2%
24 bit/192 kHz を 44.1 kHz に変換(最高クロック換算)約 10%
0%50%100%

「再生画面の描き直し」は実際の再生中に測った値で、曲のデコードは含みません。ほかの 2 つは、reTONE のエンジンの同じ計算を最高クロックで動かし、実時間に対する割合に直した値です。実際の再生中は端末がクロックを下げるため、端末上の表示では 2〜3 倍に見えます。

詳しい説明

reTONE は「止まっているときは何もしない」「画面を消して再生している間は、描画をしない」を目標にしています。定期処理は再生中だけで、画面オンでは 1 秒、画面オフでは 5 秒ごと、再生画面のシークバーは 250 ms ごとに自分だけを描き直します。時計やバッテリーの更新は、システムからの通知で動かし、ポーリングはしません。

検証に使っている端末(2012 年、Android 4.1、Cortex-A9 2 コア)での、1 コアに対する reTONE の CPU 使用率です。

  • 止まっているとき:0%。
  • 再生中に画面を消している:描画は止まります。Android の標準の再生で鳴らす曲ではほぼ 0% で、reTONE のエンジンで再生する曲(Android 4.x の FLAC・WAV など)では、下のデコードと変換の分がかかります。
  • 再生画面を表示して再生中:約 2%(実際の再生中に測った値。大半はシークバーの描き直しで、曲のデコードは含みません)。
  • reTONE のエンジンで CD 音源(16 bit/44.1 kHz)を 44.1 kHz にそのまま出力:約 2%。48 kHz に変換して出力:約 4%。
  • 24 bit/96 kHz を 48 kHz に変換:約 5%。44.1 kHz に変換:約 7%。
  • 24 bit/192 kHz を 44.1 kHz に変換:約 10%(計算部分のみ)〜約 15%(再生時の全体を最高クロックに直した概算)。
  • USB DAC へ 24 bit/192 kHz を変換なしで送る:約 20%(実際の再生中に測った値。画面オン、転送のスレッドを含む)。

「CD 音源」から「24 bit/192 kHz」までのエンジンの数値は、同じ計算を最高クロックで全速で動かし「実時間の何 % か」に直した値です。実際の再生中は端末がクロックを 200 MHz〜1 GHz の間で下げるため、端末上の表示では 2〜3 倍(24 bit/192 kHz で 20% 台)に見えます。書き方による差も大きく、同じ処理を Java で書いた試作に比べて、C と NEON で書いた今の実装は約 3〜5 分の 1 の負荷でした。

DSD を PCM に変換する場合は、2012 年の端末と電池式の DAC の組み合わせで、DSD64 を 88.2 kHz の PCM にして USB へ送ったとき、変換が約 11.8%、USB の転送が約 5.8% でした(クロックは約 1 GHz)。Android 4.4 の端末で本体の出力(48 kHz)に DSD64 を鳴らしたときは、デコード用スレッドが 23.8% でしたが、端末がクロックを最低の 300 MHz に下げたままだったため、クロックの比で単純に直すと、最高クロックでは約 3% に当たります。

確認した端末では、画面を表示しているときの負荷は、CPU の速さよりも画面の解像度で差が出ました(Android 4.x では、小さな部分の更新でも画面全体を描き直しているとみられます)。1080 × 1920 の端末では再生画面で約 4%、1440 × 3120 の Android 11 の端末では約 8.5%(8 コアのうちの 1 コアに対して。端末全体では約 1%)でした。古い端末は画面が小さく、高解像度の端末は処理能力も高いため、今のところ描き直しの回数は全端末で同じにしています。

動作を確認した端末

端末Android確認した内容
WALKMANSony NW-Z1000 シリーズ4.0.4起動、画面の表示
Xperia PSony LT22i4.1.2主な機能を一通り
AQUOS PHONE ZETA(docomo)SHARP SH-02E4.1.2主な機能を一通り
Acoustic Research AR-M204.3起動、24 bit/96 kHz の FLAC の再生
AQUOS CRYSTAL(SoftBank)SHARP 305SH4.4.2主な機能を一通り
URBANO L03(au)KYOCERA KYY234.4.2主な機能を一通り
Xperia Z4 Tablet(au)Sony SOT315.0.2主な機能を一通り
VAIO Phone AVAIO VPA0516.0.1起動、再生
Nexus 6Motorola Nexus 67.1.1起動
Galaxy S8(docomo)Samsung SC-02J9主な機能を一通り
Xperia XZ1Sony G83419起動
Android One X5(Y!mobile)LG X5-LG11主な機能を一通り
Galaxy A41(docomo)Samsung SC-41A12起動、ライブラリ、再生
Pixel 3 XLGoogle Pixel 3 XL12起動
Galaxy Z Fold5 フィールドテストSamsung Galaxy Z Fold516起動、折りたたみの画面の表示
Pixel 10a フィールドテストGoogle Pixel 10a17起動
Pixel 11 Pro Fold フィールドテストGoogle Pixel 11 Pro Fold17起動、折りたたみの画面の表示

フィールドテスト 開発に協力してくれている有志が、自分の端末で試した結果です。

USB DAC の直接出力を試した組み合わせ

端末USB DAC結果
Galaxy S8Android 9Hidizs S9 Proバスパワー動作。PCM(DAC が申告した対応レートは 44.1〜768 kHz。44.1〜192 kHz の曲で確認)、ネイティブ DSD、DAC の音量
Galaxy S8Android 9OPPO HA-2電池式動作
AQUOS PHONE ZETA SH-02EAndroid 4.1OPPO HA-2電池式動作。24 bit/96 kHz を変換なしで再生
AQUOS PHONE ZETA SH-02EAndroid 4.1Hidizs S9 Proバスパワー動作。再生の速さのずれ、途切れなし
Android One X5Android 11Hidizs S9 Proバスパワー動作
Xperia PAndroid 4.1OPPO HA-2電池式動作。24 bit/192 kHz と 96 kHz を変換なしで再生
Xperia PAndroid 4.1Hidizs S9 Proバスパワー認識しない。端末の給電が足りない
URBANO L03Android 4.4OPPO HA-2電池式使えない。Android は USB ホスト機能ありと申告するが、OTG で親にならない
AQUOS CRYSTAL 305SHAndroid 4.4—使えない。USB ホスト機能がない

USB DAC と端末の相性

USB DAC への直接出力は、端末と DAC の組み合わせで動きに差が出ます。スマートフォンの中で USB の親機の役割をする部品(ホストコントローラ)は、時代とメーカーによって作りが異なり、音楽のように一定の速さで途切れずに送る通信(等時転送)では、その違いが表に出やすいためです。DAC の側も、音を受け取る間隔、送る速さの伝え方、電源の取り方がそれぞれ異なります。reTONE は機種名で処理を分けず、つないだときの実際の動きを測って合わせます。下の表のうち、musb・EHCI・xHCI は実機で確かめた系統で、ほかは公開されている資料からの見込みです。

部品の系統起きやすいことreTONE の対応
musb2010〜2013 年ごろの一部の端末(TI、ST-Ericsson、古い MediaTek など)送るデータの間に空きができ、DAC に届く量がわずかに足りなくなる(プツプツ・途切れ)実際にデータが戻る間隔を測り、足りない分を多めに詰める
EHCI古い Qualcomm、Tegra、一部の Exynos完了の知らせがまとめて返り、追いつけないと一部を飛ばす長い時間の平均で判断する
DWC2古い Rockchip、一部の Kirin・Amlogic のタブレットなど4 バイト単位にそろっていないデータで雑音が出ることがある32 bit(4 バイト)の形式を優先する
xHCIUSB-C の端末のほとんど(2015 年ごろ以降)完了の知らせがまとめて返り、遅れると一部を飛ばす長い時間の平均で判断し、先に送っておく量を確保する
MediaTek の xHCI新しい MediaTek の端末帯域の割り当てが厳しく、高いサンプルレートの設定を受け付けないことがある未対応
  • 音を受け取る間隔:多くの DAC は 0.125 ms ごと、一部は 0.25 ms や 1 ms ごとです。reTONE は間隔に合わせて 1 回に送る量を変えます。
  • 送る速さの伝え方:多くの DAC は「この速さで送ってほしい」と端末に伝えます(非同期方式)。伝え方は機器ごとに異なりますが、reTONE は多くの DAC の伝え方に自動で合わせます(0.88.0 以降)。伝える口がなく、端末の送る速さに合わせる DAC(アダプティブ方式)もあります。
  • 電源:電池や電源を持つ DAC と、端末の電気だけで動く DAC(バスパワー)があります。バスパワーの DAC は、古い端末では電気が足りずに認識されないことがあります。電源を持つ DAC でも、端末から充電されて端末の電池が早く減ることがあります。
  • DSD:DSD をそのまま受け取れる DAC の多くは同じ並べ方(32 bit、ビッグエンディアン)ですが、例外もあります。

メーカーの音響設定

下部メニューの「サウンド」は、端末にメーカーの音響設定の画面があればその画面を、なければ Android の音の設定を開きます。開く先は、設定の「音響設定」で選べます。

端末開く画面
SHARP AQUOS CRYSTAL 305SHHarman Clari-Fi/LiveStage
KYOCERA URBANO L03(KYY23)Dolby
Sony Xperia Pサウンドエフェクト(イコライザー、ClearBass、VPT、xLOUD など)
LG Android One X5音質とサウンドエフェクト(Hi-Fi Quad DAC、デジタルフィルター、DTS:X など)
Samsung Galaxy S8SoundAlive

メーカーの設定が reTONE の再生に反映されるかは端末によります。

対応していないこと

  • イコライザー、音量の正規化、クロスフェード、波形表示は搭載していません。軽さを優先し、音に効果をかけない方針のためです。
  • 歌詞の表示には対応していません。
  • ストリーミングの再生そのものは行いません。配信アプリを開くまでが reTONE の役目で、再生とその音質はそのアプリと端末によります。
  • 初期設定では通信しません。設定の「ネットワーク機能」をオンにした場合だけ、利用者が操作したときと、設定で選んだ確認のときに通信します。利用者の情報は収集しません。
  • Android Auto や Wear OS からの操作には対応していません(通知、Android のロック画面、Bluetooth 機器からの再生操作には 0.87.0 から対応しています)。
  • DST 圧縮の DFF、APE、WMA ロスレスは、reTONE のエンジンでは再生できません。対応の予定もありません。FLAC などに変換してお使いください。
  • Android 3.x 以前では動作しません。
  • USB ホスト機能(OTG)のない端末では、USB DAC の直接出力は使えません。設定の「USB DAC の直接出力」が薄く表示され、「この端末は USB 機器の接続に対応していません」と出ます。
  • USB DAC の直接出力を確認した端末と DAC の組み合わせは限られます。ほかの端末や DAC で使えるかは確認していません。Android が「USB ホスト機能あり」と申告していても、OTG で親になれない端末があります。確認した組み合わせの一覧は「USB DAC の直接出力を試した組み合わせ」にあります。
  • DoP には対応していません。ネイティブ DSD は、DAC がネイティブ DSD に対応し、かつ USB 経由で音量を操作できる場合に限ります。それ以外の DAC では、DSD を PCM に変換して送ります。
  • USB DAC の直接出力中、ほかのアプリの音は USB DAC からは鳴りません。本体のスピーカーから鳴ります。
  • ビットパーフェクトであることは保証できません。端末がどう出力したかをアプリから確かめる手段がないためです。
  • 端末に内蔵された DAC への音声経路を変更する処理(サンプルレート変換の回避、オフロード再生の強制など)は行いません。root や端末メーカーの署名が必要なためです。
  • 画面が消えている間の音量キーの長押しによる連続変化や曲送りには対応していません。Android がキーをアプリに渡さないためです。
  • プレイリストの書き出し(M3U など)と、Android 共通のプレイリストの読み込みには対応していません。
  • タグの編集、ファイルの削除や移動には対応していません。
  • 現時点では Google Play では配布していません。