Skip to content

ミキシングシーン JSON

シーンは、ミキサー全体をプレーンデータで記述したものです。Mixer.fromSceneJson(...) が読み、toSceneJson() が書き出す形式(Python では from_scene_json(...) / to_scene_json())で、WASM・Python・Node・C ABI・C++ で同一です。プレーンな JSON なので、プロジェクトと一緒に保存し、git で差分を取り、手で編集し、あとから読み直せます。

ストリップ・センド・バスにまだ馴染みがなければ、先に ミキシングの基礎ミキシングエンジン を読んでください。本ページはフィールドごとのリファレンスです。

このページで身につくこと

このページを読むと、次のことを判断・実装できるようになります。

  • シーン最上位の形と、ストリップ、バス、VCA グループ、接続の役割を見分けられる。
  • ストリップ制御、インサート、センド、ルーティング辺を混同せずにシーンを編集・生成できる。
  • どのフィールドに既定値があり、どの識別子をグラフ内で一致させる必要があるかを理解できる。
  • 組み込みプリセットを、カスタム Scene JSON の安全な出発点として使える。

実例で形式を学ぶ

スキーマを理解する最速の方法は、組み込みプリセットを出力して読むことです。mixingScenePresetJson('vocalReverbSend') の出力には以下のすべてのフィールドが現れるので、各キーを実際の値と対応づけられます。ページ末尾の注釈つきシーンがまさにそれです。

最上位の形

json
{
  "version": 1,
  "strips": [],
  "buses": [],
  "vcaGroups": [],
  "connections": []
}
フィールド意味
versionintegerスキーマバージョン。現在は必ず 1。他の値は拒否されます。
stripsarrayトラックレーン(ストリップ参照)
busesarray共有の行き先。master を含む(バス参照)
vcaGroupsarray複数ストリップを一括調整するレベルグループ(VCA グループ参照)
connectionsarrayルーティンググラフの辺(接続参照)

未知のキーは無視されるが、insert パラメータは監査される

パーサーは認識しないシーンフィールドを無視するため、前方互換のプロデューサは古いリーダーを壊さずにメタデータを追加できます。裏を返せば、綴り間違いのシーンキーは黙って捨てられますprocessorName(誤)と processor(正)が典型です。設定が効かないように見えたら、以下の表と綴りを照合してください。

インサートの params キーにはセーフティネットがあります。シーンの読み込み後、どのプロセッサも消費しなかったパラメータキーは非致命的な警告として Mixer.sceneWarnings()(Python は scene_warnings())から読み出せます。シーン自体は読み込まれ、未知のキーは単に効果を持たないだけです — 「効かないつまみ」を探し回る代わりに、読み込み直後に警告を確認してタイプミスを表面化させてください。インサートが実際に読むキーの一覧は masteringInsertParamNames(name)(Python は mastering_insert_param_names(name))で列挙できます。

ストリップ

各ストリップオブジェクトは 1 つのチャンネルレーンを表します。数値フィールドには妥当な既定値があるので、最小のストリップは { "id": "vocal" } だけです。

フィールド既定意味
idstring—(必須)接続・センド・VCA メンバーが参照する一意の識別子
inputTrimDbnumber0処理前のゲイン(ストリップ信号フローの最初の段)
faderDbnumber0メインフェーダーのレベル
vcaOffsetDbnumber0フェーダー段に加算されるストリップごとの VCA トリム(setVcaOffsetDb(...) のライブ値。VCA グループgainDb とは別で、そちらはデルタとして上乗せされこのフィールドには書き込まれません)
pannumber0パン位置。-1(左)…+1(右)
widthnumber1ステレオ幅/サイド倍率(0 = モノラル、>1 = より広い)
mutedbooleanfalseストリップを無音化
soloedbooleanfalse他の(ソロセーフでない)ストリップを暗黙ミュート
soloSafebooleanfalse他ストリップのソロで暗黙ミュートされない
panModeinteger00 = バランス、1 = ステレオパン、2 = デュアルパン
dualPanLeftnumber-1デュアルパン時の左位置(既定はハード L の恒等ルーティングでステレオ像を保持)
dualPanRightnumber1デュアルパン時の右位置(既定はハード R の恒等ルーティング)
surroundPanobjectidentityステレオより広いホスト向けのサラウンドパンメタデータ。フィールドとしては azimuthdivergencelfe を扱い(elevationdistance は予約)、シーン JSON に検証・往復されますが、サラウンドパンの DSP はステージング段階で値は保存されるものの現時点では不活性です。オフラインの Mixer はこれらを適用せず、リアルタイムエンジンのサラウンドバスもサラウンド DSP パスが入って初めて値を消費します
polarityInvertLeftbooleanfalse左チャンネルの極性反転
polarityInvertRightbooleanfalse右チャンネルの極性反転
panLawinteger00 = 定 3 dB、1 = 定 4.5 dB、2 = 定 6 dB、3 = リニア 0 dB
channelDelaySamplesinteger0ストリップごとの遅延。PDC にも寄与
insertsarray[]直列のプロセッサ(インサート参照)
sendsarray[]バスへの並列センド(センド参照)

