blootoothchecker でイヤホン遅延を測定している様子

blootoothchecker – Bluetooth / 有線イヤホンの実測オーディオ遅延を測るテストアプリ

「この Bluetooth イヤホン、ゲームで遅くない?」 その感覚を、実測したミリ秒で確かめるためのテストアプリです。 スマホからテスト信号を鳴らし、マイクで取り込んだ音とのズレを計測することで、 Bluetooth / 有線 / スピーカーの実際のオーディオ遅延を可視化します。

作品の説明

blootoothchecker は、オーディオの「体感ラグ」を定量化するための実験用アプリです。 スマホで短いクリック音やチャープ信号を再生し、 イヤホンから出た音をスマホのマイクで拾って、 元の波形と録音波形のズレ(サンプル差) を計算します。

計測結果は「平均遅延」「最小・最大」「ばらつき」として保存され、 有線 / Bluetooth(SBC / AAC / LDAC …)や機種ごとの違いを比較できます。 ゲーム・配信・音ゲーなど、レイテンシがクリティカルな用途のための ベンチマークとして使うことを想定しています。

  • ① テスト信号(クリック/チャープ)を生成してイヤホンから再生
  • ② スマホのマイクでその音を録音
  • ③ 元信号と録音信号の相互相関を計算
  • ④ ピーク位置から「サンプル差 → ミリ秒」に変換
  • ⑤ 複数回の測定から平均・分散を集計
  • ⑥ Bluetooth / 有線 / スピーカーなどを切り替えて比較

システム概要

blootoothchecker の信号フロー図

アプリ内部では、AudioTrack でテスト信号を出力し、 AudioRecord でマイク入力を同時に取得します。 取得した 2 つの波形を Kotlin 側でバッファリングし、 相互相関(cross-correlation)でピークを求めることで遅延を推定します。

技術スタック

  • Android / Audio: Kotlin, AudioTrack, AudioRecord, AudioManager
  • Signal Processing: 相互相関, 窓関数, ピーク検出
  • UI: Jetpack Compose(測定ボタン・結果一覧・グラフ表示)
  • Persistence: Room / ローカル JSON ログ(デバイス別の測定履歴)

主要コンポーネント

  • SignalGenerator: インパルス / 正弦波チャープなどのテスト信号を生成するユーティリティ。
  • LatencyMeasurementEngine: 再生・録音の制御と、相互相関による遅延推定ロジックをまとめたコアクラス。
  • MeasurementRepository: 測定結果(デバイス名 / 接続種別 / 平均遅延 / 回数)を保存・読み出しする層。
  • ResultChartView: イヤホンごとの遅延を棒グラフ・ヒストグラムとして表示する Compose コンポーネント。

技術解説

SIGNAL DESIGN

クリック / チャープ信号で「位置が特定しやすい」波形に

遅延測定では、あとから位置を特定しやすい信号が重要です。 blootoothchecker では、立ち上がりの鋭いクリック音や、 周波数をスイープするチャープ信号を使うことで、 相互相関のピークがシャープになりやすいように設計しています。

擬似コード:テスト信号生成
val fs = 48000
val length = 2048
// 例: 簡易インパルス
val impulse = FloatArray(length).apply { this[0] = 1f }
// 例: チャープ信号(省略)
AUDIO I/O

AudioTrack / AudioRecord を合わせて扱う

Android のオーディオスタックは OS 側でもバッファを持つため、 「完全なサンプル同期」は難しいです。 blootoothchecker では、再生開始と録音開始のタイミングをできるだけ揃えつつ、 録音側にテスト信号が現れるまで十分なバッファを確保して解析しています。

LATENCY ESTIMATION

相互相関で「ズレ」をサンプル単位で求める

録音波形 y[n] と元信号 x[n] に対して、 相互相関 R_xy[k] = Σ x[n]·y[n+k] を計算し、 最大値を取るシフト量 k* を求めます。 これを k* / fs 秒として、実測遅延としています。

