So-net無料ブログ作成
» スポンサーリンク
音楽コンテンツ(作曲/演奏)
前の5件 | -

HTML5 と Web Audio で作られたブラウザで動くドラムマシン HTML5 Drum Machine
» 音楽コンテンツ(作曲/演奏) 

先週見つけて記事にしようか迷っていたら出遅れました。
すでに各所で取り上げられているので目新しさはありませんがとりあえず紹介。
HTML5 + JavaScript + Web Audio API を使って作られたブラウザベースのドラムマシン HTML5 Drum Machineです。

Chrome、Firefox で動きます。
Safari、Internet Explorer では動きません。
対応していない場合は最初にメッセージダイアログが表示されます。



 13パート、16ステップのオーソドックスなドラムマシンで、音色の違う5種類のドラムキットを選ぶことができます。

 上段のパート名が書かれたボタンを選択して、下段のステップボタンでパターンのトリガーを指定します。各パートはチューンとボリュームを独立して調整することができます。

 作ったパターンは2つ保持できて、気に入ったパターンは WAV 形式でエクスポートしてファイルに保存できます。






UI デザインは見やすくて操作性も普通のドラムマシンと変わりなく、再生ももたつきなくスムーズに動作するのは素晴らしい。

惜しいところは、ハイハットが排他になっていないのと、各キットの音色のチョイスが微妙なところでしょうか。

今後のバージョンアップに期待したいところですね。

[関連サイト]
 HTML5 Drum Machine
permalink
trackback
このエントリーをはてなブックマークに追加


iTunes App Store / Mac App Store 音楽アプリベストセラー
for iPad





for iPhone/iPod touch





for Mac





» スポンサーリンク
DMR

サウンドハウス

Web Audio対応ブラウザで動くReBirth風3トラックアシッドボックス Errozero Acid Machine
» 音楽コンテンツ(作曲/演奏) 

Web Audio 対応ブラウザで動く ReBirth RB-338 風のアシッドマシン Errozero Acid Machine Beta を紹介。

Web Audio API に対応した Chrome、Safari、Firefox なとで実行してください。
iOS の mobile Safari は Web Audio API に制限があるため動きません。
Internet Explorer は Web Audio API に対応していないので動きません。



 TB-303 風ベースシンセ×2、TR-909 風ドラムマシン×1の3トラック構成で、それぞれ16ステップ×8パターンのステップシーケンサーでフレーズを打ち込んで再生できます。




 ベースシンセは、ノコギリ波/矩形波の波形選択のほか、チューニング、カットオフ、レゾナンス、エンベロープモジュレーション、ディケイ、アクセントのパラメータが変更でき、エフェクターとしてディストーションとディレイが付いています(パラメータは変更不可)。

 右側の UP/DOWN ボタンでステップを切り替えて、ノート、アクセント、スライド(TB-303 でのグライド効果)などのボタンでトリガーを指定します。

 左側のランダマイズボタンで、ノート、スライド、アクセントがランダムに配置されたフレーズが生成されます。



 ドラムマシンは、キック、スネア、ロータム、ミッドタム、ハイタム、リムショット/ハンドクラップ、クローズ/オープンハイハット、ライド/クラッシュシンバルの計11音色のパート構成になっています。
 右側6パートは2つずつセットになってますが、排他ではなく同時使用可能です。

 各パートボタンでステップシーケンスを切り替えて、16ステップの中からトリガーするステップを指定します。


処理全体は JavaScript で書かれていて、シンセエンジン部分は Web Audio API を利用したオリジナルのソフトシンセで、ドラムマシンは各パートごとにサンプルの mp3 を用意して発音しているようです。
エフェクトのエンジン部分は tuna.js が使用されています。

UI 関連は jQuery 2.x & jQuery UI にサークルノブの部分はプラグインで jQuery Knob が使用されています。

音やグライドもちゃんと TB-303っぽくてなかなかよくできてますね。素晴らしい。
ベータ版のようなので今後機能が増えていくのかもしれません。

[関連サイト]
 Acid Machine
 Errozero
 jQuery
 jQuery UI
 tuna.js
permalink
trackback
このエントリーをはてなブックマークに追加


iPhoneを左右に振ってJavaScriptで方位を取得してテルミンを演奏するサウンドWebアプリを作ってみました
» 音楽コンテンツ(作曲/演奏) 

