ReaScript

PeloReaper Extensionの情報やダウンロードはこちらからどうぞ。
PeloReaper Extension for REAPER is here.
ReaperBanner01_w250 AudioSoftBanner01_w250

ReaScript入門(1): ReaScriptの初歩的なこと~Hello World

今回からREAPER上で動作させられるスクリプトやその動作環境などについて解説していきます。少しでもReaScript入門のハードルを下げていければと思っていますが、どうなることやら。


ReaScriptイントロダクション

ReaScriptとは

ReaScriptとはREAPER上で動かせるスクリプト(もしくはその実行環境のこと)を指します。厳密な解説は下記リンクの公式サイトに譲るとして、ひとまず「スクリプトを追加することでREAPERのActionを追加できる」のだと理解していれば十分かと思います。

ReaScriptからはREAPER本体やExtensionから提供されるAPIを呼び出したり、他の既存のActionを実行したりといったことが出来ます。APIはActionを作るためのプログラムの部品のようなもので、例えばTrackの個数を返してくれる関数など様々なものがあります。

では「これで何を実現できるか」というのは多岐にわたるのですが、例えば以下のようなものでしょうか。

  • 手間がかかる定型作業を1つのAction(スクリプト)で実行させるような自動化(Item編集やMIDI編集、FXのパラメータ設定等様々な作業に応用可能)
  • 既存のActionの動作では満足いかなかった場合に、自分専用にカスタムした動きのActionを作って作業オペレーションを最適化
  • カスタムGUIを作成して自分用のツールを作る
これらの他にもアイデア次第で自分のやりたい事を実現出来ると思います。

また、REAPER上で動作するスクリプトという意味では、オーディオFXやMIDI FXを作れるJSFX、動画などの画像処理を行うVideo Processorスクリプトなどもありますが、この記事の系列では扱いません。Video Processorについてはこの辺りで過去にいろいろ記事を書きましたので、そちらを見てもらうと良いかと思います。


ReaScript自作の必要性

ではどういった時にReaScriptを自作する必要があるのでしょうか?

REAPERを使い始めた初心者の方は、いきなりReaScriptを書く必要はありません。既に便利なActionやスクリプトが沢山ありますので、それを使って自分の作業環境を良くしていければ十分じゃないかと思います。

ReaScript自作に手を出す前に、試しに使ってみて把握しておくと良さそうなところをいくつかリストアップしておきますので参考にしてみて下さい(下に行くほど高度・面倒)。

  • デフォルトでREAPERに実装されている様々なActionを使ってみる。
  • SWSもインストールして、これに含まれるActionも使ってみる。
  • REAPER標準のCustom Action(複数のActionを並べて順番に実行できる、一般的なツールだとマクロ機能のようなもの)でActionを組み合わせて実行してみる。
  • ReaPackで有志の方が作成したスクリプトをダウンロードしていろいろ試してみる。
  • おまけとしてSWSのCycle Actionを試すのもアリですが、もうこのあたりからプログラミング色が強くなってきます(プログラミングに慣れてくればReaScriptで書いた方が楽かも)。

こういった既存の機能をいろいろと使っていくと、それらでは細かいところに手が届かないように感じたりする場面が出てきたりします。そう感じて更に自分に最適なActionが欲しくなってきたら、いよいよReaScriptを書く必要性が高まってきたと言えるでしょう。

とはいえReaScript自体に興味があるなら、もろもろすっ飛ばしていきなりスクリプトを作り始めてもいいと思います。上記の内容はあくまで参考までにということで。


ReaScript作成に使用できるプログラミング言語

ReaScriptを作成するのに使用できる言語はReaScript公式ページに記載されていますが、EEL2、Lua、Pythonから選ぶことが出来ます。Pythonはセットアップが必要なので、デフォルトの状態で使えるのはEEL2とLuaになります。