enum はファイルでは整数、API では文字列

シーンファイルpanModepanLaw を整数で保存しますが、インサートの slot とセンドの timing は短い文字列トークン "pre" / "post" で保存します。JavaScript の実行時メソッドは分かりやすい文字列を受け付けます — setPanLaw(strip, 'const3dB')addSend(..., 'postFader')。Python はセンド/メータータップでは同じ名前を受け付けますが、パンロー文字列は 'const-3db''const-4.5db''const-6db''linear-0db' のような正規化名(または enum/int 値)を使います。どちらも同じ内部値に対応し、違いはファイル形式か使いやすい API かだけです。

実行時にパンを編集したあとでシーンを書き出しても、ストリップの現在の panMode は保持されます。パン関連フィールドを手で組み直すのではなく、Mixer.toSceneJson() / Mixer.to_scene_json() を使ってください。

インサートの slot とセンドの timing必ず文字列で指定してください"timing": 1 のような文字列以外の値は、読み込み時に InvalidParameter エラー(send timing must be a string ("pre" or "post"))として拒否されます。常に "pre""post" と書いてください。

フィールド用語: デュアルパン・ポラリティ反転・パンロー・PDC
  • デュアルパンpanMode: 2) — 信号全体をまとめて動かすのではなく、左右チャンネルを独立した位置にパンします。すでにステレオの素材を狭めたり配置し直したりするのに便利です。
  • ポラリティ反転 — チャンネルを −1 倍して波形を反転します。別トラックと逆相で録れてしまった場合の補正に使います。位相関係を変えるもので、それ自体は体感ラウドネスを変えません。
  • パンロー(pan law) — パンしてもラウドネスが一定に保たれるよう、中央を左右いっぱいに対してどれだけ下げるか。定 3/4.5/6 dB は定パワー系、リニア 0 dB は合算レベルを一定に保ちます。ミキシングエンジン を参照してください。
  • PDC(プラグインディレイ補償) — ある経路がルックアヘッド処理で遅れるとき、エンジンが短い経路を合わせて遅らせ、マスターで揃えます。channelDelaySamples はこの計算に入ります。

インサート

インサートは、ストリップ(またはバス)内で直列に動く名前付きプロセッサです。

フィールド意味
slot"pre" | "post"フェーダーの前か後で動く。短いトークンに注意 — preFader/postFader ではありません。
processorstringプロセッサ id(例 eq.parametricdynamics.compressoreffects.reverb.plate)。マスタリングプロセッサ参照。
paramsstringプロセッサのパラメータを JSON 文字列(エスケープしたオブジェクト)で。例 "{\"thresholdDb\":-18,\"ratio\":2.5}"
sidechainKeystring任意。 このインサートの外部サイドチェインに供給するストリップ id(ダッキングなど)。空のときは省略されます。

サイドチェインとダッキング

通常、プロセッサは自分を通過する音声に反応します。サイドチェインを使うと、代わりに別のトラックに反応させられます。sidechainKey がその別ストリップを指定します。定番の用途はダッキングです。音楽側にかけたコンプが、指定した声のストリップが大きいときに音楽を下げ、音楽ベッドの上で話声をクリアに保ちます。

params はオブジェクトではなく文字列

シーン JSON 内では params はネストしたオブジェクトではなく、エスケープした JSON 文字列を保持します — "params": "{\"ratio\":2.5}"。これにより各プロセッサのパラメータスキーマをシーンパーサーから不透明に保てます。個別の値を読むには自分でパースしてください。

センド

センドは、ストリップ信号のコピーを行き先バスへ送ります。フェーダーの前("pre")でタップするか後("post")でタップするかは timing フィールドで選びます — チャンネルストリップの信号フローを参照してください。