あけましておめでとうございます。
本年も音楽方丈記をよろしくお願いします。
年々更新頻度が落ちてますが細々とがんばります。



iPhone を左右に振ってテルミンっぽいサウンドを鳴らすシンプルなサウンド Web アプリ Theremin-1 を作ってみました。

iOS 6以降の iPhone/iPod touch/iPad の Mobile Safari で動きます。
Mobile Safari 以外や Android では未確認。もしかしたら動くかもしれません。



 前に Web Audio API と加速度センサーを利用した簡単な Web アプリを作ったので、次はジオロケーションの方位を使って何か手軽にできないかと考えて思いついたのがこれです。

 iPhone を左右に振るとテルミンっぽい演奏ができるシンプルなサウンド Web アプリで、Web Audio API でサイン波(正弦波)を生成してシンプルなディレイをかけつつ、方位を取得する DeviceOrientationEvent を利用して音程を連続的に変化させるというものです。

Theremin-1 の使い方


   
←左の QR コードをタップするか、iPhone のカメラで読み取って Theremin-1 にアクセスしてください。


  • iPhone を手前に出して「Play」ボタンを押してください。
  • iPhone を左右に弧を描くように動かすと音程が連続的に変化します。
  • 調整できるパラメーターは以下の4種類です。
    • Sensitivity: 振り角に対する音程変化の度合いを調整
    • Delay Time: ディレイタイムの調整 (0~1000ms)
    • Feedback: フィードバックレベルの調整
    • Wet Level: ウェットレベルの調整(ドライ:ウェットの比率)

  振るときに iPhone がすっぽ抜けないように十分注意してください。
  (万が一 iPhone を落として壊してもこちらは責任は負いません)

プログラムの内容について

プログラムの処理内容に興味がない人はここから先はスルーしてください。

 UI 部分はお手軽な jQuery + jQuery UI の組み合わせで、タッチデバイス上のスライダーハンドルのドラッグ操作に対応するため jQuery プラグインの jquery-ui-touch-punch を利用しました。

 テーマは MEDIALOOT で配布されているカスタマイズテーマの jQuery UI Theme: Retro のフリー版を元に、さらに少しだけカスタマイズを施しました。


 あと、特に必要というわけではないのですが、画面左上のアイコンをタッチすると画面が右にスライドして QR コードと短縮 URL を表示するようにしてあります。
 この部分の動作は jQuery プラグイン mmenu を利用しました。

↓JavaScript のサウンド関連部分だけ抜粋
var context = null;
var osc = null;
var baseFreq = 880; // A5
var baseDir = 0;
var ratio = 5;
var delay = null;
var wetGain = null;
var dryGain = null;
var fbGain = null;
var delayTime = 0.3;
var fbLevel = 0.3;
var wetLevel = 0.3;
var valueMax = 50;

// Audio コンテキストの生成
try{
  var AudioContext = window.AudioContext || window.webkitAudioContext;
  context = new AudioContext();
}catch(e){
  context = null;
}

// サウンド出力開始
function playSound(){
  baseDir = 0;
  $(".slider").slider("disable");
  $("#stop").button("enable").focus();
  $("#play").button("disable");
  
  // 正弦波のオシレーター生成
  osc = context.createOscillator();
  osc.type = 0;
  osc.frequency.value = baseFreq;

  // ディレイとゲインのノード生成
  delay = context.createDelay();
  wetGain = context.createGain();
  dryGain = context.createGain();
  fbGain = context.createGain();
  
  // 各ノード間のルーティング
  osc.connect(delay);
  osc.connect(dryGain);
  delay.connect(wetGain);
  delay.connect(fbGain);
  fbGain.connect(delay);
  wetGain.connect(context.destination);
  dryGain.connect(context.destination);
 
  // ディレイパラメーターの指定
  delay.delayTime.value = delayTime;
  fbGain.gain.value = fbLevel;
  wetGain.gain.value = wetLevel;
  dryGain.gain.value = 1 - wetLevel;

  // 再生開始
  osc.noteOn(0);
}

// サウンド出力停止
function stopSound(){
  $(".slider").slider("enable");
  $("#play").button("enable").focus();
  $("#stop").button("disable");

  // 再生停止
  osc.noteOff(0);
}

