ハプティクス フレームワークのための UX の基礎

Android フレームワークで行われてきたハプティクス関連のあらゆる改善は、それと同じ速度で進化を続ける UX の方針によっても後押しされています。現在の方針では、耳障りなバイブレーションからクリア ハプティクスへの進化や、リッチ ハプティクスの模索が行われています。

UX の方針

図 1. 現在の方針

次の表に、使用可能なハプティクス API を示します。

API メソッド 追加した年
android.view.HapticFeedbackConstants
  • CONTEXT_CLICK
  • CLOCK_TICK
  • VIRTUAL_KEY
  • KEYBOARD_TAP
  • LONG_PRESS
2016 年以前
  • KEYBOARD_PRESS
  • KEYBOARD_RELEASE
  • TEXT_HANDLE_MOVE
  • VIRTUAL_KEY_RELEASE
2017 年(Android 8)
  • CONFIRM
  • REJECT
  • GESTURE_START
  • GESTURE_END
2020 年(Android 11)
android.View
  • performHapticFeedback()
2016 年以前
android.os.Vibrator
  • vibrate()
  • hasVibrator()
2016 年以前
  • hasAmplitudeControl()
2017 年(Android 8)
  • areAllEffectsSupported()
  • areAllPrimitivesSupported()
  • areEffectsSupported()
  • arePrimitivesSupported()
2020 年(Android 11)
android.os.VibrationEffect
  • createOneShot()
  • createWaveform()
2017 年(Android 8)
  • EFFECT_TICK
  • EFFECT_CLICK
  • EFFECT_HEAVY_CLICK
  • EFFECT_DOUBLE_CLICK
  • createPredefined()
2019 年(Android 10)
android.os.VibrationEffect.Composition
  • PRIMITIVE_TICK
  • PRIMITIVE_CLICK
  • addPrimitive()
  • compose()
2020 年(Android 11)
android.media.AudioAttributes.Builder
  • setHapticChannelsMuted()
2019 年(Android 10)

うるさいバイブレーション

ポケットベルやフィーチャー フォンの時代には、低品質ながらも電力効率の高い ERM ブザーベースのバイブレーションが、サイレント モードの着信音の代用として使われていました。大音量で不快な可聴ノイズを発生させる従来のハードウェア コンポーネントは、低品質な印象(安くて壊れた電話など)を与え、触覚 UX に悪影響を及ぼす可能性があります。

クリア ハプティクス

クリア ハプティクスは、非連続の状態変化(電源オン / オフなど)の感覚をサポートします。非連続なアフォーダンスの性質上、クリア ハプティクスは単一のエンティティとして生成されます(たとえば、入力イベントごとに触覚効果が 1 つ生成されます)。

Android は、うるさい、安っぽいといった感覚よりも、強力かつシャープな感覚の触覚を提供することを目指しています。

クリアな触覚をサポートするために作成された事前定義済みの触覚定数には、次のものが含まれます。

HapticFeedbackConstants 内:

  • CLOCK_TICK
  • CONFIRM
  • CONTEXT_CLICK
  • GESTURE_END
  • GESTURE_START
  • KEYBOARD_PRESS
  • KEYBOARD_RELEASE
  • KEYBOARD_TAP
  • LONG_PRESS
  • REJECT
  • TEXT_HANDLE_MOVE
  • VIRTUAL_KEY
  • VIRTUAL_KEY_RELEASE

VibrationEffect 内:

  • EFFECT_CLICK
  • EFFECT_DOUBLE_CLICK
  • EFFECT_HEAVY_CLICK
  • EFFECT_TICK

デバイス メーカーとデベロッパーの間で共通の知識を構築することは、Android エコシステムにおける触覚の全体的な品質向上において重要です。基本チェックリストハードウェア評価CDD を使用して、触覚の実装の詳細をご確認ください。

ボタンの押下とリリース

図 3. ボタンの押下とリリース

リッチ ハプティクス

リッチ ハプティクスは、単一のインパルス ベースの効果を超えるハプティクス カテゴリであり、現在も進化を続けています。Android では、組み合わせや調整が簡単で、滑らかな粒度を持つ、リッチな触覚をサポートすることを目指しています。Android 11 以下では、次のユースケースがサポートされています。

リッチ ハプティクス

図 4. スライドのテクスチャを使用したリッチ ハプティクス

ドラッグとスワイプ

図 5. ドラッグとスワイプ

ユースケース 1: スライドするときのテクスチャ