フィールド意味
idstringセンド識別子
destinationBusIdstring対象バスの id
sendDbnumberセンドレベル(dB)
timing"pre" | "post"フェーダーの前か後でタップ(こちらも短いトークン)

バス

フィールド意味
idstringバス識別子(慣習上 1 つは "master"
rolestring"master""aux"、または "submix" などのグループバス
insertsarrayバス自体のプロセッサ(ストリップと同じインサート形式)

特別なロールトークンは masteraux だけ

エンジンが特別扱いするのは masteraux だけで、それ以外のロール文字列は単なるマスター以外のバスです。つまり「ドラムバス」は、ロールが submix でも subgroup でも group でも同じように動きます。トークンは挙動を切り替えるスイッチではなくラベルです。組み込みの drumBusSubgroup プリセットは subgroup を使うので、出力する(mixingScenePresetJson('drumBusSubgroup'))と "role": "submix" ではなく "role": "subgroup" が表示されます。

VCA グループ

フィールド意味
idstringグループ識別子
gainDbnumber各メンバーのフェーダーに加算するオフセット
membersstring[]グループが統括するストリップ id

接続

フィールド意味
sourcestring信号が出るストリップ/バス id
destinationstring信号が入るストリップ/バス id

接続はグラフの辺です。master へ送るストリップは { "source": "vocal", "destination": "master" } です。センドのバスは、バス(またはそのリターンストリップ)から master への接続を通じてマスターへ届きます。

組み込みプリセット

プリセット意図
vocalReverbSendボーカルストリップ(EQ + コンプのインサート)と、プレートリバーブリターンへのポストフェーダー AUX センド
drumBusSubgroupキック/スネア/オーバーヘッドをグループバス(ロール subgroup)へ送り、パラレルコンプとテープでまとめ、「drums」VCA で調整
commentaryDuckinghost/guest の話声(ディエス + コンプ)と、host をキーにした dynamics.sidechainRouter でダッキングする音楽ベッド

実行時には mixingScenePresetNames() で一覧を取得し、mixingScenePresetJson(name) で 1 つを取得します。

注釈つきの完全なシーン

これは mixingScenePresetJson('vocalReverbSend') の実際の出力です(読みやすさのため既定値は省略)。すべての関係が現れます。2 つのプリフェーダーインサートとポストフェーダーセンドを持つボーカルストリップ、リバーブリターンストリップ、2 つのバス、それらをマスターへ配線する接続です。

json
{
  "version": 1,
  "strips": [
    {
      "id": "vocal",
      "faderDb": -3,
      "inserts": [
        { "slot": "pre", "processor": "eq.parametric",
          "params": "{\"band0.type\":4,\"band0.frequencyHz\":80,\"band1.frequencyHz\":4000,\"band1.gainDb\":2}" },
        { "slot": "pre", "processor": "dynamics.compressor", "params": "{\"thresholdDb\":-18,\"ratio\":2.5}" }
      ],
      "sends": [
        { "id": "vocal-to-verb", "destinationBusId": "vocal-verb", "sendDb": -14, "timing": "post" }
      ]
    },
    {
      "id": "vocal-verb-return",
      "faderDb": -10,
      "width": 1.25,
      "inserts": [
        { "slot": "post", "processor": "effects.reverb.plate", "params": "{\"decaySec\":1.8,\"preDelayMs\":25}" }
      ]
    }
  ],
  "buses": [
    { "id": "master",     "role": "master" },
    { "id": "vocal-verb", "role": "aux" }
  ],
  "vcaGroups": [],
  "connections": [
    { "source": "vocal",             "destination": "master" },
    { "source": "vocal-verb",        "destination": "vocal-verb-return" },
    { "source": "vocal-verb-return", "destination": "master" }
  ]
}

リバーブの経路をたどると、vocal ストリップのポストフェーダーセンドが vocal-verb AUX バスへ供給し、そのバスは(プレートリバーブを置いた)vocal-verb-return ストリップへ接続し、リターンが master へつながります。ドライのボーカルも直接 master へつながります。リバーブは 1 インスタンス、ドライとウェットは分離されたままです。

eq.parametric インサートはバンドインデックス指定のキーを使う

eq.parametric インサートが読むのはバンドインデックス指定のキーです — band{N}.typeband{N}.frequencyHzband{N}.gainDbband{N}.q、およびバンドごとのダイナミック EQ フィールド。このプリセットでは band0 が 80 Hz のハイパス("band0.type": 4 は EQ バンドタイプ enum の HighPass)、band1 が 4 kHz の +2 dB プレゼンスベルで、実際に機能するハイパス+プレゼンスブーストになっています。

キーの全一覧は masteringInsertParamNames('eq.parametric') で取得できます。一覧外のキー(たとえばフラットな highPassHz)も読み込みは通りますが効果を持たず、シーン読み込み後に Mixer.sceneWarnings() が報告します。

つまみ 1 つのトーン調整には、より単純なインサートも使えます。明暗を広く傾けるなら eq.tilt(tiltDbpivotHz)、高域シェルフの「エア」を持ち上げるなら spectral.airBand(amountshelfFrequencyHz)です。

編集して保存し直す

typescript
const json = mixingScenePresetJson('vocalReverbSend');
const mixer = Mixer.fromSceneJson(json, 48000, 512);

mixer.sceneWarnings();  // [] — タイプミスした insert パラメータがあれば非致命的にここへ並ぶ

mixer.addSend(0, 'more-verb', 'vocal-verb', -18, 'postFader');  // トポロジー変更
mixer.compile();                                                 // タイミングが重要な処理の前に再構築

const saved = mixer.toSceneJson();   // 同じスキーマへラウンドトリップ
python
import libsonare as sonare

scene_json = sonare.mixing_scene_preset_json('vocalReverbSend')
mixer = sonare.Mixer.from_scene_json(scene_json, sample_rate=48000, block_size=512)

mixer.scene_warnings()  # [] — タイプミスした insert パラメータがあれば非致命的にここへ並ぶ

mixer.add_send(0, 'more-verb', 'vocal-verb', -18, 'post_fader')  # トポロジー変更
mixer.compile()                                                  # タイミングが重要な処理の前に再構築

saved = mixer.to_scene_json()   # 同じスキーマへラウンドトリップ
mixer.close()                   # ネイティブハンドルを解放
bash
# 組み込みシーンを書き出し、JSON を編集してからレンダーする。
sonare mixing-preset --preset vocalReverbSend > my-scene.json
sonare mix --scene my-scene.json --input vocal.wav --input reverb-return.wav -o master.wav

mix --scene でのストリップごとの入力指定は Python CLI 限定

JSON ファイルからシーン全体をレンダーし、ストリップごとに --input を 1 つずつ渡す機能は Python CLI が実装しています。C++ CLI の mix コマンドは単一ストリップ・単一入力のプロセッサ(--scene 非対応)です。フルシーンのレンダーではなく、ストリップ単位の手早い確認に使ってください。

いつ再コンパイルするか

構造的な編集 — バス・センド・接続の追加/削除 — はグラフを dirty にし、次のタイミングが重要なブロックの前に compile() が必要です。パラメータ操作(setSendDb / Python set_send_dbsetPanLaw)、VCA グループの変更(追加・削除・ゲイン調整。メンバーストリップへのコントロール専用ゲインオフセットとして即時反映されます)、スケジュール済みオートメーションには再コンパイルは不要です。

ブラウザデモのプロジェクト JSON

/ja/mixing デモは、ブラウザセッション用に別の小さなファイルを書き出します。これはミキサーシーンではなく UI プロジェクトで、デコード済み音声ではなくトラックごとのアレンジ設定を保存します。

以下の例は省略版で、代表的なキーの一部だけを示しています。実際の書き出しには、トップレベルの追加フィールド(reverbvcaGains など)やトラックごとの追加設定も含まれます。

json
{
  "version": 1,
  "masterFaderDb": 0,
  "tracks": [
    {
      "id": "track-id",
      "name": "Lead Vocal",
      "offsetSeconds": 1.5,
      "inputTrimDb": 0,
      "faderDb": -3,
      "pan": 0,
      "width": 1,
      "muted": false,
      "soloed": false,
      "polarityLeft": false,
      "polarityRight": false
    }
  ]
}

offsetSeconds はアレンジタイムライン上のクリップ開始時刻です。デモは WASM ミキサーを呼ぶ前に各ステムをその分だけパディングするため、画面上の開始時刻がオフラインバウンスにも保たれます。ファイルは音声を含まないので、再インポート時は音声を再読み込みしたあとに id(または name)でトラックを照合します。

関連