// DeviceOrientationEvent のハンドラー
function deviceOrientationHandler(e){
  // compassHeading: 角度 0~360, 0=真北
  var dir = e.originalEvent.compassHeading || e.originalEvent.webkitCompassHeading || 0;

  // 相対位置に変換してから、振り角に変化倍率をかける
  if(dir > 180) dir -= 360;
  dir *= ratio;
  
  if(baseDir == 0){
    // 基準方位(Playボタンを押したときの方位)
    baseDir = dir;
  }else{
    // 出力周波数の指定:現在方位と基準方位の差を基準周波数(880Hz)に加算
    osc.frequency.value = baseFreq + (dir - baseDir);
  }
}

$(function(){
  // DeviceOrientationEvent のハンドラー指定
  $(window).on("deviceorientation", deviceOrientationHandler)
  
  // ページ遷移時(pagehide)のハンドラー指定
  $(window).on("pagehide", function(e){ stopSound(); });
  
  // Play ボタン押下イベント
  $("#play").button().click(playSound).focus();

  // Stop ボタン押下イベント
  $("#stop").button().click(stopSound).button("disable");
  
  // スライダー1: 振り角に対する音程変化の比率
  $("#ratio").slider({
    orientation: 'vertical', min: 1, max: 10, range:'min',
    value: ratio,
    slide: function(event, ui){ ratio = ui.value; }
  }).draggable();

  // スライダー2: ディレイタイム
  $("#delaytime").slider({
    orientation: 'vertical', min: 0, max: valueMax, range:'min',
    value: delayTime * valueMax,
    slide: function(event, ui){ delayTime = ui.value / valueMax; }
  }).draggable();

  // スライダー3: フィードバック
  $("#feedback").slider({
    orientation: 'vertical', min: 0, max: valueMax, range:'min',
    value: fbLevel * valueMax,
    slide: function(event, ui){ fbLevel = ui.value / valueMax; }
  }).draggable();

  // スライダー1: Dry/Wet の比率
  $("#wetlevel").slider({
    orientation: 'vertical', min: 0, max: valueMax, range:'min',
    value: wetLevel * valueMax,
    slide: function(event, ui){ wetLevel = ui.value / valueMax; }
  }).draggable();

});

デバイス方向のイベント DeviceOrientationEvent

iOS はバージョン 5 からデバイスの傾きや方位の値を読み出すことができる DeviceOrientationEvent が追加されていて、Safari の JavaScript からイベントハンドラを指定してリアルタイムに現在値を取得することができます。

 » Safari Developer Library - DeviceOrientationEvent Class Reference

window.addEventListener("deviceorientation", function(e){
  var z = e.alpha;        // z軸回転量
  var x = e.beta;          // x軸回転量
  var y = e.gamma;     // y軸回転量
  var heading  = e.webkitCompassHeading;   // 方位 0=真北~360
  var accuracy = e.webkitCompassAccuracy; // 方位の誤差
});

// jQuery の .on(), .bind() で使う場合はプロパティの前に originalEvent を付加
$(window).on("deviceorientation", function(e){
  var heading = e.originalEvent.webkitCompassHeading;
});

 Theremin-1 では方位 (webkitCompassHeading) だけを利用しています。返される値は 0~360で真北が0になります。

 最初は DeviceOrientationEvent を知るより先に Geographic Location API の navigator.geolocation.watchPosition() が返すパラメーターに現在の方位を返す coords.heading (0~360)があるのを見つけていて、使えるだろうと思っていざ組み込んで試してみたら、ある程度移動しながらでないと現在方位が変化しないことが分かったので、今回の用途には使えないことが分かりました。

 iOS 標準のマップやコンパスアプリ、他社製の地図アプリでも位置を移動しなくても方位を常時取得して表示しているものがあるので、おそらく別にコンパス API みたいなものがあるんだろうと調べて見つけたのが、DeviceOrientationEvent で、試してみると compassHeading で簡単に現在方位を取得することができました。

Mobile Safari の Web Audio API

iOS6 以降の Mobile Safari から実装された Web Audio API を使用しています。

 Safari Developer Library - Playing Sounds with the Web Audio API