擬似コード:
fun estimateDelayMs(x: FloatArray, y: FloatArray, fs: Int): Float {
 // 簡易な相互相関(実装は最適化可)
 var bestK = 0
 var bestVal = Float.NEGATIVE_INFINITY
 for (k in 0 until maxLag) {
  var sum = 0f
  for (n in x.indices) {
   if (n + k < y.size) sum += x[n] * y[n + k]
  }
  if (sum > bestVal) { bestVal = sum; bestK = k }
 }
 return bestK * 1000f / fs
}
STATS & LOGGING

複数回の測定から平均・ばらつきを見る

遅延は毎回完全に同じではないので、 同じデバイス・同じ接続方法で複数回測り、 平均・標準偏差・最小/最大などを保存します。 これにより、「たまたま遅かった」のか 「そもそもレイテンシが大きい」のかを切り分けやすくしています。

実験・結果・課題

有線 vs Bluetooth の実測例

手元のスマホとイヤホンで、 有線イヤホン / Bluetooth イヤホン(SBC / AAC)を何度か測定したところ、 おおよそ以下のような傾向が見られました(あくまで一例です)。

イヤホン種別ごとの遅延グラフ
(a) イヤホン種別ごとの平均遅延(例)
遅延分布のヒストグラム
(b) 同じ Bluetooth イヤホンでの遅延分布(例)

「Bluetooth はなんとなく遅い」ではなく、 実際に ○○ms 遅い / ばらつきがこれくらい と数字で見えると、 用途に応じたデバイス選びがしやすくなります。

現在の課題

・スマホの内部バッファや OS レベルの遅延も含んだ値になるため、  「絶対値」としては限界があること ・周囲の騒音やマイクの位置により測定が不安定になること ・リアルタイムグラフ表示を滑らかにしつつ、バッテリー消費を抑える必要があること など、実験ツールならではの難しさもあります。

スマホ内部遅延のキャリブレーションは未実装 サンプル数を増やして統計的に補正する予定

デモ動画

実際にイヤホンを接続して測定を行い、 結果がリアルタイムで更新されていく様子を撮影したデモ動画です。

blootoothchecker – 測定とグラフ更新の様子

まだできていない部分と今後

「測るだけ」から「チューニングツール」へ

blootoothchecker は現状、オーディオ遅延を測るだけのツールです。 しかし今後は、測定結果をもとに 「このゲームは有線推奨」「この遅延なら音ゲーは厳しい」など、 用途別の目安も提示できるようにしていきたいと考えています。

  • 短期: 測定プロファイル(ゲーム / 動画 / 配信)プリセットの追加。
  • 中期: 測定結果から「用途ごとの向き・不向き」を簡単に表示。
  • 長期: 他のオーディオツール(スペクトログラム / F0 チェッカー)と連携し、 総合的なオーディオ研究アプリ群の一つに。

これからの改善点と開発計画

計測精度・使いやすさ・解釈のしやすさをバランスよく伸ばしていく予定です。

  • 計測精度: 自動ゲイン調整、ノイズ除去、キャリブレーション手順の追加。
  • UX: 測定ウィザード、測定中の視覚的フィードバック改善。
  • 共有: 結果のエクスポート(画像 / CSV)や共有リンクの生成。
17
18
19
20
21
22
23
24
25
26
27
28
29
30
キャリブレーション手順の設計・実装
用途別プロファイル UI の追加
結果エクスポート / 共有機能

このプロジェクトを通して

感じていること

オーディオの世界では、「なんとなく遅い」「気のせいかも」という 感覚ベースの議論が多くなりがちです。 blootoothchecker を作る過程で、 「体感」を「データ」に変換することの大切さを改めて実感しました。

一方で、計測の前提や限界(スマホ内部遅延 / ノイズ / 計測環境)もはっきり見えてきて、 「数字が出たから正しい」というわけではないことも学びました。 それでも、自分の耳と数値の両方を並べて考えられるようになったのは、 この小さなテストアプリのおかげだと思います。

今の自分へのメモ

  • ・オーディオの“体感”は大事にしつつ、それを裏付けるデータを自分の手で取り続けること。
  • ・測定ツールを作るときは、「何を含んだ値か」をユーザーにちゃんと説明すること。

リファレンス & リンク

リファレンス

  • Android Developers – AudioTrack / AudioRecord ガイド
  • Basic audio latency measurement methods(一般的な遅延測定手法に関する資料)
  • 信号処理入門 – 相互相関・チャープ信号

リンク