Tips & Tricks

API Web Audio avec Claude Code

Découvrez aPI Web Audio avec Claude Code. Conseils pratiques et exemples de code inclus.

Web Audio APIの可能性

Web Audio APIは、ブラウザ上で高度な音声処理を行うための強力なAPIです。音楽再生アプリ、ゲームのサウンド、音声ビジュアライザー、さらにはシンセサイザーまで実現できます。Claude Codeを使えば、Audio Nodeの複雑な接続やエフェクト処理を効率的に実装できます。

オーディオプレイヤーの基本

> Web Audio APIを使ったカスタムオーディオプレイヤーを作って。
> 再生・一時停止・ボリューム・シーク操作に対応して。
class AudioPlayer {
  private context: AudioContext;
  private source: AudioBufferSourceNode | null = null;
  private gainNode: GainNode;
  private analyser: AnalyserNode;
  private buffer: AudioBuffer | null = null;
  private startTime = 0;
  private pauseTime = 0;
  private isPlaying = false;

  constructor() {
    this.context = new AudioContext();
    this.gainNode = this.context.createGain();
    this.analyser = this.context.createAnalyser();
    this.analyser.fftSize = 2048;

    this.gainNode.connect(this.analyser);
    this.analyser.connect(this.context.destination);
  }

  async load(url: string) {
    const response = await fetch(url);
    const arrayBuffer = await response.arrayBuffer();
    this.buffer = await this.context.decodeAudioData(arrayBuffer);
  }

  play() {
    if (!this.buffer || this.isPlaying) return;

    this.source = this.context.createBufferSource();
    this.source.buffer = this.buffer;
    this.source.connect(this.gainNode);
    this.source.start(0, this.pauseTime);
    this.startTime = this.context.currentTime - this.pauseTime;
    this.isPlaying = true;

    this.source.onended = () => {
      if (this.isPlaying) {
        this.isPlaying = false;
        this.pauseTime = 0;
      }
    };
  }

  pause() {
    if (!this.isPlaying || !this.source) return;
    this.source.stop();
    this.pauseTime = this.context.currentTime - this.startTime;
    this.isPlaying = false;
  }

  setVolume(value: number) {
    this.gainNode.gain.setValueAtTime(
      Math.max(0, Math.min(1, value)),
      this.context.currentTime
    );
  }

  get currentTime(): number {
    if (this.isPlaying) return this.context.currentTime - this.startTime;
    return this.pauseTime;
  }

  get duration(): number {
    return this.buffer?.duration ?? 0;
  }

  getFrequencyData(): Uint8Array {
    const data = new Uint8Array(this.analyser.frequencyBinCount);
    this.analyser.getByteFrequencyData(data);
    return data;
  }
}

オーディオビジュアライザー

> 周波数データを使ったCanvasビジュアライザーを作って。
import { useRef, useEffect } from 'react';

function AudioVisualizer({ player }: { player: AudioPlayer }) {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const animationRef = useRef<number>();

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d')!;

    const draw = () => {
      const data = player.getFrequencyData();
      const width = canvas.width;
      const height = canvas.height;
      const barWidth = width / data.length * 2.5;

      ctx.clearRect(0, 0, width, height);

      data.forEach((value, i) => {
        const barHeight = (value / 255) * height;
        const hue = (i / data.length) * 360;

        ctx.fillStyle = `hsl(${hue}, 70%, 50%)`;
        ctx.fillRect(
          i * barWidth,
          height - barHeight,
          barWidth - 1,
          barHeight
        );
      });

      animationRef.current = requestAnimationFrame(draw);
    };

    draw();
    return () => {
      if (animationRef.current) cancelAnimationFrame(animationRef.current);
    };
  }, [player]);

  return <canvas ref={canvasRef} width={800} height={200} className="w-full rounded-lg bg-gray-900" />;
}

エフェクトチェーン

class AudioEffects {
  private context: AudioContext;

  constructor(context: AudioContext) {
    this.context = context;
  }

  createReverb(duration = 2): ConvolverNode {
    const convolver = this.context.createConvolver();
    const sampleRate = this.context.sampleRate;
    const length = sampleRate * duration;
    const impulse = this.context.createBuffer(2, length, sampleRate);

    for (let channel = 0; channel < 2; channel++) {
      const data = impulse.getChannelData(channel);
      for (let i = 0; i < length; i++) {
        data[i] = (Math.random() * 2 - 1) * Math.pow(1 - i / length, 2);
      }
    }
    convolver.buffer = impulse;
    return convolver;
  }

  createEqualizer(): BiquadFilterNode[] {
    const frequencies = [60, 170, 350, 1000, 3500, 10000];
    return frequencies.map((freq) => {
      const filter = this.context.createBiquadFilter();
      filter.type = 'peaking';
      filter.frequency.value = freq;
      filter.Q.value = 1;
      filter.gain.value = 0;
      return filter;
    });
  }

  createDistortion(amount = 50): WaveShaperNode {
    const shaper = this.context.createWaveShaper();
    const samples = 44100;
    const curve = new Float32Array(samples);
    for (let i = 0; i < samples; i++) {
      const x = (i * 2) / samples - 1;
      curve[i] = ((Math.PI + amount) * x) / (Math.PI + amount * Math.abs(x));
    }
    shaper.curve = curve;
    return shaper;
  }
}

Reactプレイヤーコンポーネント

function PlayerUI() {
  const [player] = useState(() => new AudioPlayer());
  const [playing, setPlaying] = useState(false);
  const [volume, setVolume] = useState(0.8);

  const toggle = () => {
    if (playing) { player.pause(); } else { player.play(); }
    setPlaying(!playing);
  };

  return (
    <div className="p-4 bg-gray-900 rounded-xl text-white">
      <AudioVisualizer player={player} />
      <div className="flex items-center gap-4 mt-4">
        <button onClick={toggle} aria-label={playing ? '一時停止' : '再生'}
          className="w-12 h-12 rounded-full bg-white text-gray-900 flex items-center justify-center">
          {playing ? '⏸' : '▶'}
        </button>
        <input type="range" min={0} max={1} step={0.01} value={volume}
          onChange={(e) => { const v = Number(e.target.value); setVolume(v); player.setVolume(v); }}
          aria-label="音量" className="flex-1" />
      </div>
    </div>
  );
}

Summary

Claude Codeを使えば、Web Audio APIによるカスタムプレイヤーからビジュアライザー、エフェクト処理まで効率的に実装できます。Canvasの描画についてはCanvas/WebGL開発を、パフォーマンス最適化はパフォーマンス最適化を参照してください。

Web Audio APIの仕様はMDN Web Docs - Web Audio APIをご覧ください。

#Claude Code #Web Audio API #音声処理 #ビジュアライザー #TypeScript