15
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

WebAudio/WebMIDI API Advent Calendar 2017Advent Calendar 2017

Day 4

はじめてWeb Audio APIに触ってみる

Last updated at Posted at 2017-12-03

2017/12/4追記
実際に動くサンプルです。

普段はDTMとかで音楽に触れています響音カゲです。Web Audio APIというものを知り、ブラウザでどこまでできるのかやってみたくなったのでいろいろいじってみることにしました。

「初めて触る人でもこんなに簡単に音が出るよ!」って感じの紹介記事です。

とりあえず動かしてみる

サイン波、三角波、矩形波、ノコギリ波の4種類の波形を鳴らしてみます。

index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Web Audio API Test</title>
  <link rel="stylesheet" href="./index.css">
</head>

<body>
  <button onclick="playOsc('sine')">Sin</button>
  <button onclick="playOsc('triangle')">Triangle</button>
  <button onclick="playOsc('square')">Square</button>
  <button onclick="playOsc('sawtooth')">Sawtooth</button>
  <button onclick="stopOsc()">Stop</button>
  <input id="gain" type="range" />
  <script src="./play-osc.js"></script>
</body>

</html>
play-osc.js
// AudioContextを取得
window.AudioContext = window.webkitAudioContext || window.AudioContext;
const audioCtx = new AudioContext();

let play = false;
let osc;
let gain;
let gainCtx;

document.getElementById('gain').onchange = (e) => {
  console.log(e.target.valueAsNumber);
  gain = convertRangeValue(e);
  if (typeof gainCtx !== 'undefined') {
    gainCtx.gain.value = gain;
  }
};

function convertRangeValue(e) {
  return e.target.valueAsNumber / 100;
}

function playOsc(waveformType = 'sine') {
  if (!play) {
    osc = audioCtx.createOscillator();
    gainCtx = audioCtx.createGain();
    osc.connect(gainCtx);
    gainCtx.connect(audioCtx.destination);
    osc.frequency.value = freq;
    gainCtx.gain.value = gain;
    console.log(gainCtx);
    osc.start();
    play = true;
  }
  osc.type = waveformType;
}

function stopOsc() {
  if (play) {
    osc.stop();
    play = false;
  }
}

実行結果

image.png

音が出た!

AttackとReleaseをつけてみる

次はアタックとリリースで音の立ち上がりと終わりに音量の変化をつけてみます。

index.html
  <!-- 追加 -->
  <p>attack:<input id="attack" type="range" /></p>
  <p>release:<input id="release" type="range" /></p>
play-osc.js

let attack = 0.5;
let release = 0.5;

function convertRangeValue(e) {
  return e.target.valueAsNumber / 100;
}

document.getElementById('attack').onchange = (e) => {
  attack = convertRangeValue(e);
}

document.getElementById('release').onchange = (e) => {
  release = convertRangeValue(e);
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

function playOsc(waveformType = 'sine') {
  if (!play) {
    osc = audioCtx.createOscillator();
    gainCtx = audioCtx.createGain();
    osc.connect(gainCtx);
    gainCtx.connect(audioCtx.destination);
    osc.frequency.value = 440;
    gainCtx.gain.value = 0;  // 0からスタートさせて
    console.log(gainCtx);
    gainCtx.gain.linearRampToValueAtTime(gain, audioCtx.currentTime + attack); // gainの値まで上げる
    osc.start();
    play = true;
  }
  osc.type = waveformType;
}

function stopOsc() {
  if (play) {
    gainCtx.gain.linearRampToValueAtTime(0, audioCtx.currentTime + release);  // ゆるやかにゼロにする
    play = false;
  }
}

実行結果

アタックとリリースだけですが音量変化がつきました!

image.png

音程を変えてみる

次に音程を変えてみます。

play-osc.js
let freq = 440;

document.getElementById('freq').onchange = (e) => {
  freq = convertRangeValue(e) * 950 + 50; // 20Hz~1000Hzまでマッピングしてみる
  if (typeof osc !== 'undefined') {
    osc.frequency.value = freq;  // 音程変える
  }
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

function playOsc(waveformType = 'sine') {
  if (!play) {
    osc = audioCtx.createOscillator();
    gainCtx = audioCtx.createGain();
    osc.connect(gainCtx);
    gainCtx.connect(audioCtx.destination);
    osc.frequency.value = freq;  // 音程セット
    gainCtx.gain.value = 0;
    console.log(gainCtx);
    gainCtx.gain.linearRampToValueAtTime(gain, audioCtx.currentTime + attack);
    osc.start();
    play = true;
  }
  osc.type = waveformType;
}

実行結果

image.png

これであなたのおうちのスピーカーが何Hzまで出るかチェックできますね!

感想

ブラウザにオシレーターが乗っかる時代が来るなんて今まで想像できませんでした。Audio Streamをいじれるのでいろいろインタラクティブなサウンドコンテンツを作れそうで面白いです。そのうち簡単な打ち込みツール作りたいです。

ソースコード

15
8
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
15
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?