言語追加セットアップ解説
EEL2 不要 REAPERを含むCockosのツール専用の範囲ではあちこちで使われている言語。Video processorやJSFX等のオーディオ処理等にも用いられており、スクリプト実行パフォーマンスが良いとされています。REAPER内のみだけでスクリプトを組む前提なら、覚えておくといろいろなものを作れるようになるので便利な一方、REAPER以外ではほぼ使われていない言語なので、3つの言語のうち習得ハードルは最も高いと言えるでしょう。
Lua 不要 ReaScriptを書くのに最も標準的に使われている言語で、ネットにもLua言語解説の記事は多数存在するので習得が比較的容易です。REAPER以外のオーディオ関連ツールでもLuaの採用率は高い(例:Steinberg HALion、UVI Falcon、SurgeXT、Synthesizer V、Renoiseなど)ので、習得しておくとREAPER以外でも役に立つ可能性があります。何か特別な理由がなければLuaがオススメです。
Python 必要 上記2つの言語が割とコンパクトな規模のものなのに対して、様々なモジュールを用いて複雑な作業を割と容易に実現できるのがPythonの良いところ。言語自体の解説記事なども多く、習得が比較的容易。一見最強の選択肢に見えますが、いくつかデメリットも存在します。
  • REAPERでPythonを使うには追加のセットアップが必要。スクリプトを他人に配るなら、相手側にも同じPythonをインストールしたりする必要があったり、それに伴う面倒な環境依存問題に悩むことがあるかも。
  • 公式サイトにも書かれていますが、一部の機能がPythonではサポートされていなかったりします。
  • うろおぼえ的な記憶だと、Pythonスクリプト起動には若干時間がかかるので、スクリプトを高速に連打するようなことをやるとLuaと比べてかなり処理が遅くなることもあったような・・・(最近試してないので、既に改善されている可能性はあります)。

いろいろ書いてしまいましたが、ザックリまとめると

  • 一般的にはLuaがオススメ
  • 多少手間はあるけど複雑な事をサクッとやりたいならPythonも使う
あたりが落としどころでしょうか。

※今後の記事ではLuaを使用することを前提として解説を進めていきます。また、Lua言語自体の書き方や言語仕様等の説明も出来るだけ割愛させて頂くことにして、ReaScript固有の部分に的を絞って解説しますのでご了承下さい。


(おまけ)REAPER Extensionについて

REAPERのAPIは上記で紹介したスクリプト言語からだけでなく、C言語から呼び出す方法も用意されています。C言語で作成されたREAPERのプラグインは特別にREAPER Extensionと呼ばれています。こちらはLua等のテキストファイルを追加すればサクッとActionを追加出来るというような代物ではなく、作成のハードルは非常に高くなっています。

過去に当ブログでもREAPER Extensionの作り方についてこの辺りの記事で解説していますが、ゴリゴリのエンジニア向けの内容となります。本記事の読者向けには「まぁそんなものもあるのね」くらいに知っておいてもらえればOKです。


ReaScriptを作成してみる

ReaScript作成~実行方法

それでは簡単なReaScriptを作成して、実行してみましょう。

  1. REAPERメインメニューから [Actions > Show action list...] でAction Listを表示します。
  2. Action List下部にある [New action...] ボタンをクリックして [New ReaScript...] を選ぶと、スクリプトの保存場所を聞かれます。 ReaScript_HelloWorld_AddNewScript
  3. ファイルの種類は [Lua files (*.lua)] で、ファイル名は任意に指定します(ファイル名はそのままAction名になるのと、利便性の都合上日本語は用いずに半角英数のみのファイル名にしておくのがオススメです)。
    ここでは HelloReaperWorld.lua という名前にして保存します。
    ReaScript_HelloWorld_AddNewScriptFile
  4. 保存するとスクリプトを編集するテキストエディタが表示されますが、実はもうこの時点でスクリプト自体の作成(とそれに対応するActionの追加)は完了していて、Action Listに「Script: HelloReaperWorld.lua」というActionが並んでいると思います。もちろん、実行も可能です(スクリプトが空なので何も起きませんが)。
    ReaScript_HelloWorld_Action

Hello World:テキストを表示するプログラムの作成

では作成したスクリプトにエディタ上で以下のコードを追加して、Ctrl+Sで保存してみましょう。保存すると、同時にActionも実行されます。

reaper.ShowConsoleMsg("Hello REAPER World!!")

ReaScript_HelloWorld_Code_01

REAPERのコンソールウィンドウが開いて、「Hello REAPER World!!」と表示されたのではないでしょうか。
ReaScript_HelloWorld_Result

これでLuaによる初めての自作ReaScriptの完成です! あとはいつでもAction Listから呼び出すことが可能です。

プログラムの簡単な解説

  • REAPERのAPIは、Luaだと「reaper.API名(パラメータ)」のような形で呼び出せます。
  • 「ShowConsoleMsg」はREAPERのコンソールウィンドウにメッセージを表示するAPIで、パラメータとして "Hello REAPER World!!" という文字列をセットしています。

作成したスクリプトを後から修正したい場合

また、後からこのスクリプトを修正したい場合は、追加したスクリプトのActionをAction Listで選択して [Edit action...] ボタンで編集出来ます。

ReaScript_HelloWorld_EditScript


作成したスクリプトを削除したい場合

既に作成してあるスクリプトのActionを選択して、Action Listの [Delete] ボタンで削除できます。