↓ サウンド出力部分だけ抜粋
function playSound(){
  
  // 正弦波のオシレーター生成
  osc = context.createOscillator();
  osc.type = 0;
  osc.frequency.value = baseFreq;  // 周波数初期値

  // ディレイとゲインのノード生成
  delay = context.createDelay();
  wetGain = context.createGain();
  dryGain = context.createGain();
  fbGain = context.createGain();
  
  // 各ノード間のルーティング
  osc.connect(delay);
  osc.connect(dryGain);
  delay.connect(wetGain);
  delay.connect(fbGain);
  fbGain.connect(delay);
  wetGain.connect(context.destination);
  dryGain.connect(context.destination);
 
  // ディレイパラメーターの指定
  delay.delayTime.value = delayTime;
  fbGain.gain.value = fbLevel;
  wetGain.gain.value = wetLevel;
  dryGain.gain.value = 1 - wetLevel;

  // 再生開始
  osc.noteOn(0);
}

» ノードの接続チャート


 ノードの接続チャートを見ると分かるように構造はいたってシンプルです。

 正弦波のオシレーターを生成して、1つはそのままドライ出力の Gain ノードから Web Audio API の終端入力 (context.destination) へ、もう1つは Delay ノードに渡します。

 Delay ノード単体では、入力したシグナルをディレイタイムで設定した時間(ms単位)だけ遅らせて出力するだけの機能しかないため、フィードバック回路は自分で作ってやる必要があります。

 フィードバック回路は Delay ノードからフィードバック用の Gain ノードへ入力して、指定ゲイン値に下げた後で Delay ノードへ出力を戻してやります。
 ここをぐるぐる回ることでフィードバックの出力が段々小さくなっていって、ディレイエコー独特の減衰効果が生成されます。

 ディレイから出力されるシグナルは、ウェット出力の Gain ノードで指定したウェットレベルのゲイン値に調整されてから終端 (context.destination) へ渡されます。
 今回はパラメーターを簡略化するために、ドライレベルの出力ゲインは、最大値(1) からウェットゲインを引いた残りの値を設定しています。

 オシレーターノードは noteOn() を呼んで再生を開始すると noteOff() を呼ぶまで鳴りっぱなしになり、その間にオシレーター周波数のパラメーター (frequency.value) を変更してやると、すぐに出力に反映されます。

 今回は方位を取得する DeviceOrientationEvent のハンドラー内で現在方位からオシレーター周波数 (frequency.value) を決定しているので、方位が変わるたびに音程が連続的に変化していきます。

その他 Tips

 スライダーのようなドラッグ対応のコントロールを操作していると、まれに意図せずテキストの範囲選択状態になって鬱陶しいので、CSS に以下の宣言を追加して Mobile Safari の範囲選択を無効にしました。
* {
  -webkit-user-select: none;
}

 あと、縦にスライダーを配置すると、1画面に収まっているページの場合に上下スクロールの押し戻しがスライダーのドラッグ操作を邪魔するので touchmove イベントを無効にしてみました。
// HTML の場合
<body ontouchmove="event.preventDefault()">

// jQuery の場合
$(window).on("touchmove", function(e){ e.preventDefault(); });


面白いサウンド Web アプリを思いついたらまた公開したいと思います。

試すときはくれぐれも iPhone を落とさないように注意してください。

[関連サイト]
 jQuery
 jQuery UI
 jquery-ui-touch-punch
 MEDIALOOT - jQuery UI Theme: Retro
 mmenu
 Web Audio API
 Safari Developer Library


Web Audio API

Web Audio API

  • 作者: Boris Smus
  • 出版社/メーカー: Oreilly & Associates Inc
  • 発売日: 2013/03/22
  • メディア: ペーパーバック
Moog Theremini 【並行輸入】

Moog Theremini 【並行輸入】

  • 出版社/メーカー: Moog
  • メディア:
テルミン―エーテル音楽と20世紀ロシアを生きた男

テルミン―エーテル音楽と20世紀ロシアを生きた男

  • 作者: 竹内 正実
  • 出版社/メーカー: 岳陽舎
  • 発売日: 2000/08
  • メディア: 単行本


permalink
trackback
このエントリーをはてなブックマークに追加


iPhoneを振ってJavaScriptから加速度を検知して除夜の鐘を鳴らすサウンドWebアプリ [改良版]
» 音楽コンテンツ(作曲/演奏) 

先日の Sleigh Bells (改良版)に続く時期ネタ第二弾ということで、除夜の鐘バージョン Temple Bell (改良版) を公開します。

