REAPERの拡張機能ReaWwiseがリリースされ、その作成に至るまでの経緯を紹介するよい機会であると考えました。本ブログは2部に分け、前半の今回はReaWwiseプロジェクトのプロダクション前のプロセスを、後半で拡張機能の開発について説明したいと思います。
REAPERを選択した理由
ゲームオーディオ業界ではDAWに対する期待が高く、ニーズも非常に具体的です。大多数のDAWのワークフローはタイムラインに沿っています。タイムラインを軸とするワークフローをインタラクティブ性のある部分に、活用することができるのでしょうか?
DAWがゲームオーディオのワークフローで成功するための要素をいくつか紹介します:
- さまざまな形式のコンテンツを一括エクスポートする機能
- カスタマイズできるインターフェースとワークフロー
- 拡張性
- 容易な自動化、スクリプト作成
- 迅速、軽量、ポート可能
REAPERはこれらのチェックボックスをすべて満たしています。REAPERを提供しているCockos社はコミュニティの声に耳を傾けてきたのです。だからこそREAPERは、ゲームオーディオのニーズに応える人気上昇中のDAWであるのかもしれません。
出発地点
私たちはしばらく前からREAPERのインテグレーションを作成したいと考えていました。数年前にKarl Davis(@karltechno)がReaper-Waapi-Transferを手がけたのがきっかけです(https://github.com/karltechno/Reaper-Waapi-Transfer)。REAPERからWwiseにオーディオファイルを転送するためのワークフローが、実現可能であることを証明してくれたプロジェクトでした。このアイデアをさらに発展させ、アクセスをより簡単にしたいと私たちは思いました。
WAAPI Transfer
REAPERがゲームオーディオコミュニティで普及しはじめていることを知っていた私たちは、いずれ行動を開始すべきだと考えていましたが、その前にコミュニティの人々がどのようにREAPERを使用しているのかを理解したいと感じました。
ユースケースを理解する
調査を開始するにあたりいくつかのスタジオのサウンドデザイナーのヒアリングを行い、彼らのワークフロー、コンテンツ整理の仕方、そしてREAPERのカスタマイズ方法などを聞きました。私たちは次のようなことに気づきました:
カスタムユーザインターフェース:REAPERは柔軟性に大変優れていますが、そのままではゲームオーディオに最適化されたワークフローとなりません。REAPERの使い心地をよくするために、スタジオ側でユーザインターフェースやワークフローのカスタマイズに時間をかける必要があります。
キャンバス代わりになるタイムライン:ほとんどのユーザが、タイムラインをサウンドデザインのキャンバス代わりに使っています。REAPERのタイムラインを使い、簡単にクリップをインポート、スケッチ、並べなおすことができます。REAPERは軋轢のない自由形式のサウンドデザインを可能にします。
リージョン:リージョンはタイムライン上で個別のエリアを区切るためによく使われます。エクスポートバウンダリと一致することが多いです。リージョンはメタデータの保存にも使用します。REAPERプロジェクトに数十のリージョン、多い場合は数百ものリージョンがあることも珍しくありません。リージョン名がレンダー設定で使用されることがあるため、リージョン名においても命名規則が採用されます。異なるバリエーション、バージョン、ステート、スイッチを識別するためにリージョンを使用することができます。例えばフットステップのプロジェクトでは、リージョンの中にさまざまなバリエーションや地面の種類(コンクリート、芝生、石など)が含まれているかもしれません。
トラック:みなさんは水平方向をキャンバスとして使っているほか、縦方向を整理整頓のために使っているようです。トラックはデータ構造を組み立てるために使うことができます。再生時にオーディオをミックスするためだけではないのです。プロジェクトに数百ものトラックがあり、私たちはミュートやソロのボタンを利用してプロジェクトの特定部分にフォーカスできるようなプロジェクトをいくつか見てきました。
レンダー設定:最初はREAPERのレンダー設定が威圧的で抵抗を感じるかもしれませんが、レンダーエンジンこそREAPERの強みの1つです。ワイルドカードシステムがレンダーエンジンを力強いものにします。ワイルドカードを多用して命名規則に準拠させることで、同時に数百個のWAVファイルを一括エクスポートすることができます。
リージョンレンダーマトリクス:これも威圧的に感じるかもしれませんが、レンダリングしたいトラックやリージョンをリージョンレンダーマトリクスで設定することができます。レンダリングする時にプロジェクトのどの部分を一緒にミックスダウンするのかを、マトリクスで指定します。
サブプロジェクト:大規模なデータの管理にサブプロジェクトを利用するスタジオを、私たちはいくつか見ました。サブプロジェクトをコンテンツの抽象化や整理に使用することができます。大きいチーム内で仕事を分割し、ソースコントロールのコンフリクトを最小限にするためにもサブプロジェクトが便利です。
カスタムスクリプト:ReaPackなどの配信システムを通してさまざまな種類のスクリプトが公開されていますが、実際には多くのユーザが自分たちでスクリプトを開発しています。ReaScriptはプログラミングの知識がはじめに多少必要ですが、REAPERをカスタマイズするためのアクセスしやすいシステムです。
最初のプロトタイプ
みなさんはREAPERで何をしていて、どのように使っているのかをよく理解できたところで、このインテグレーションで何を可能にしたいのかを私たちはおおまかに定義しはじめました。次の2つを主な目的とすることに決めました:
- レンダリングされたWAVファイルのWwiseへのインポート。
- レンダリングされたファイルと共に、Wwiseオブジェクト構造を作成する。
UX面の目標もいくつかありました:
- セットアップは1回とし、イテレーションを迅速にする。
- 命名規則を細かく制御する。
最初のデモとして“FS”というREAPERプロジェクトをつくりましたが、これには2つのリージョンと数個のトラックが入っています。
FSというREAPERプロジェクトのタイムライン
リージョンごとに1つのWAVファイル、つまり2つのWAVファイルを作成するとし、以下のワイルドカードを使用することにします:
- $project: REAPERプロジェクト名の“FS”となります。
- $regionnumber: リージョン番号“1”、“2”となります。
REAPERレンダー設定
ここでWwiseにWAVファイルをインポートするためには、当然WAAPIを活用してak.wwise.core.audio.import関数を利用すべきだと考えられます(https://www.audiokinetic.com/library/edge/?source=SDK&id=ak_wwise_core_audio_import.html)。
この関数はタブ区切りテキストインポート(https://www.audiokinetic.com/library/edge/?source=Help&id=importing_media_files_from_tab_delimited_text_file)とコアコードが同じです。
事例として以下は1つのランダムコンテナと2つのサウンドを定義するタブ区切りインポートファイルですが、同じことをWAAPIで行うこともできます。
オーディオファイル |
オブジェクトパス |
C:\wave\REAPER\FS_GRASS_01.wav |
\Actor-Mixer Hierarchy\Default Work Unit\<Random Container>FS_GRASS\<Sound SFX>SFX_FS_GRASS_01 |
C:\wave\REAPER\FS_GRASS_02.wav |
\Actor-Mixer Hierarchy\Default Work Unit\<Random Container>FS_GRASS\<Sound SFX>SFX_FS_GRASS_02 |
これで以下の階層が作成されます:
Wwiseで作成される階層
REAPERのワイルドカードシステムを使用してWAVファイルを命名することができるのであれば、同じしくみでProject Explorerに表示されるWwiseオブジェクトを命名できないかと自然と考えました。というのも、最終的にそれらは互いに連携するべきだからです。ユーザはWAVファイルとWwiseオブジェクトの双方の命名規則を制御できるべきです。
オブジェクトパス列を生成するワイルドカードのレシピはこのようになります:
\Actor-Mixer Hierarchy\Default Work Unit\<Random Container>$project\<Sound SFX>SFX_$project_$regionnumber
私たちはReaScript で何が可能なのかを探りました。REAPERがRender設定ではなく任意の文字列に対し、自身のワイルドカードを解決することができるのかを確認してみたかったのです。答えはNoです。そこでテストのために、非常におおざっぱなことを試みました:
1. Render設定のfile nameフィールド値をバックアップします。
2. リクエストされるWwiseのオブジェクトパスを、Render設定のfile nameフィールドに設定します。
3. レンダリングされたファイル名のクエリを行います(すでにこれはファイル名ではなく、出されたオブジェクトパスになっています)。
4. 以前のfile nameをRender設定で復元します。
なんと!上手くいきました。もともと複数のREAPERワイルドカードを含んでいたオブジェクトパスとすることができました。ただし、これはかなりのハッキングです。REAPERのUIは点滅していて、Render設定の整合性を危機にさらしていました。
REAPERチームにサポートを依頼する
私たちはCockosチームに連絡して、目標達成のための協力をお願いしました。私たちが聞いたのは:
各レンダーファイルのREAPERワイルドカードを含む任意の文字列とすることのできる関数を、ReaScriptで公開することは可能ですか?
彼らはとても反応が速く、この機能のあるビルドをすばやく提供してくれました。私たちはそれがうまくいくことをすぐに確認しました。REAPERの次のバージョンにこの機能が含まれていました。CockosのJohn Schwartz氏とJustin Frankel氏に、ここでお礼を申し上げます。最高です!ありがとう!
こちらはオブジェクトパスとなる、ワイルドカードを含む別のインポート式を使う初期のプロトタイプです:
ReaWwise初期のプロトタイプ
インポート後に以下の構造がWwiseで作成されます:
ReaWwiseが作成したWwise階層
この時点で私たちは目標に到達できると自信を持ちました。次に将来的な拡張のためにユーザエクスペリエンスを改善する必要がありました。
ユーザエクスペリエンス
そこでユーザエクスペリエンスのイテレーション作業を開始しました。初期プロトタイプのようにコードで行うのではなく、静的なモックアップを使用してすすめました。モックアップはすばやくイテレーションができるため、とても便利です。私たちは拡張機能のためのユーザインターフェースのドラフトを書きはじめました。さまざまな関係者を議論に引き込み、数週間のイテレーション作業を行いました。
これは私たちのイテレーション結果を示す初期のコラージュモックアップです。
開発中に作成したReaWwiseのモックアップ
ある時点で私たちはコードに戻り、ほかの仮定の検証を行いながら実際のREAPERプロジェクトでアイデアをいくつかテストしました。この時の新しいプロトタイプはWAAPI-transferコードで直接作成しましたが、このコードはVisual C++のセットアップ、Win32 Windows初期化、REAPERハンドシェイク、WAAPIコミュニケーションなど多くのものをすでに実装していました。
ReaWwiseの別のプロトタイプ
このプロトタイプを社内でイテレーションとデモを行い、共有しました。私たちはいよいよ方向性が正しいという自信をもてました。プロジェクトを実現するチームを見つけ、プロジェクトをロードマップ上にスケジュールとして組み込む必要がありました。
後半につづく
ブログの後半では拡張機能の開発作業に焦点をあてます。複数のプロトタイプの後に何が起きたのかを紹介します。後半はReaWwiseのメインデベロッパであるAndrew Costaが担当します。
コメント