OngaqJSを触ってみた

[ニュースが出てた](https://prtimes.jp/main/html/rd/p/000000001.000038855.html)ので触ってみました。

## なに
JSで作曲できる、というサービスです。
公式ページは[ここ](https://www.ongaqjs.com)

## どうやって
サービスのサーバーに用意された音源を、JSからメロディ付けてコントロールしているようです。
なので、APIキーと実行環境のIPアドレスが必要。

### APIキーの発行とIPアドレスの登録
- [サインアップページ](https://www.ongaqjs.com/sign/)でアカウントを作成
- サインインし、`Dashboard` ページで`API Key`が発行されていることを確認
- 同ページの`Authorized Origins` に使用するIPアドレスを登録
    - `Current remote IP address`に現在のIPが書いてあるので、そのまま転記
    - Webサイトから実行する場合はドメイン名を登録するっぽいです

## 仕組み
[ここ](https://www.ongaqjs.com/api/)に詳しいです。
楽器クラスを作成し、音源とメロディを覚えさせ、ミキサークラスに接合するって感じでしょうか。
多少であれば楽器の配置も可能（各楽器のボリュームコントロールはわからん）。

DTMでやってる内容が、そのままプログラム化されているようなイメージです。

1小節が16拍で構成されており、どの楽器が何小節演奏し、どの拍でなんの音をどれぐらい流すか、でメロディを構成することでができます。
各楽器は決められた小節分をループで構成します。

### 楽器
- `Part`クラスを使用
- 初期化時、`sound`に音源名を設定することで、音源を決められる
- 初期化時、`measure`で何小節分構成するか決められる
- `attach`で音色を決めれるみたいですが未検証
- `tag`はミキサーに設定した楽器クラスを参照する用の名前

```javascript
// ドラム
const myDrum = new Part({
    sound: "small_cube_drums",
    measure: 4
})
```

### メロディ
- `Filter`クラスを使用
- `Part`クラスの`add`で追加
    - 何個でも追加可能
    - パターンの違うメロディを複数追加とかしてわかりやすくできる
    - だが、ひとつの楽器に対して、同じ位置で複数メロディ追加しても意味はないので注意
- 初期化時、`key`で音色を設定
    - ドラムは`snare`、`kick`など
    - それ以外は`C2`、`C1#`などドレミで
    - `["C2", "E2", "G2"]`とすると和音になる
- 初期化時、`length`で音色の長さを設定
- 初期化時、`active`で音色を弾くタイミングを設定
- この初期化の3要素とも関数で構成されており、引数からそれぞれの要素の内容をその時々で変更することが可能
    - 第一引数が拍
    - 第二引数が小節
    - 第三引数がアタッチメント
    - 例えば、1拍目がドで2拍分続ける、4拍目がレで1拍分続ける、それ以外は弾かない、とかできる

```javascript
// キックを4拍に1回叩くドラム楽器を4小節分設定
const myDrum = new Part({
    sound: "small_cube_drums",
    measure: 4
})
myDrum.add(new Filter({
    key: "kick",
    active: n => (n % 4 === 0)
}))

// 和音を1拍に1回弾き続けるキーボード楽器を2小節分設定
const myKeyboard = new Part({
    sound: "plain_keyboard",
    measure: 2
})
myKeyboard.add(new Filter({
    key: ["C3", "E3", "G3"],
    length: 1,
    active: 0
}))
```

### 配置
- `Filter`クラスを使用
- `Part`クラスの`add`で追加
- 初期化時、`type`に`pan`を指定
- 初期化時、`x`で配置を設定

```javascript
// キーボードを-45度の位置に配置
myKeyboard.add(new Filter({
    type: "pan",
    x: -45
}))
```

### ミキサー
- `Ongaq`クラスを使用
- 初期化時、`bpm`でBPMを設定
    - 60以下は動かないっぽい？
- 初期化時、`volume`にボリュームを設定
- 初期化時、`onReady`で準備完了イベントをキャッチ可能
    - 遠隔で何かセットアップしているのか、結構OKになるのが遅いです
- `add`で楽器を追加
- `start`で演奏開始
- `pause`で演奏停止
- `params.isPlaying`で演奏中かどうかとれます

```javascript
const ongaq = new Ongaq({
    api_key: "aaaaaaa",
    volume: 80,
    bpm: 60,
    onReady: () => {
        console.log("ok")
    }
})

ongaq.add(myDrum)
ongaq.add(myKeyboard)

if (ongaq.params.isPlaying) {
    ongaq.pause()
} else {
    ongaq.start()
}
```

### かえるのうたつくってみた
とりあえずなんか作ってみようと思ってかえるのうた作ってみました。
ながーいっすが、自分でわかるように切れ目ごとにメロディをわけてるので長いです。

```javascript
const ongaq = new Ongaq({
    api_key: "aaaaa",
    volume: 80,
    bpm: 60
})

// 4小節のピアノ
const myPiano = new Part({
    sound: "my_piano",
    measure: 4
})
// ♪ドレミファミレド
myPiano.add(new Filter({
    key: (beat) => {
        switch (beat) {
        case 0: return ["C2"]
        case 2: return ["D2"]
        case 4: return ["E2"]
        case 6: return ["F2"]
        case 8: return ["E2"]
        case 10: return ["D2"]
        case 12: return ["C2"]
        }
    },
    length: 2,
    active: (beat, measure) => {
        return (measure === 0 && ((beat < 14) && (beat % 2 === 0)))
    }
}))
// ♪ミファソラソファミ
myPiano.add(new Filter({
    key: (beat) => {
        switch (beat) {
        case 0: return ["E2"]
        case 2: return ["F2"]
        case 4: return ["G2"]
        case 6: return ["A2"]
        case 8: return ["G2"]
        case 10: return ["F2"]
        case 12: return ["E2"]
        }
    },
    length: 2,
    active: (beat, measure) => {
        return (measure === 1 && ((beat < 14) && (beat % 2 === 0)))
    }
}))
// ♪ドドドド
myPiano.add(new Filter({
    key: ["C2"],
    length: 3,
    active: (beat, measure) => {
        return (measure === 2 && (beat % 4 === 0))
    }
}))
// ♪ドドレレミミファファミレド
myPiano.add(new Filter({
    key: (beat) => {
        switch (beat) {
        case 0: return ["C2"]
        case 1: return ["C2"]
        case 2: return ["D2"]
        case 3: return ["D2"]
        case 4: return ["E2"]
        case 5: return ["E2"]
        case 6: return ["F2"]
        case 7: return ["F2"]
        case 8: return ["E2"]
        case 10: return ["D2"]
        case 12: return ["C2"]
        }
    },
    length: (beat) => {
        if (beat < 8) {
            return 1
        } else {
            return 2
        }
    },
    active: (beat, measure) => {
        return (measure === 3 && ((beat < 14) && ((beat < 8) || (beat >= 8 && beat % 2 === 0))))
    }
}))

ongaq.add(myPiano)
```

自作曲も軽めで作ってみましたが、GithubPagesに公開しようとして、APIキーの設置がいるので諦めました。
どっかに環境用意するほどでもないので、、、

## 無料でできること
- 13楽器のみ使用可能
    - [ここ](https://www.ongaqjs.com/api/name_sound/)の`Only Free`で出るやつのみ
- それ以外は特に制限はなし
    - ただ、`Showcase`へのアップは制限されそうかな？
    - あと、今は無制限なリクエストになってるけど、それも制限されそうな気がする

## やってみて
大昔DTMやってた時代を思い出して懐かしいです。
そのままがJSになってるので、あまり違和感なく入れる。
ただ、メロディもプログラムで、タイミングベースで頭の中に思い描きながらif文駆使しないといけないので、それは多分プログラマ以外には相当ハードル高いかな、と思います。

## どう活かすか
難しいですよね。
これをそのままWebサイトに貼り付ける、ってわけにもいかないし。
MIDI時代を思い出して、サイトの入口で鳴らすとか？（冗談）
例えば、パララックスみたいにスクロール位置に合わせて曲をコントロールする、とかはできそうでしょうか？

まだまだ発展途上ですが、アイディアとしては非常におもしろかったので、このまま継続していって欲しいです。

以上