iOS 6以降の iPhone/iPod touch/iPad の Mobile Safari で動きます。
Mobile Safari 以外や Android では未確認。もしかしたら動くかもしれません。



 iPhone を振ってお寺の鐘をゴーンと鳴らすだけのシンプルなサウンド Web アプリで、Sleigh Bells と同じく JavaScript から Web Audio API と加速度センサーの値を取得する DeviceMotionEvent を使用しています。

初版は Facebook ページだけで公開

去年、初版 Sleigh Bells を作った後で、大晦日の夜になってから「除夜の鐘に差し替えたバージョンもありかも?」と思い付き、使えそうな寺の鐘の音を急いで探して差し替えて作ったのですが、出来上がった時間が時間だっただけにブログ記事では間に合わず、急遽 Facebook ページのほうだけで公開告知していました。

ということで、この改良版も中身は Sleigh Bells 改良版のサウンドを差し替えただけのものです。(なんてお手軽な…)

Temple Bell の使い方


   

←左の QR コードをタップするか、iPhone のカメラで読み取って Temple Bell にアクセスしてください。
短縮 URL: http://goo.gl/JwA1pX


使い方はスレイベルと同じくシンプルです。
  • まず「Sound Preview」ボタンで iPhone の音量を確認・調整してください。
  • 次に iPhone を握って手首のスナップをきかせて振ってみてください。
  • 反応が悪い場合は振る速度を速くするか感度を低くしてみてください。
  振るときに iPhone がすっぽ抜けないように十分注意してください。
  (万が一 iPhone を落として壊してもこちらは責任は負いません)

タイトルバーの左のアイコンをタップすると画面が右にスライドして QR コードと短縮 URL が表示されます。



プログラムの処理内容について知りたい方は Sleigh Bells 改良版の記事を参照してください。



試すときはくれぐれも iPhone を落とさないように注意してください。

まだいくつか別のネタも作ってあるので後日公開予定です。

[関連サイト]
 jQuery
 jQuery UI
 jquery-ui-touch-punch
 MEDIALOOT - jQuery UI Theme: Retro
 mmenu
 Web Audio API
 Safari Developer Library


Web Audio API

Web Audio API

  • 作者: Boris Smus
  • 出版社/メーカー: Oreilly & Associates Inc
  • 発売日: 2013/03/22
  • メディア: ペーパーバック
permalink
trackback
このエントリーをはてなブックマークに追加


iPhoneを振ってJavaScriptから加速度を検知してスレイベルを鳴らすサウンドWebアプリ [改良版]
» 音楽コンテンツ(作曲/演奏) 

ここんとこずっと時事ネタばかりで、自分発のネタをほとんど書いてなかったということで(といっても使いまわしなんですが)、去年作ったサウンド Web アプリ Sleigh Bells の改良版を公開します。

iOS 6以降の iPhone/iPod touch/iPad の Mobile Safari で動きます。
Mobile Safari 以外や Android では未確認。もしかしたら動くかもしれません。



 iPhone を振ってスレイベルをシャンシャン鳴らすだけの超シンプルなサウンド Web アプリで、JavaScript から Web Audio API と加速度センサーの値を取得する DeviceMotionEvent を使用しています。

スレイベル (Sleigh Bells)とは?

去年の記事と同じくまずはスレイベルの説明から。
スレイベルは木製の棒に鈴がたくさんついたパーカッションの一種です。
(輪っかに鈴がついた小型のタイプもあります)
名前や形は知らなくても、クリスマスの鈴の音といえば分かる人も多いのでは?



Sleigh Bells for iPhone の使い方


     

←左の QR コードをタップするか、iPhone のカメラで読み取って Sleigh Bells にアクセスしてください。
短縮 URL: http://goo.gl/72A8fF


使い方はいたってシンプルです。
  • まず「Sound Preview」ボタンで iPhone の音量を確認・調整してください。
  • iPhone を握って手首のスナップをきかせて振ってみてください。
  • 反応が悪い場合は振る速度を速くするか感度を低くしてみてください。
  振るときに iPhone がすっぽ抜けないように十分注意してください。
  (万が一 iPhone を落として壊してもこちらは責任は負いません)

プログラムの内容について