指をタッチ面でスライドさせる動作(ファントム触覚テクスチャをトリガーする、サーフェスでのドラッグ、スワイプ、移動など)によって触覚効果が繰り返される場合、繰り返される触覚効果はクリアで繊細であることが好まれます。

個々の効果がクリアではなくうるさい場合は、個々の効果の繰り返しの間隔がなくなってしまう可能性があります。その結果、複数の個別のシグナルではなく、1 つの長いうるさいシグナルになってしまいます。

振幅が十分に小さくない場合、認識されるハプティクス エネルギーは繰り返しによって増大し、繰り返しの最後には著しく強い触覚が発生します。

スワイプとドラッグのジェスチャーに対するシンプルなサーフェス ハプティクス テクスチャの実装

HapticFeedbackConstantsCLOCK_TICKTEXT_HANDLE_MOVE を使用します。これらの定数は、繰り返しと振幅の特性を事前定義します。

独自の効果の作成

独自の効果を作り出すには、VibrationEffect.CompositionPRIMITIVE_CLICKPRIMITIVE_TICK のシーケンスをつなぎ合わせて、デザインを作成します。addPrimitive(int primitiveID, float scale, int delay) を使用すると、繰り返しの特性と振幅の特性を調整できます。サポートは、Vibrator HAL インターフェースCAP_COMPOSE_EFFECTS 機能に依存します。

ユースケース 2: イーズイン効果を使用したロング バイブレーション

ロング バイブレーションは、0 から目的の振幅に滑らかに移行する振幅振動です。ロング バイブレーションは、認識可能な触覚を容易に生成できます。しかし、突然のロング バイブレーションは、静かな環境でユーザーを驚かせてしまう場合があり、耳障りな可聴ノイズを発生させてしまうことも少なくありません。より心地よいロング バイブレーションを生成するには、ロング バイブレーションの開始時にイーズイン効果を適用します。これにより、目的の振幅まで滑らかに振幅を移行させることをできます。

イーズイン効果の適用

  1. android.os.Vibrator.hasAmplitudeControl() を使用して振幅制御のハードウェア機能を確認します。

    • 振幅が変化するイーズイン効果を作成するには、結果が true である必要があります。
  2. VibrationEffect.createWaveform(timings[], amplitudes[], int repeat) を使用します。

  3. timings[]amplitudes[] を調整して、図 6 に示すようにイーズイン曲線を生成します。

ロング バイブレーション

図 6. ロング バイブレーションのイーズイン曲線

ユースケース 3: 音声と組み合わせた触覚

音声と組み合わせた触覚は、音声のリズムと組み合わせた触覚パターンであり、ユーザーの注意を引き付けることができます。

音声と組み合わせた触覚: メリット

音声と組み合わせた触覚を実装するには、クリア ハプティクスとロング バイブレーションを組み合わせます。クリア ハプティクスの強力かつ短い触覚は、独特のリズムパターンを生成します。ロング バイブレーションが生み出す強い刺激と組み合わせることで、ユーザーの注意を引き付けることができます。

こうした触覚はリズムパターンであると捉えることが重要です。リズムが不自然であれば、ユーザーは触覚をランダムでうるさいものとして認識し、無視するようになります。

音声との組み合わせ

図 7. 音声と組み合わせた触覚の例

音声と組み合わせた触覚: 実装のヒント

音声と組み合わせた触覚を実装する場合は、音声チャンネルと触覚チャンネル両方のコンテンツ再生についての基本的な知識が必要です。以下の点に注意する必要があります。

  • MediaPlayer クラスまたは SoundPool クラスを使用します。

    • 特殊なメタデータキーを持つ OGG 形式のアセット(ANDROID_HAPTIC の後に多くの触覚チャンネルが続く形式)は、MediaPlayerSoundPool を使用したハプティクス データおよび再生の存在を示します。
  • audio_policy_configuration.xml での触覚と音声再生のサポートを示します。

    • 触覚チャンネル AUDIO_CHANNEL_OUT_HAPTIC_A|B を含む出力プロファイルを使用します。
    • 触覚チャンネルを含む出力ストリームの場合は、その触覚チャンネルはデータ内で追加のチャンネルとして示されます。

    出力ストリームのチャンネル マスクが次の場合、

    AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A

    すべてのサンプルは次のようになります。

    AUDIO_LEFT_CHANNEL,AUDIO_RIGHT_CHANNEL,HAPTIC_CHANNEL_A

  • AudioAttributes.Builder( ).setHapticChannelsMuted(boolean muted)false に変更し、触覚チャンネルを再生します。

    • デフォルトでは、触覚チャンネルはミュートされています(true)。
    • ユースケースには、同期ハプティクスやフィードバックを使用した着信音や UI サウンドが含まれます。
  • Vibrator HAL は外部制御サポートを実装する必要があります。