ReaScript_HelloWorld_DeleteScript


既に作っておいたScriptを読み込んでActionにしたい場合

最初にスクリプトを作成する時と似ていますが、Action Listのボタンで [New action... > Load ReaScript...] からスクリプトのファイルをロードすればOKです。

ReaScript_LoadScriptFile



今回はここまで。前置きが長かった割に、スクリプトを作り始めたらあっという間だったのではないでしょうか。Actionをこんなにも簡単に追加出来ると分かると、夢が広がりますよね。


[SWS] Loudness・RMSとReaScript

お久しぶりです、ぺろりです。
しばらく放置状態でしたが、また少しずつREAPER関連の情報を書いていこうかなと思います。
(できるだけサクっとラクに書けるものを・・・)

今回はSWSに実装されている、ラウドネスの計測機能についてです。
・・・といいたいところですが、ネット上にはこのへんガッツリ解説されてるページが既にあるのでもうそっち見て下さいという感じ。
→ ポジティブ・アレルギー:REAPER:ラウドネス・アナライズ&ノーマライズ

ちなみにRMSでActionを検索すれば、RMS計測とかRMS順にItem並べ替えるとかいったActionも出てきますので、必要に応じて利用できます。

実際のところ、ほとんどのREAPERユーザーはここまでの機能が使いこなせれば十分なのではないでしょうか。

ところが

まだもうちょっと先があるんですね。
実はReaScriptやExtensionのプログラミング向けに、SWSからAPIが公開されてるんですよ。
このへんはまさにREAPERならではという感じでしょうか。

SWSインストール済みのREAPERでメインメニューから [Help>ReaScript documentation..] を選ぶとAPIリファレンスが表示されます。
このリファレンスのThird-party API Function ListというところにSWSなどのExtensionから公開されているAPIが並んでいます。
ラウドネス計測機能であれば、NF_AnalyzeTakeLoudness* 系のAPIがあるはず。
NF_なんたらにはRMS関連の計測APIもありますね。
SWS_API

試しにNF_AnalyzeTakeLoudness_IntegratedOnlyをReaScript(lua)で使ってみた例はこちら。
SWS_Script_LI

こんな感じで簡単にプログラムからラウドネス値が取得できます。
この例ではあくまでシンプルな例としてIntegratedのみを取得していますが、より詳細なラウドネス情報を取得したい場合は、NF_AnalyzeTakeLoudness2あたりを使うとよいでしょう。

てことで今回はSWSから公開されている、Loudness,RMS関連APIの簡単な紹介でした。
また次の記事でお会いしましょう。

C++ REAPER Extension (6) : CやReaScript(lua,EEL)にAPIを公開

こんにちは、ぺろりです。
今回はExtensionからC/C++とReaScript(lua,EEL)に対してAPIを公開する方法を紹介します。
Pythonでスクリプトを書く方法は試してないので機会があれば・・・。

ここまで読み進めて来たという方であればコード見ればすぐ分かりそうですので、そこからいきましょう。
/// REAPER経由での公開関数
/// @param[in] num 任意の数値
/// @return てきとーに計算した結果
static int UnkoFunc(int num)
{
	return 2 * num; // てきとーに値を倍にして返すだけ
}
/// 単なる便利用typedef
typedef int (*FUNC_UnkoFunc)(int);

/// Luaから呼び出せるようにするための関数
/// - Script系の言語からはCの関数を直接ではなくて、こういった可変引数的な呼ばれ方をする模様
/// @param[in] arglist luaとかからくる引数リスト
/// @param[in] numParams arglistの要素数
/// @return 結果の値(ここだとUnkoFunc()の戻り値)
static void* __vararg_UnkoFunc( void** arglist, int numParams )
{
	// Cで公開していた関数を呼ぶ
	int res = UnkoFunc( (intptr_t)arglist[0] );
	// 戻り値をvoid*にして返してやる
	return (void*)(intptr_t)(res);
}

REAPER_PLUGIN_DLL_EXPORT int 
REAPER_PLUGIN_ENTRYPOINT(
	REAPER_PLUGIN_HINSTANCE hInstance, reaper_plugin_info_t *rec)
{
	// (中略)
	// 初期化時の処理で、以下の登録処理を行う

	// 公開する処理を書く関数を登録
	plugin_register( "API_UnkoFunc", (void*)UnkoFunc );
	// 関数の引数やHelp文字列などの情報を登録
	plugin_register( "APIdef_UnkoFunc",
			"int\0int\0num\0[Pelori:API]Exported Unko API" );
	// luaなどのスクリプト側から呼ばれる関数を登録
	plugin_register( "APIvararg_UnkoFunc", __vararg_UnkoFunc );


	// Cで呼び出せるかのテスト
	// 関数のアドレスをREAPERから取得
	FUNC_UnkoFunc unkofunc_ptr = (FUNC_UnkoFunc)(rec->GetFunc("UnkoFunc"));
	// 呼び出してみる
	int unkoResult = unkofunc_ptr( 3 ); // 3*2=6が返ってくればOK

// (後略)
}