プログラムの処理内容に興味がない人はここから先はスルーしてください。
中身は去年作ったものとほぼ同じでサンプルレベルの短いものですが、細かい部分に少しだけ改良を加えました。

 UI 部分はお手軽な jQuery + jQuery UI の組み合わせで、タッチデバイス上のスライダーハンドルのドラッグ操作に対応するため jQuery プラグインの jquery-ui-touch-punch を利用しました。(ここは去年と同じ)

 今回は見た目も少し良くしようということで、MEDIALOOT で配布されているカスタマイズテーマの jQuery UI Theme: Retro のフリー版を元に、さらに少しだけカスタマイズを施しました。


 あと、特に必要というわけではないのですが、画面左上のアイコンをタッチすると画面が右にスライドして QR コードと短縮 URL を表示するようにしてあります。
 この部分の動作は jQuery プラグイン mmenu を利用しました。

↓JavaScript のサウンド関連部分だけ抜粋
var soundfile = 'sleigh-bells.mp3';
var locktime = 200;
var outputgain = 0.5;

var context = null;
var buffer = null;
var threshold = 0;
var valuemax = 3000;
var flashing = false;
var playing = true;

// Audio コンテキスト生成と音声ファイルの読み込み
try{
  var AudioContext = window.AudioContext || window.webkitAudioContext;
  context = new AudioContext();

  var request = new XMLHttpRequest();
  request.open('GET', soundfile, true);
  request.responseType = 'arraybuffer';
  request.onload = function(){
    context.decodeAudioData(request.response, function(data){
      buffer = data;
    });
  }
  request.send();
}catch(e){
  context = null;
}

// サウンド再生
function playSound(){
  if(playing) return;  // ロック中はキャンセル

  // 2度鳴り防止のロック時間を設定
  playing = true;
  window.setTimeout(function(){ playing = false; }, locktime);

 // サウンド再生
  var output = context.createGain();
  output.gain.value = outputgain;
  output.connect(context.destination);

  var src = context.createBufferSource();
  src.buffer = buffer;
  src.connect(output);
  src.noteOn(0);
}

// しきい値(感度)の設定
function setThreshold(value){
  threshold = value;
  var text = ["Sensitivity: ", parseInt(value / valuemax * 100), '%'].join('');
  $("#threshold-value").text(text);
}

$(function(){
  setThreshold(valuemax / 2);   // しきい値(感度)の初期値

  // Device Motion のイベントハンドラー指定
  $(window).on("devicemotion", function(e){
    if(Math.floor(e.originalEvent.acceleration.x * 100) > threshold){
      playSound();
    }
  });

  // Preview Sound ボタンのクリックイベント指定
  $("#preview").button().click(function(){
    playing  = false;
    playSound();
  }).focus();

  // しきい値(感度)のスライダーイベント指定
  $("#threshold-slider").slider({
    min: valuemax / 10, max: valuemax, range:'min',
    value: threshold,
    slide: function(event, ui){ setThreshold(ui.value); }
  }).draggable();
});

加速度センサーのイベント DeviceMotionEvent

iOS はバージョン 4.2 から加速度センサーの値を取得できる DeviceMotionEvent が追加されていて、JavaScript からイベントハンドラを指定してリアルタイムに現在値を取得することができます。

 » Safari Developer Library - DeviceMotionEvent Class Reference

window.addEventListener("devicemotion", function(e){
  // 傾きの加速度
  var accX = e.acceleration.x  // 左右方向
  var accY = e.acceleration.y  // 前後方向
  var accZ = e.acceleration.z  // 上下方向
  // 傾きの重力加速度
  var grvX = e.accelerationIncludingGravity.x
  var grvY = e.accelerationIncludingGravity.y
  var grvZ = e.accelerationIncludingGravity.z
  // 回転の加速度
  var rotZ = e.rotationRate.alpha  // z (上下方向)
  var rotX = e.rotationRate.beta    // x (左右方向)
  var rotY = e.rotationRate.gamma // y (前後方向)
});

// jQuery の .on(), .bind() で使う場合はプロパティの前に originalEvent を付加
$(window).on("devicemotion", function(e){
  var accX = e.originalEvent.acceleration.x
});

 Sleigh Bells では X 方向の加速度変化 (acceleration.x) だけを利用しています。X 方向は iPhone 本体正面から見て左右に動かしたときの移動で左方向がマイナス、右方向がプラスの値になります。
 今回の場合は握ったときに本体側面が対面になるので、前後に振る動作で変化する X 軸の値を利用します。

 指定した加速度に達したときに playSound() を呼び出して音を鳴らします。スレイベルを振る演奏操作的には振出しの動作と引きの動作の途中は鳴らずに、手前に強く押し出して止めたとき(加速度がマイナスからプラスの最大値に変化するとき)だけ鳴ればよいので、プラス方向でしきい値を超えたときだけ反応するようにしてあります。

 前回のバージョンでは、一振りで「シャシャン」と続けてトリガーされる2度鳴りが起こることがあったので、新たにトリガーロック時間を設けて指定時間内にトリガーがあった場合無視するようにしました。