音声と組み合わせた触覚

図 8. 音声と組み合わせた触覚の実装

音声と組み合わせたハプティクス: 触覚生成ツール

HapticGenerator は、Android 12 で導入されたオーディオ エフェクトで、音声チャンネルから触覚データを生成し、音声と組み合わせたハプティクスとしてリアルタイムで再生できます。 この効果は、図 9 に示すように AudioTrack に適用されます。

触覚生成ツールのアーキテクチャ

図 9. 触覚生成ツールのアーキテクチャ

触覚生成アルゴリズムで高品質な触覚が生成されるようにするには、音声波形に適用するフィルタのチェーンを構成するパラメータを調整して、デバイス バイブレータ モーターに合わせて生成アルゴリズムを調整します。このセクションでは、これらのパラメータの詳細とハードウェア仕様に合わせてパラメータを調整する方法について説明します。

  1. バンドパス フィルタの共振周波数

    バイブレータの共振周波数は、触覚アクチュエータの最大出力の周波数です。このパラメータでは、応答伝達関数を部分的にフラット化するためにアンチレゾネーターを調整して、帯域幅を広げます。Android フレームワークは、この値を自動的に Vibrator HAL メソッド IVibrator.getResonantFrequency の出力にリンクします。

    このパラメータのデフォルト値は 150Hz です。これは、こちらのコード内で変更できます。

  2. スロー エンベロープの正規化機能

    このパラメータにより、部分正規化(自動ゲイン コントロール)での指数が決まります。デフォルト値は -0.8 です。つまり、ダイナミック レンジ バリエーションの 80% が、このゲイン コントロール ステップで削除されます。これは、こちらのコード内で変更できます。

  3. バンドストップ フィルタの Q 係数

    バイブレータの品質係数(Q 係数)は、次の 2 つのパラメータによって決まります。

    • Zero Q。共振を部分的にキャンセルするバンドストップ フィルタの零点の品質係数。

    • Pole Q。バンドストップ フィルタの極の品質係数。

    これらの 2 つの値の割合により、共振を抑制する際の上限を定め、低周波を強めてアルゴリズムの応答を広くします。たとえば、Zero Q のデフォルト値 8 と Pole Q のデフォルト値 4 であれば、比率が 2 になり、共振の抑制が 2 倍(6 dB)までに制限されます。Android フレームワークでは、両方の値を Vibrator HAL メソッド IVibrator.getQFactor の出力にリンクします。

    デフォルト値でデバイスのモーター強度の減衰が考慮されていない場合は、両方の値を同時に変更し、片方を増やしたり減らしたりしないことをおすすめします。Zero Q と Pole Q の比率は 1 より大きくする必要があります。これは、こちらのコード内で変更できます。

  4. 歪みのコーナー周波数

    コーナー周波数は、低レベルのバイブレーションを抑制し、3 次歪みを使用してより高レベルを強めるローパス フィルタによって適用されます。デフォルトは 300Hz です。これは、こちらのコード内で変更できます。

  5. 歪みの入力ゲインと 3 次しきい値

    これらのパラメータは、入力波形に適用される非線形歪みフィルタで使用され、低周波数信号のバイブレーションを減衰させて、高周波数信号を増幅します。

    • 入力ゲイン係数のデフォルト値は 0.3 です。
    • 3 次しきい値のデフォルト値は 0.1 です。

    両方の値を合わせて変更することをおすすめします。これらのコードについては、こちらをご覧ください。

    このフィルタによって適用される機能の詳細については、こちらに記載の実装をご覧ください。これらの 2 つのパラメータが出力に与える影響については、フィルタの周波数応答をプロットし、さまざまなパラメータ値で周波数応答がどのように変化するか確認することをおすすめします。

  6. 歪みの出力ゲイン

    このパラメータは、最終的なバイブレーションの振幅を制御します。これは、バイブレーションの振幅を 1 未満に制限するソフト リミッターの後に適用される最終的なゲインです。デフォルト値は 1.5 です。こちらのコードで変更できます。バイブレーションが小さすぎる場合は、値を増やします。アクチュエータのハードウェアからガタガタという音が聞こえる場合は、値を減らします。