2回クリックするだけでREAPERからADXへの素材インポートができる裏ワザ
※本記事はCRI Chinaが公開した以下の記事を日本語化したものになります。
什么神仙操作?样本从REAPER转到ADX,点两下鼠标就解决了?
https://mp.weixin.qq.com/s/KGjgGqcjp4PehuIVfYKC3Q
サウンドプロジェクトを作成するときに、次のようなことを経験していませんしたか?

(上:大量にある素材
左:今日は超格好いい素材を作ったからキューにして見せつけてやるぞ
右:すごいね~できてからカッコつけようね~
赤文字:(こんなに素材があったら作業で疲れ死ぬ)
気分上々な一日は、「素材を選び、プロジェクトをインポートして、キューを作成する」という単純でリズミカルな仕事から始まりました。
Let’s Rock n Roll!


しかし重複作業していると、上の空になって、こんな面白おかしいミスをしてしまうことも避けられません(下図)

ユーザーさんたちからのツッコミを聞いているうちに、CRIの開発チームは一つ大胆なアイデアを思いつきました。
「Robotでスクリプトを書けばこんなの一発で終わるじゃん!」

素材が多くない場合、データ変換は構造を保ったまま瞬時に完了できます!
もちろん、詳細なスクリプトの説明とサンプルプロジェクトは包み隠さずお伝えします。
さあ、始めましょう!
リモート接続の準備
Atom Craftロボット機能の全体的な紹介は、ぜひともチュートリアル連載をご確認ください。
今日はその中でもリモート制御のやり方について練習していきましょう!
CRI ADX2 サウンドオーサリングツール AtomCraft チュートリアル「Atom Craft ロボット編」
https://game.criware.jp/learn/tutorial/atomcraft/#robot
元記事:チュートリアル(中国語版)のURL
https://www.criware.cn/Home/Goods/study_1_list/cat_id/47/article_id/282.html#
Pythonでcri Robot APIを呼び出すには、ランタイムライブラリを導入する必要があります。 これらのランタイムライブラリは、AtomCraftのルートディレクトリにあるrobot/remote/pythonフォルダーにあります。
APIをimportする必要がある場合、スクリプトを正しいファイルパスに配置する必要があります。 たとえば、AtomCraftにリモート接続する場合、cri.atomcraft.criatomcraft_libをimportする必要があるため、実行するスクリプトでは、robot/remote/pythonの下にあるcriフォルダーの内容に合わせて調整する必要があります。(テイ:原文のままだがなにを調整するのかはわからない)
Pythonを使用してReaperを制御できるようにするには、ReaperのReaScriptを使用する必要があります。ReaScriptはPythonを含む多種なスクリプトをサポートできますが、最初にいくつかの設定を行う必要があります。
Reaperメニューバーで[Option]-> [Perference]を見つけ、その中の[Plug-ins]-> [ReaScript]を見つけて、[Enable Python for use with ReaScript]をチェックします。

そのあとにPythonライブラリへのパスとdllファイル名を指定します。これで、Pythonを使用してReaperを制御できます。 次に、ReaScriptを使用して、AtomCraft Robotのリモート接続用のApiをインポートし、ReaperとAtomCraftの間の連動を実現します。
ReaScriptからスクリプトを起動
Reaperメニューバーから[アクション]-> [アクションリストの表示]にたどり着きます。便利なスクリプトを以前にもインストールしている場合、ここではそのすべてが表示されます。 次に、[New Action]-> [Load ReaScript]を見つけます。ここで、実行しようとしているスクリプトをロードしてRobotに接続できます。スクリプトの中でcri.atomcraft.criatomcraft_libをimportする必要があるため、ロードされるスクリプトは[cri]フォルダと同じディレクトリに置く必要があります。

AtomCraftサーバーを起動
AtomCraft側にも相応な準備が必要です。AtomCraftメニューバーで[スクリプト]-> [サーバー]-> [スクリプトサーバーを起動]を見つけてください。 起動後、Pythonを使ったAtomCraftへのリモート接続ができるようになります。
ワンクリックでAtomCraftキューを生成
今回のサンプルスクリプトでは、ReaperプロジェクトにあるTrackとそれに含まれるMediaItemをワンクリックでAtomCraftプロジェクトのキューに転送します。ReaperのプロジェクトはAtomCraftのキューに、Trackはキューのトラックに対応し、MediaItemは波形リージョンと対応関係にあります。(ReaScriptとRobotを習熟するためには、それぞれのオブジェクト構造を理解する必要があります。AtomCraftのオブジェクト構造につては、以前のRobotチュートリアルをご参照ください)
スクリプト(コメント付き)
以下のスクリプトはまだ改善されており、処理されていない可能性のあるエラーがまだ多くあります。一部のパラメーターをローカルプロジェクトの設定と一致させる必要があります。ご参考までにご確認ください。
実際の使用では、いくつかのパラメータを変更する必要があります。
import cri.atomcraft.criatomcraft_api_lib as acconnect
import cri.atomcraft.debug as acdebug
import cri.atomcraft.project as acproject
def GenerateAtomCue():
# get all mediaitems
#(すべてのmediaitemを走査して取得する。RPR_GetNumTracks()とRPR_GetTrackNumMediaItems()を使って、Reaperプロジェクトのトラック数とトラック内のアイテム数を取得できます。最終結果はmediaitemsの2次元リストに保存されます。)
mediatrack = []
mediaitems = []
for i in range(RPR_GetNumTracks()) :
mediatrack.append(RPR_GetTrack(0, i))
_mediaitem = []
for j in range(RPR_GetTrackNumMediaItems(mediatrack[i])) :
_mediaitem.append(RPR_GetTrackMediaItem(mediatrack[i],j))
mediaitems.append(_mediaitem)
# get each item position
#(RPR_GetMediaItemInfo_Value()を使用して、タイムライン上のすべてのmediaitemの位置を取得します。RPR_GetMediaItemInfo_Valueは、位置だけでなくアイテム内のさまざまな属性も取得でき、最終結果はpositionsという2次元リストに保存されます。)
positions = []
for i in mediaitems:
_position = []
for j in i:
_position.append(RPR_GetMediaItemInfo_Value(j, "D_POSITION"))
positions.append(_position)
# get each sound source path from each item
#(素材ファイルをAtomCraftに登録するには、ファイルパスを取得する必要があります。 Reaperでは、アイテムに複数の「take」が存在する可能性があります。このサンプルスクリプトでは、1つのアイテムは1つのテイク(シーケンス0のテイク)にのみ対応するとみなします。実際の状況では、デザイナーの意思に従ってさらに細分化することもできます。 最後に、RPR_GetMediaSourceFileName()でこのtakeのmaterialのファイルパスを取得し、その結果をsource_filenamesという2次元リストに保存します。)
source_filenames = []
for i in mediaitems:
_source_filename = []
for j in i:
_take = RPR_GetMediaItemTake(j, 0)
_source = RPR_GetMediaItemTake_Source(_take)
_result = RPR_GetMediaSourceFileName(_source, "", 512)
_filename = _result[1]
_source_filename.append(_filename)
source_filenames.append(_source_filename)
# connect to AtomCraft
#(AtomCraftに接続するための手順です。このサンプルスクリプトでは、ロカールマシーンに接続します。 (AtomCraftサーバーはポート9000を使用します))
result = acconnect.initialize()
if result != 0:
RPR_ShowConsoleMsg("initialize error")
return
result = acconnect.connect("127.0.0.1", 9000)
if result != 0:
RPR_ShowConsoleMsg("connection failed")
acconnect.finalize()
return
# get workunit
#(現在のプロジェクトのWorkUnitを取得します。デフォルト名は(WorkUnit_0)です。)
result = acproject.get_workunit("WorkUnit_0")
if not result["succeed"]:
acdebug.warning("Failed to get WorkUnit")
RPR_ShowConsoleMsg("Failed to get WorkUnit")
return
workunit = result["data"]
# register material
#(保存されたマテリアルのファイルパスのリストを使用し、register_materialで対応のマテリアルをAtomCraftのマテリアルツリーに登録します。対応のファイルもAtomCraftプロジェクトのマテリアルディレクトリに自動的にコピーされ、返されたmaterialオブジェクトも後で使うためにmaterialsリストに保存されます。)
material_rootfolder = acproject.get_material_rootfolder(workunit)["data"]
materials = []
for i in source_filenames:
_material = []
for j in i:
result = acproject.register_material(material_rootfolder, j)
if not result["succeed"]:
RPR_ShowConsoleMsg("Failed to register material")
break
_material.append(result["data"])
materials.append(_material)
# get CueSheet (you can create a CueSheet by yourself)
#(キューを作成するために必要なCueSheetを取得します。サンプルスクリプトでは、CueSheet_0というキューシートが既にプロジェクトに存在していると仮定します。)
cuesheet_rootfolder = acproject.get_cuesheet_rootfolder(workunit)["data"]
cuesheet_folder = acproject.get_child_object(cuesheet_rootfolder, "CueSheetFolder", "WorkUnit_0")["data"]
cuesheet = acproject.get_child_object(cuesheet_folder, "CueSheet", "CueSheet_0")["data"]
# create a Cue
#(このReaperプロジェクトに対応するキューを作成します。キューが既に存在している場合は既存のものを取得します。)
cue = acproject.create_object(cuesheet, "Cue", "From_Reaper")["data"]
cue = acproject.get_child_object(cuesheet, "Cue", "From_Reaper")["data"]
# create Tracks and Waveformregions
#(上記手順で取得したmediaitemに従って、create_objectでトラックを作成し、各itemの設定に従ってトラックの下に波形リージョンをcreate_waveform_regionで作成し、タイムライン設定に従ってset_valueでリージョンの開始位置を設定します。)
tracks = []
waveform_regions = []
x = 0
for i in materials:
x = x + 1
_track = acproject.create_object(cue, "Track", "Track"+str(x) )["data"]
tracks.append(_track)
waveform_region = []
for j in i:
result = acproject.create_waveform_region(tracks[materials.index(i)], j)
waveform_region.append(result["data"])
acproject.set_value(result["data"], "DelayTimeMS", positions[materials.index(i)][materials[materials.index(i)].index(j)]*1000)
waveform_regions.append(waveform_region)
# disconnect
acconnect.disconnect()
acconnect.finalize()
RPR_ShowConsoleMsg("Cue Generated")
return
GenerateAtomCue()
スクリプトの実行
スクリプトをテストするために、次のサンプルプロジェクトを使用して試してみます。

サンプルプロジェクトを開いた後、メニュー[アクション]-> [アクションリストの表示]を選択して、スクリプト管理UIを開きます。 [New Action]-> [Load ReaScript]を選択し、前に編集したPythonスクリプトを見つけて、追加します。スクリプトは、CRIが提供しているRobotランタイムライブラリをインポートする必要があり、即ちランタイムライブラリと同じディレクトリに置く必要があるので、ご注意ください。
追加後、スクリプトを実行できます。

実行後、ダイアログボックスが表示されます。成功した場合、AtomCraftは次のような表示になります。

Reaperのプロジェクトの構造がAtomCraftのキューとしてそのまま登録されていることがわかります。 魔法のように感じませんか?
まとめ
このタイプの方法を使用すると、サウンド担当者はAtomCraftを簡単に統合できます。もちろん、実際のアプリケーションでは、異なる利用シナリオの要件に対応する必要があり、ユーザーは自分でスクリプトを変更する必要があります。プログラマーがAtomCraft RobotのAPIに慣れてくると、サウンドデザイナーに多数の便利な自動化ツールを提供でき、開発効率が大幅に向上されます。
Author: Yin Long, Jiawei Lu
Translate: Yunpeng Bai, Haokan Cheng