Mobile Safari の Web Audio API

サウンドの再生は前回と同じく Mobile Safari で利用できる WebKit の Web Audio API を利用しています。

 去年初版を作ろうとした当初は HTML5 標準の Audio オブジェクトを使おうと思っていたのですが、Mobile Safari は Audio オブジェクトの play() を呼び出すたびに毎回律儀に音声ファイルをサーバーからロードしてしまって、再生が開始されるのが遅すぎて当初想定したレスポンスが得られないことが分かったので、今回も Web Audio API を採用しました。

 Safari Developer Library - Playing Sounds with the Web Audio API

 鈴の音の mp3 ファイルを Ajax 経由でバッファに読み込んでおいて、指定のタイミングで playSound() を呼ぶだけのシンプルな作りです。

// Audio コンテキスト生成と音声ファイルの読み込み
try{
  var AudioContext = window.AudioContext || window.webkitAudioContext;
  context = new AudioContext();
  var request = new XMLHttpRequest();
  request.open('GET', soundfile, true);
  request.responseType = 'arraybuffer';
  request.onload = function(){
    context.decodeAudioData(request.response, function(data){
      buffer = data;
    });
  }
  request.send();
}catch(e){
  context = null;
}

function playSound(){
  // ノードのルーティング
  var output = context.createGain();
  output.gain.value = outputgain;  // 出力ゲイン 0~1
  output.connect(context.destination);

  // バッファに読み込んだサウンドの再生
  var src = context.createBufferSource();
  src.buffer = buffer;
  src.connect(output);
  src.noteOn(0);
}

 あと、去年作っていて分かったことは、Mobile Safari は他のブラウザとちがって Web Audio API の再生はユーザーが画面上のボタンを押すなどの任意に画面操作を行うまでサウンドの再生が許されないという仕様で、ページロード後にいきなりサウンドを再生しても反応しない(オートプレイを禁止する)ようになっているということでした。

Apple Developer Library - Playing Sounds with the Web Audio API より抜粋

Note: On iOS, the Web Audio API requires sounds to be triggered from an explicit user action, such as a tap. Calling noteOn() from an onload event will not play sound.

 DeviceMotionEvent 経由で再生させる場合もこれ該当していて、ページロード直後に noteOn() を呼んでも反応しなかったため、苦肉の策として音量確認用という名目でプレビューボタンを設けました。
 一度任意で再生されると、後は Device Motion イベント経由でも再生できるようになります。

その他 Tips

 スライダーのようなドラッグ対応のコントロールを操作していると、まれに意図せず範囲選択状態になって鬱陶しいので、CSS に以下の宣言を追加して Mobile Safari の範囲選択を無効にしました。
* {
  -webkit-user-select: none;
}

 ページが画面内収まっている状態で余分なスクロールの押し戻しを無効にしたい場合は、HTML もしくは JavaScript で touchmove イベントを無効にします。
// HTML の場合
<body ontouchmove="event.preventDefault()">

// jQuery の場合
$(window).on("touchmove", function(e){ e.preventDefault(); });


ソースコードはサンプルレベルの短いものですが、JavaScript だけでもアイディア次第でこんなことができるサウンド Web アプリの一例として公開してみました。

他にもいくつか別のネタも作ってあるので後日公開予定です。

試すときはくれぐれも iPhone を落とさないように注意してください。

[関連サイト]
 jQuery
 jQuery UI
 jquery-ui-touch-punch
 MEDIALOOT - jQuery UI Theme: Retro
 mmenu
 Web Audio API
 Safari Developer Library


Web Audio API

Web Audio API

  • 作者: Boris Smus
  • 出版社/メーカー: Oreilly & Associates Inc
  • 発売日: 2013/03/22
  • メディア: ペーパーバック

permalink
trackback
このエントリーをはてなブックマークに追加


前の5件 | -
音楽コンテンツ(作曲/演奏)