HISE HiseScript - DTMプログラミング言語探訪

[DTMプログラミング言語探訪](https://qiita.com/aike@github/items/77b3eccc6861de09513a)

# HISE HiseScript

## 概要

オープンソースのサンプラー／シンセサイザーソフト[HISE](http://hise.audio/)にはHiseScriptというJavaScriptをベースにした独自言語が用意されています。

HISEはモジュールをツリー状に積み重ねて楽器を構成します。スクリプトはそのモジュールごとに作成することができるため、小さな機能単位でモジュール化されたロジックを書くことができます。

## 用途

NoteOnなどのイベントに対応してサウンドエンジンのパラメータをカスタマイズしたり、タイマーイベントで音を鳴らしたりするのが典型的な使い方ですが、Webアクセスをはじめ非常に多くのAPIが用意されているため、可能性としてはそれだけにとどまりません。
Script FXは音声信号データを直接操作することが可能で、いわゆる信号処理を記述することができます。
GUIの作成やカスタマイズ、コールバックロジックなどもスクリプトで書くことができます。またGUIの作成はWYSIWYGエディタからおこなうこともできます。

- キースイッチなどによるアーティキュレーション切り替え
- 乱数やラウンドロビンによるヒューマナイズ
- アルペジエーター
- GUI
- 信号処理

## 言語仕様

- JavaScriptをベースにカスタマイズした独自言語
- イベントコールバック
- サウンドエンジンAPI
- ファイルAPI
- WebアクセスAPI
- GUI API

JavaScriptをベースに、newオペレータを廃止、namespace、inline関数、reg変数の追加など、動的なメモリ確保を最小限に抑え、より安全で高速に実行できる言語にカスタマイズされた独自言語です。

[公式リファレンス](https://docs.hise.audio/scripting/index.html)


## GUI仕様

スライダー（ノブ）、ボタン、コンボボックス、テーブル、波形表示などが用意されています。
パーツを自作画像に置き換えられるため、独自デザインのGUIを作ることができます。
UI全体の背景やロゴなどの画像を読み込んで表示するだけでなく、パス指定のベクタグラフィックスなど自由な描画ができます。
フローティングタイルを使用してWebページのように拡大縮小に対応した自動レイアウトも可能です。

## プログラム例

### ノートナンバー表示 

押された鍵盤のノートナンバーを表示します。
ConsoleのCは大文字であることに注意してください。

```javascript:interface.onNoteOn
function onNoteOn()
{
  Console.print("note = " + Message.getNoteNumber());
}
```

### MIDIチャンネルマッパー

HiseScriptはMIDIメッセージの操作も可能です。
ただし他のプラグインにMIDIメッセージを送ることはできないようなので、HISEに複数の発音モジュールをロードしてマルチティンバー楽器として使用する場合に利用できるスクリプトです。

```javascript:onInit
const var map = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
map[1] = 5; // map 1ch -> 5ch
map[2] = 3; // map 2ch -> 3ch
```

```javascript:onNoteOn
functionon NoteOn()
{
  Message.setChannel(map[Message.getChannel()]);
}
```

```javascript:onNoteOff
function onNoteOff()
{
  Message.setChannel(map[Message.getChannel()]);
}
```

```javascript:onController
function onController()
{
  Message.setChannel(map[Message.getChannel()]);
}
```


### エフェクター

さらに、限定的ですが信号処理のスクリプトを書くこともできます。
以下はScript FXを使用したFuzzエフェクターの例です。ノブで歪みの量を調整します。

```javascript:onInit
reg dataL;
reg dataR;
reg val;
reg drive;

const var knbFuzz = Content.addKnob("Fuzz", 50, 0);

Content.setPropertiesFromJSON("Fuzz", {
  "text": "Fuzz Drive",
  "defaultValue": 0.5
});
```

```javascript:processBlock
function processBlock(channels)
{
  drive = knbFuzz.getValue();
  dataL = channels[0];
  dataR = channels[1];
  for(i = 0; i < dataL.length; i++)
  {
    val = dataL[i];
    val *= 20.0 * drive;
    if (val > 1.0)
      val = 1.0;
    else if (val < -1.0)
      val = -1.0;
    val /= 10.0;
    dataL[i] = val;
  }
  dataL >> dataR;   
}
```


## 実行方法

### トップレベルのスクリプト

Master ChainモジュールのMIDIタブをクリック
![hs1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22455/bed30a21-07bc-b8f0-dde6-af5b2a59d411.png)
MIDI Processorの左端にある＋をクリックしてScript Processorを選択
![hs2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22455/ff2415a0-3179-6652-3892-ea2af7b402c6.png)
onInit、onNoteOnなどコールバックごとにタブがあるので選択して内蔵エディタに入力する
右下のCompileボタンを押すとスクリプトが適用される
![hs4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22455/e757360c-b95e-013c-ff62-006dbeb55ee4.png)
トップレベルのGUIは家アイコン(Frontend Panels)をクリックすると表示されます
![hs5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22455/e8dd10fc-5c82-098b-9f7f-d558fb5e5e25.png)

### 子モジュールのスクリプト

次に子モジュールのスクリプトの例です
Master Chainから例としてSine Wave Generatorを子モジュールとして追加します
![hs6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22455/b9491275-88bf-6a3e-fe7d-2eecce627de8.png)
今回はFXを作成します
Sine Wave GeneratorのFXタブをクリックする
![hs7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22455/00432f8d-acc7-ed0e-fc36-8a64a7c95c6b.png)
FXの左端にある＋をクリックしてScript FXを選択する
![hs8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22455/dd5df414-19de-028e-2f8e-725478949f3e.png)
FXの場合、コールバックがMIDIと異なります
スクリプトを入力してCompileボタンで適用する
![hs9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22455/5361a5dd-0b36-bfd4-64fa-5e8c60cd011f.png)
子モジュールのGUIはInterfaceタブを選択すると表示されます
![hs10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22455/d7bfd602-40b2-ecd6-f186-bf20a5b8332a.png)


## 感想

オープンソースながらHISE自体非常に安定しており、機能も豊富で、想像以上に完成度の高いソフトウェアという印象でした。
内蔵エディタも、シンタックスハイライトやショートカット、アンドゥなど用意されていて普通に使いやすいものになっています。
スクリプトは、商用ソフトウェアに比較しても圧倒的にAPIが充実していて多様な機能を実装することができます。また、JavaScriptそのままではなく、安全性と高速性を高めたカスタム言語であるところにもセンスを感じます。

さらに、今回は触れていませんがC++インタフェースやScriptnode Expression Language(SNEX)と呼ばれる高速な言語なども用意されています。もちろんオープンソースなのでソースコードを追加・改変することでHISE自体を変更することも可能です。ただしライセンスはGPL v3なのでその点は注意してください。

ただ、現状はサンプルスクリプトが非常に少なく、APIドキュメントだけ見てもわからないことも多い状況です。また、実用的なライブラリもほぼない状態で、このあたりが充実してくるとHISEのポテンシャルがもっと広く伝わるのではないかと思います。

[DTMプログラミング言語探訪](https://qiita.com/aike@github/items/77b3eccc6861de09513a)