【obniz×圧電スピーカー】処理(曲)コードをまとめました。 #マンボ #Disney

obniz1Yと圧電スピーカーを使って今まで実装してきた曲のコードのみを公開します。
自分で楽しんでもよし！他の事に使ってもよし！

実際に使った記事は以下になります。

https://qiita.com/yui-kouy/items/d7959be61262a714833f

https://youtu.be/euZJfDe7YFA

※obnizの0と1へ圧電スピーカーをつないで使用するソースコードを記載します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122199/791f3c26-5b13-4464-1912-865c21c5a36e.jpeg" width=50%>

#音符・休符の長さ、音階周波数について
##音符・休符の長さ
音符・休符の長さは、全音符・全休符の長さを基準として定数にします。
【参考】[バンド・スコアの小楽典 - 2. 音譜・休符・拍子](https://www.doremi.co.jp/gakufu_no_mikata/gakufu/basic2.html)

``const sp1 = 2000`` の``2000``は曲の速さに合わせて変更します。

:::note warn
数字を大きくすると遅くなり、小さくすると速くなります。
数字を小さく(=速く)しすぎると圧電スピーカーで対応できず破損する恐れがありますのでご注意ください。
:::


##音階周波数
音階ごとに周波数を定数にします。

【参考】[音階の周波数](https://tomari.org/main/java/oto.html)

:::note warn
低すぎる または 高すぎる 音はうまく作動しないことが多かったので、適度な音階(上記リンク先の4～5)を使用しています。
:::


#ソースコード
汎用で使用できる部分のコードを記載します。
音符・休符、音階周波数をそれぞれ定数化します。
曲ごとに使用する定数を挿入します。

##汎用ソースコード
汎用で使用できる部分のコードを記載。

```javascript
    const Obniz = require('obniz');
    const obniz = new Obniz('****-****'); // Obniz_IDに自分のIDを入れます
    //***************************ここから音符・休符の定数宣言***************************
    const sp1 = 2000                    // 全音符・全休符
    const sp2 = sp1 / 2                 // 2分音符・2分休符
    const sp4 = sp1 / 4                 // 4分音符・4分休符
    const sp8 = sp1 / 8                 // 8分音符・8分休符
    const sp16 = sp1 / 16               // 16分音符・16分休符
    const sp2_34 = sp2 + sp4            // 付点2分音符・付点2分休符  
    const sp4_34 = sp4 + sp8            // 付点4分音符・付点4分休符
    const sp8_34 = sp8 + sp16           // 付点8分音符・付点8分休符
    const sp16_34 = sp16 + (sp16 / 2)   // 付点16分音符・付点16分休符
    //***************************ここまで音符・休符の定数宣言***************************
    //***************************ここから音階周波数の定数宣言***************************
    const oto_do_4 = 261.626;           // ド4
    const oto_re_4 = 293.665;           // レ4
    const oto_mi_4 = 329.628;           // ミ4
    const oto_fa_4 = 349.228;           // ファ4
    const oto_so_4 = 391.995;           // ソ4
    const oto_ra_4 = 440.000;           // ラ4
    const oto_si_4 = 493.883;           // シ4
    const oto_do_5 = 523.251;           // ド5
    const oto_re_5 = 587.330;           // レ5
    const oto_mi_5 = 659.255;           // ミ5
    const oto_fa_5 = 698.456;           // ファ5
    const oto_so_5 = 783.991;           // ソ5
    const oto_ra_5 = 880.000;           // ラ5
    const oto_si_5 = 987.767;           // シ5
    const oto_do_6 = 1046.502;          // ド6

    const oto_fa_5S = 739.989;          // ファ#5
    const oto_so_5S = 830.609;          // ソ#5
    const oto_si_5F = 932.328;          // シb5(ラ#5)
    //***************************ここまで音階周波数の定数宣言***************************

    // obnizが接続済み
    obniz.onconnect = async function () {

       // 任意の秒数待つことができる関数
       // 参考: https://qiita.com/suin/items/99aa8641d06b5f819656
       const sleep = (msec) => new Promise(res => setTimeout(res, msec));
       // スピーカーを利用　obnizの0と1を使う　+-どっちでも良い。
       const speaker = obniz.wired('Speaker', { signal: 0, gnd: 1 });

       //***************************ここから曲コードを挿入***************************

       //***************************ここまで曲コードを挿入***************************
    }
```

##4曲分
###マンボNo.5
繰り返す回数をランダムにするところがあるので、特別に曲コードの前に定数を追加する必要があります。

```javascript
    //繰り返す回数はランダムにするか固定、どちらかを//より下のconstを挿入する。
    //ランダム回数　※以下songNoとsongFlgを使用して配列に入った数字をランダム回数として使用する
    const songNo = [2,3,4,5]; //繰り返す回数を配列に入れる
    const songFlg = (songNo[Math.floor(Math.random() * songNo.length)]);   //ランダム回数
    //固定回数　※ランダムが嫌なら、以下2を繰り返したい回数へ変更する
    const songFlg = 2
```

<details><summary><font color="#000080">**コード（クリックで開きます）**</font></summary><div>

```javascript
//マンボNo.5
    //最初4
    speaker.play(oto_ra_4); await sleep(sp8); speaker.stop(); await sleep(sp8);            // ラ4
    speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(sp8+sp2);        // レ5
    speaker.play(oto_ra_4); await sleep(sp8); speaker.stop(); await sleep(0);              // ラ4
    speaker.play(oto_ra_4); await sleep(sp8); speaker.stop(); await sleep(0);              // ラ4
    speaker.play(oto_ra_4); await sleep(sp8); speaker.stop(); await sleep(0);              // ラ4
    speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(sp4);            // レ5
    for (c = 1 ; c <= 2 ; c += 1 ) {
        speaker.play(oto_ra_4); await sleep(sp8); speaker.stop(); await sleep(0);          // ラ4
        speaker.play(oto_ra_4); await sleep(sp8); speaker.stop(); await sleep(0);          // ラ4
        speaker.play(oto_ra_4); await sleep(sp8); speaker.stop(); await sleep(0);          // ラ4
        speaker.play(oto_ra_4); await sleep(sp8); speaker.stop(); await sleep(0);          // ラ4
        switch (c){
            case 1 : //1回目
                speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(sp8);         // レ5
                break;
            case 2 : //2回目
                speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(sp8+sp2+sp1); // レ5
                break;
        }
    }
    //繰り返す回数指定してマンボを実行
    for ( c= 1 ; c <= songFlg ; c += 1 ) {
        speaker.play(oto_ra_4); await sleep(sp8); speaker.stop(); await sleep(sp8+sp8);    // ラ4　★
        speaker.play(oto_do_5); await sleep(sp8); speaker.stop(); await sleep(0);          // ド5
        speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(0);          // ミ5
        speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(sp8);        // レ5
        speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(0);          // ミ5
        speaker.play(oto_ra_4); await sleep(sp8); speaker.stop(); await sleep(sp8);        // ラ4　★
        speaker.play(oto_do_5); await sleep(sp8); speaker.stop(); await sleep(0);          // ド5
        speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(sp8);        // ミ5
        speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(sp8);        // レ5
        speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(0);          // ミ5
        speaker.play(oto_so_4); await sleep(sp8); speaker.stop(); await sleep(sp8+sp8);    // ソ4　★
        speaker.play(oto_si_4); await sleep(sp8); speaker.stop(); await sleep(0);          // シ4
        speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(0);          // ミ5
        speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(sp8);        // レ5
        speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(0);          // ミ5
        speaker.play(oto_so_4); await sleep(sp8); speaker.stop(); await sleep(sp8);        // ソ4　★
        speaker.play(oto_si_4); await sleep(sp8); speaker.stop(); await sleep(0);          // シ4
        speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(sp8);        // ミ5
        speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(sp8);        // レ5
        speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(0);          // ミ5
    }
    speaker.play(oto_ra_4); await sleep(sp8); speaker.stop(); await sleep(sp8+sp8);        // ラ4　★
    speaker.play(oto_do_5); await sleep(sp8); speaker.stop(); await sleep(0);              // ド5
    speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(0);              // ミ5
    speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(sp8);            // レ5
    speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(0);              // ミ5
    speaker.play(oto_ra_4); await sleep(sp8); speaker.stop(); await sleep(sp8);            // ラ4　★
    speaker.play(oto_do_5); await sleep(sp8); speaker.stop(); await sleep(0);              // ド5
    speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(sp8);            // ミ5
    speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(sp8);            // レ5
    speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(0);              // ミ5
    for (c = 1 ; c <= 2 ; c += 1 ) {
        speaker.play(oto_so_5); await sleep(sp8); speaker.stop(); await sleep(0);          // ミ5
        speaker.play(oto_so_5); await sleep(sp8); speaker.stop(); await sleep(0);          // ミ5
        speaker.play(oto_so_5); await sleep(sp8); speaker.stop(); await sleep(sp4+sp8);    // ミ5
    }
```

</div></details>


###Part of your world（映画「リトルマーメイド」より）

<details><summary><font color="#000080">**コード（クリックで開きます）**</font></summary><div>

```javascript
//Part of your world
    speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(0);        // レ5
    speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ミ5
    speaker.play(oto_fa_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ファ5
    speaker.play(oto_fa_5); await sleep(sp4_34); speaker.stop(); await sleep(sp4);   // ファ5
    speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ミ5
    speaker.play(oto_fa_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ファ5
    speaker.play(oto_so_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ソ5
    speaker.play(oto_so_5); await sleep(sp4_34); speaker.stop(); await sleep(sp4);   // ソ5
    speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(0);        // レ5
    speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ミ5
    speaker.play(oto_fa_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ファ5
    speaker.play(oto_fa_5); await sleep(sp4); speaker.stop(); await sleep(0);        // ファ5
    speaker.play(oto_mi_5); await sleep(sp4); speaker.stop(); await sleep(0);        // ミ5
    speaker.play(oto_fa_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ファ5
    speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ミ5
    speaker.play(oto_fa_5); await sleep(sp4); speaker.stop(); await sleep(0);        // ファ5
    speaker.play(oto_so_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ソ5
    speaker.play(oto_so_5); await sleep(sp4); speaker.stop(); await sleep(sp4);      // ソ5
    speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ミ5
    speaker.play(oto_fa_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ファ5
    speaker.play(oto_so_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ソ5
    speaker.play(oto_so_5); await sleep(sp4); speaker.stop(); await sleep(0);        // ソ5
    speaker.play(oto_fa_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ファ5
    speaker.play(oto_so_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ソ5
    speaker.play(oto_fa_5); await sleep(sp4_34); speaker.stop(); await sleep(sp8);   // ファ5
    speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(0);        // レ5
    speaker.play(oto_fa_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ファ5
    speaker.play(oto_so_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ソ5
    speaker.play(oto_ra_5); await sleep(sp4); speaker.stop(); await sleep(0);        // ラ5
    speaker.play(oto_ra_5); await sleep(sp4); speaker.stop(); await sleep(0);        // ラ5
    speaker.play(oto_so_5); await sleep(sp8); speaker.stop(); await sleep(0);        // ソ5
    speaker.play(oto_so_5); await sleep(sp8+sp2); speaker.stop(); await sleep(sp1);  // ソ5
```

</div></details>

###【オクタヴィネル寮】お店を切り盛りしよう！一部抜粋（ゲーム「Twisted Wonderland」より）

<details><summary><font color="#000080">**コード（クリックで開きます）**</font></summary><div>

```javascript
// TWISTED-WONDERLAND Mostro Lounge by Disney
    speaker.play(oto_si_5); await sleep(sp8_34); speaker.stop(); await sleep(0);        // シ5
    speaker.play(oto_si_5F); await sleep(sp16); speaker.stop(); await sleep(0);         // シb5
    speaker.play(oto_ra_5); await sleep(sp8_34); speaker.stop(); await sleep(0);        // ラ5
    speaker.play(oto_fa_5S); await sleep(sp16); speaker.stop(); await sleep(0);         // ファ5
    speaker.play(oto_so_5); await sleep(sp8_34); speaker.stop(); await sleep(0);        // ソ5
    speaker.play(oto_mi_5); await sleep(sp16+sp4); speaker.stop(); await sleep(0);      // ミ5
    speaker.play(oto_ra_5); await sleep(sp4); speaker.stop(); await sleep(sp8_34);      // ラ5
    speaker.play(oto_si_5F); await sleep(sp16+sp4); speaker.stop(); await sleep(sp4);   // シb5
    speaker.play(oto_fa_5); await sleep(sp4); speaker.stop(); await sleep(sp8_34);      // ファ5
    speaker.play(oto_fa_5S); await sleep(sp16+sp4); speaker.stop(); await sleep(0);     // ファ#5
    speaker.play(oto_re_5); await sleep(sp4); speaker.stop(); await sleep(0);           // レ5
    speaker.play(oto_mi_5); await sleep(sp4); speaker.stop(); await sleep(0);           // ミ5
    speaker.play(oto_fa_5S); await sleep(sp4); speaker.stop(); await sleep(0);          // ファ#5
    speaker.play(oto_so_5); await sleep(sp16); speaker.stop(); await sleep(sp16_34);    // ソ5
    speaker.play(oto_ra_5); await sleep(sp16); speaker.stop(); await sleep(sp16);       // ラ5
    speaker.play(oto_do_6); await sleep(sp8_34); speaker.stop(); await sleep(sp8);      // ド6
```

</div></details>

###【スケアリーモンスターズ】ハロウィーンを楽しもう！一部抜粋（ゲーム「Twisted Wonderland」より）

<details><summary><font color="#000080">**コード（クリックで開きます）**</font></summary><div>

```javascript
// TWISTED-WONDERLAND SCREAMING HALLOWEEN by Disney
    speaker.play(oto_ra_5); await sleep(sp8); speaker.stop(); await sleep(sp8);         // ラ5
    speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(0);           // レ5
    speaker.play(oto_mi_5); await sleep(sp8); speaker.stop(); await sleep(0);           // ミ5
    speaker.play(oto_fa_5); await sleep(sp8); speaker.stop(); await sleep(0);           // ファ5
    speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(sp8);         // レ5
    speaker.play(oto_ra_5); await sleep(sp8); speaker.stop(); await sleep(sp8);         // ラ5
    speaker.play(oto_si_5F); await sleep(sp8); speaker.stop(); await sleep(sp8);        // シ♭5
    speaker.play(oto_ra_5); await sleep(sp8); speaker.stop(); await sleep(sp8);         // ラ5
    speaker.play(oto_so_5); await sleep(sp4); speaker.stop(); await sleep(0);           // ソ5
    speaker.play(oto_so_5S); await sleep(sp8); speaker.stop(); await sleep(0);          // ソ#5
    speaker.play(oto_ra_5); await sleep(sp8); speaker.stop(); await sleep(sp8);         // ラ5
    speaker.play(oto_fa_5); await sleep(sp8); speaker.stop(); await sleep(0);           // ファ5
    speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(0);           // レ5
    speaker.play(oto_fa_5); await sleep(sp8); speaker.stop(); await sleep(0);           // ファ5
    speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(sp8);         // レ5
    speaker.play(oto_fa_5); await sleep(sp4); speaker.stop(); await sleep(0);           // ファ5
    speaker.play(oto_re_5); await sleep(sp8); speaker.stop(); await sleep(0);           // レ5
    speaker.play(oto_so_5S); await sleep(sp8); speaker.stop(); await sleep(0);          // ソ#5
    speaker.play(oto_ra_5); await sleep(sp8); speaker.stop(); await sleep(0);           // ラ5
    speaker.play(oto_do_6); await sleep(sp16); speaker.stop(); await sleep(sp16);       // ド6
    speaker.play(oto_si_5); await sleep(sp4); speaker.stop(); await sleep(sp8);         // シ5
```

</div></details>


#さいごに
音符・休符・音階周波数を定数化していますので、汎用的に使うことができると思います。
これからobnizと圧電スピーカーを使って音を鳴らしたい方の役に立てると嬉しいです。