plugin_register( "API_UnkoFunc", (void*)UnkoFunc ) は、"UnkoFunc"という名前でExtensionAPIを登録しています。"API_"以下の部分が公開APIの名前となりますが、登録する関数(第2引数のやつ)の名前は合わせなくても問題ないようです(__UnkoFuncという関数を登録しても問題なかった)。

plugin_register( "APIdef_UnkoFunc", ... ) ではAPIの戻り値、Helpテキストといった情報を登録します。これも登録が必須です。文字列のフォーマットは
"戻り値\0引数の型リスト\0引数の名前リスト\0Helpテキスト"
といった感じでしょうか。複数引数があるなら、例えば "int\0int,double\0arg1,arg2\0Hoge Function" という感じです。

plugin_register( "APIvararg_UnkoFunc", ... ) はスクリプトから呼ばれる関数登録となります。スクリプトからは "API_○○" で登録した関数が直接呼ばれるわけではありません。"APIvararg_○○" で登録した関数が呼ばれることになります。
スクリプトから呼び出されると、引数(arglist)がどれだけ積まれたか(numParams)という情報がやってきますので、必要なだけ情報を引用して結果を返してやればいいようです。今回のサンプルだと UnkoFunc を呼んで結果を返してやればOK。

あとはExtension終了時に plugin_register( "-API_UnkoFunc", (void*)UnkoFunc ); などで登録したものを解除して実装完了です。(このへんはまぁ、もう分かりますよね)

実際のところ、1つのAPI登録で3つの登録用文字列が必要なことから、沢山APIを公開しようとすると結構煩雑になっていくと思います。SWSのReaScript.cppあたりを見てみると、マクロで文字列を一括定義したりといった部分などもろもろ参考になるのではないかと思います。



これらを実装したExtensionをREAPERにインストールしてからREAPERを起動して、reaper_plugin_functions.hを書き出す(Action"[developer] Write C++ API functions header"で[Write functions exported by 3rd party extensions]にチェックを入れる)と、自分で登録した関数(ここだとUnkoFunc)がヘッダに出力されて使えるようになります。
// (↓ reaper_plugin_functions.hに書き出された部分)
#if defined(REAPERAPI_WANT_UnkoFunc) || !defined(REAPERAPI_MINIMAL)
REAPERAPI_DEF //==============================================
// UnkoFunc
// [Pelori:API]Exported Unko API

  int (*UnkoFunc)(int num);
#endif

・・・っと書いたものの、自分の環境だとこの3rdPartyの関数も出力したreaper_plugin_functions.hを使おうとしてみたところ、他のExtensionが公開している関数で使われている構造体などの型が見つからず、コンパイルエラーになってしまいました(このへんもうちょっと頑張って取り組むのは後にしようかと思います)。
なので、自分は前述のサンプルコードにあるようにGetFunc()で関数ポインタを取得して使う方法を今のところ使っています。

ひとまずC++側では呼べるようになったので、次はluaで呼び出してみます(ActionListでReaScriptのNewボタンでluaファイルを作成してスクリプトを書きます)。
val = reaper.UnkoFunc(3)
reaper.ShowConsoleMsg(val)
QS_20180128-190450
ハイ、簡単ですね。

ついでにEELでも試してみます。今度は.eelファイルを作成して書きます。
EELではExtension APIの呼び出しに extension_api() を使います。
num = extension_api("UnkoFunc", 3);
sprintf(#str, "Result:%d", num);
ShowConsoleMsg(#str);
QS_20180128-192654

ちなみにExtensionからの公開関数はREAPERのメニューから、[Help > ReaScript documentation]でHTML出力されるので、自分の関数がこのHTMLにも表示されるようになります。
QS_20180128-195149


今回はREAPERのExtension API公開方法を解説しました。
これでスクリプトからもあなたの関数を呼び出すことができて、また一段とREAPER機能実装の自由度が上がるのではないかと思います。

しかしこのDAW、ホントやりたい放題出来てオモチャとして面白すぎる・・・

ではまた次の記事でお会いしましょう。
このブログについて
ぺろりがREAPERで遊びたいというだけのブログかもしれない

必ずこちらをお読みください

twitter: @pelori

管理人用
  • ライブドアブログ