1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

Web Audio APIで音声解析をしていると、解析値がちゃんと取れているか確認したくなります。

コンソールに出すだけでも確認できますが、ビジュアライザーを作るなら、画面上にメーターとして表示した方が分かりやすいです。

今回は React で、

  • volume
  • bass
  • mids
  • highs

を表示する簡単な音声メーターを作ります。

作るもの

以下のような値を受け取って、横棒のメーターとして表示します。

type AudioFeatures = {
  volume: number
  bass: number
  mids: number
  highs: number
}

値は 0〜1 の範囲を想定します。

<Meter label="volume" value={features.volume} />
<Meter label="bass" value={features.bass} />
<Meter label="mids" value={features.mids} />
<Meter label="highs" value={features.highs} />

Meterコンポーネント

まずはシンプルな Meter コンポーネントを作ります。

type MeterProps = {
  label: string
  value: number
}

export function Meter({ label, value }: MeterProps) {
  const clampedValue = Math.max(0, Math.min(1, value))

  return (
    <div className="meter">
      <div className="meter__header">
        <span>{label}</span>
        <span>{Math.round(clampedValue * 100)}%</span>
      </div>

      <div className="meter__track">
        <div
          className="meter__bar"
          style={{ width: `${clampedValue * 100}%` }}
        />
      </div>
    </div>
  )
}

値が 0〜1 の範囲を超える可能性もあるので、念のため clamp しています。

CSS

見た目は最小限にします。

.meter {
  display: grid;
  gap: 6px;
}

.meter__header {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: #666;
}

.meter__track {
  height: 8px;
  overflow: hidden;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.12);
}

.meter__bar {
  height: 100%;
  border-radius: inherit;
  background: currentColor;
  transition: width 80ms linear;
}

transition を少しだけ入れると、急な変化が少しなめらかに見えます。

ただし、音声解析値自体に smoothing をかけている場合は、CSS側の transition は短めでも十分です。

featuresをまとめて表示する

複数のメーターを並べるコンポーネントも作ります。

type AudioFeatures = {
  volume: number
  bass: number
  mids: number
  highs: number
}

type AudioMetersProps = {
  features: AudioFeatures
}

export function AudioMeters({ features }: AudioMetersProps) {
  return (
    <div className="audio-meters">
      <Meter label="volume" value={features.volume} />
      <Meter label="bass" value={features.bass} />
      <Meter label="mids" value={features.mids} />
      <Meter label="highs" value={features.highs} />
    </div>
  )
}

CSSは以下のようにします。

.audio-meters {
  display: grid;
  gap: 12px;
}

毎フレーム更新しすぎない

音声解析値は requestAnimationFrame で毎フレーム更新されます。

ただ、メーター表示のために毎フレーム React state を更新すると、再レンダリングが多くなりすぎる場合があります。

そのため、UI用の値は少し間引いて更新するのが扱いやすいです。

const [featuresSnapshot, setFeaturesSnapshot] = useState<AudioFeatures>({
  volume: 0,
  bass: 0,
  mids: 0,
  highs: 0,
})

解析ループ内では、たとえば30fps程度に間引きます。

let lastUpdate = 0

function analyze(time: number) {
  const nextFeatures = getAudioFeatures()

  if (time - lastUpdate > 33) {
    setFeaturesSnapshot(nextFeatures)
    lastUpdate = time
  }

  requestAnimationFrame(analyze)
}

3D描画やCanvas描画では最新値が必要でも、UI表示は少し間引いても十分見えます。

メーターがあると調整しやすい

音声ビジュアライザーを作るとき、メーターがあるとかなり便利です。

たとえば、

  • bassが強すぎる
  • highsがほとんど反応していない
  • volumeだけ常に高い
  • smoothingを上げすぎて動きが鈍い
  • sensitivityを上げすぎて常に振り切っている

といったことに気づきやすくなります。

ビジュアルだけ見ていると、何が原因で動きが不自然なのか分かりにくいことがあります。

メーターを置いておくと、解析値と見た目を対応させながら調整できます。

sensitivityの確認にも使える

音への反応を強くするために、sensitivityをかけることがあります。

const adjustedBass = clamp(bass * sensitivity, 0, 1)

このとき、メーターがあると、値がどれくらい増えているのか見えます。

もし常に100%に近いなら、sensitivityが強すぎます。

逆にほとんど動かないなら、感度が低すぎる可能性があります。

まとめ

Reactで音声メーターを作ると、Web Audio APIの解析値を視覚的に確認しやすくなります。

今回作ったのは、

  • volume
  • bass
  • mids
  • highs

を横棒で表示するシンプルなUIです。

音声ビジュアライザーでは、見た目の調整だけでなく、解析値そのものを見ることも重要です。

メーターを用意しておくと、感度やsmoothingの調整がかなりやりやすくなりました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?