ファミマ入店音 on obniz Board 1Y


2021/3/27公開
2021/4/17更新

概要
圧電スピーカー2個とobnizのIO-Animation機能を使ってファミマ入店音を鳴らしてみました。
なんとかして減衰音を作りたかったんですがうまくいかなかったので連続音で鳴らしてます。
楽譜をコードに落とし込むのが地味に大変でした。

サンプルコード
<script src="https://unpkg.com/obniz@3.x.0/obniz.js"></script>

<script>
// 音階と周波数の定義
const FREQS = {
    'C4'  : 261.626,
    'C#4' : 277.183,
    'D4'  : 293.665,
    'D#4' : 311.127,
    'E4'  : 329.628,
    'F4'  : 349.228,
    'F#4' : 369.994,
    'G4'  : 391.995,
    'G#4' : 415.305,
    'A4'  : 440.000,
    'A#4' : 466.164,
    'B4'  : 493.883,

    'C5'  : 523.251,
    'C#5' : 554.365,
    'D5'  : 587.330,
    'D#5' : 622.254,
    'E5'  : 659.255,
    'F5'  : 698.456,
    'F#5' : 739.989,
    'G5'  : 783.991,
    'G#5' : 830.609,
    'A5'  : 880.000,
    'A#5' : 932.328,
    'B5'  : 987.767,
    
    'C6'  : 1046.502,
    'C#6' : 1108.731,
    'D6'  : 1174.659,
    'D#6' : 1244.508,
    'E6'  : 1318.510,
    'F6'  : 1396.913,
    'F#6' : 1479.978,
    'G6'  : 1567.982,
    'G#6' : 1661.219,
    'A6'  : 1760.000,
    'A#6' : 1864.655,
    'B6'  : 1975.533
}

var obniz = new Obniz("OBNIZ_ID_HERE");
var spk1 = null;
var spk2 = null;

obniz.onconnect = async function () {
    spk1 = obniz.wired("Speaker", {signal:0, gnd:1});  // スピーカー1個目
    spk2 = obniz.wired("Speaker", {signal:2, gnd:3});  // スピーカー2個目

    // canvas準備
    const canvas = document.createElement('canvas');
    canvas.width = 128;
    canvas.height = 64;
    const ctx = canvas.getContext("2d");

    // 画像読み込み
    const img = new Image();
    img.src = "data:image/png;base64,【ここにBASE64エンコードした画像データ(省略)】";
    img.onload = function() {
      ctx.drawImage(img, 0, 0);
      obniz.display.draw(ctx);
  };

  // スピーカー1と2から音を出して接続確認
  spk1.play(2000);
  obniz.wait(100);
  spk1.stop();
  spk2.play(1000);
  obniz.wait(100);
  spk2.stop();
  
  obniz.switch.onchange = function(state) {
    // 左上のスイッチを押し込むと再生
    if (state === "push") {
      play();
    }
  }
}

function play() {
    obniz.io.repeatWait([
      {
        duration: 333,
        state: function(index){
          spk1.play(FREQS['G5']);
        }
      },{
        duration: 333,
        state: function(index){
          spk1.play(FREQS['D#5']);
       }
      },{
        duration: 333,
        state: function(index){
          spk1.play(FREQS['G4']);
          spk2.play(FREQS['A#4']);
       }
      },{
        duration: 333,
        state: function(index){
          spk1.play(FREQS['D#5']);
          spk2.stop();
       }
      },{
        duration: 333,
        state: function(index){
          spk1.play(FREQS['D#5']);
          spk2.play(FREQS['F5']);
       }
      },{
        duration: 667,
        state: function(index){
          spk2.play(FREQS['A#5']);
       }
      },{
        duration: 333,
        state: function(index){
          spk1.play(FREQS['F4']);
       }
      },{
        duration: 333,
        state: function(index){
          spk1.play(FREQS['F5']);
          spk2.play(FREQS['A#4']);
       }
      },{
        duration: 333,
        state: function(index){
          spk1.play(FREQS['G5']);
       }
      },{
        duration: 333,
        state: function(index){
          spk1.play(FREQS['F5']);
       }
      },{
        duration: 333,
        state: function(index){
          spk1.play(FREQS['A#4']);
          spk2.stop();
       }
      },{
        duration: 667,
        state: function(index){
          spk1.play(FREQS['D#5']);
          spk2.play(FREQS['G4']);
       }
      },{
        duration: 10,
        state: function(index){
          spk1.stop();
          spk2.stop();
       }
     }
    ],13);
}
</script>


戻る