hyperframes-audio について
HyperFrames Audioは、HyperFramesプロジェクトのトラックをミキシング、処理するスキルです。音声、音楽、エフェクトの調整に向け、プレビューとレンダーで同じオーディオグラフを使い、属性で自動化とエフェクトチェーンを定義します。
主な機能
- 01フェードとクロスフェードの設定
- 02音量とエフェクトパラメーターの自動化
- 03ナレーション用の周波数帯域の確保
- 04EQ、コンプレッサー、リバーブなどの適用
- 05プリセットと診断手順の活用
活用シーン
- 01BGM上でナレーションを聞き取りやすくする
- 02音声レベルを調整し、部屋鳴りを抑える
- 03トラックにEQ、ディレイ、リバーブを加える
- 04音声ファイルの問題を診断する
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ heygen-com/ hyperframes --skill hyperframes-audioインストール後、Claude Code で/hyperframes-audioを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/attributes.mddiagnosis.mdfx-registry.mdpresets.mdscripts/carve.mjscarve.test.mjsscripts/lib/main-module.mjs詳細
プラグインのインストール: このスキルが HyperFrames プラグイン内にある場合、セットアップや最新状態の確認コマンドを実行する前に、プラグインの実行ルールに従ってください。スタンドアロンでインストールしている場合は、以下の更新手順をそのまま使用してください。
HyperFrames Audio
ミックスとは、プロセッサーを積み重ねることではなく、関係性の集合です。それぞれ単独では問題なく聞こえる2つのトラックでも、合わせると聞きづらくなることがあり、その解決策はほとんどの場合「片方の音量を下げる」ことではありません。どの帯域を奪い合っているのかを見つけ、必要としているほうにその帯域を与えることです。ここにあるツールはすべて、そうした関係性を表現するためにあります。
エフェクトは要素の data-fx-chain に設定されます。プレビューとレンダーは同じ Web Audio グラフを実行します。スタジオはライブコンテキストで、エンジンはブラウザー内のオフラインコンテキストで動作します。各エフェクトの実装は1つだけなので、スクラブ中に聞こえる音がそのまま書き出されます。2回調整する必要はありません。
クリップのタイミングは引き続き /hyperframes-core が担当します。オーディオ/ビデオのトリムとソース範囲には data-start、data-duration、data-media-start を使用し、クロスフェードでは異なるトラック上のクリップを重ねます。このスキルが担当するのは、配置済みトラックのフェードイン/フェードアウト、クロスフェードのエンベロープ、トラックゲイン/トラック音量、音量とエフェクトのオートメーション、ダッキング/ナレーション用の帯域調整、エフェクトチェーンです。素材の調達、生成、前処理は /media-use が担当します。
一定の data-playback-rate(0.1..10)は、対応するオーディオ/ビデオ要素のタイミング、ソースオフセット、再生レートが同じであれば、映像とピッチを保持した音声のレンダーに安全に使用できます。速度ランプは data-automation の rate レーンです(docs/reference/speed-ramps を参照)。一定のレートより優先され、プレビューとレンダーの両方でピッチを保持します。HyperFrames は波形の自動同期やズレの補正には対応していません。
コピーして使えるカット/クロスフェード/再生速度変更のレシピは、/hyperframes-core → references/creator-editing-recipes.md を参照してください。
3つの属性ですべてを設定します。オーディオ/ビデオ要素自体、または最初の2つについては <hf-audio-group> バスにも設定できます(「複数のトラックに1つのバスを使う」を参照)。
| 属性 | 内容 |
|---|---|
data-fx-chain | 信号の順序に並べたエフェクト |
data-automation | このトラックの音量またはエフェクトパラメーターのエンベロープ |
data-fx-carve | カーブの設定。再計算に使用します |
標準搭載のエフェクトファミリーは、ゲイン、EQ(ハイパス、ローパス、ピーキング、シェルフ)、コンプレッサー、リミッター、truepeak(先読み式トゥルーピークリミッター)、ゲート、サチュレーション、ディレイ、リバーブ、コーラス、フェイザー、ビットクラッシュです。
各エフェクトの正確な JSON と、レーンが満たすべきルール:references/attributes.md。
各エフェクトのパラメーター、範囲、単位:references/fx-registry.md。
音を聞けないファイルの問題を特定する方法:
references/diagnosis.md。
プリセット、名前付きジョブ、1つのつまみで使えるプロファイル、症状と解決策の対応表:
references/presets.md — チェーンを手作業で組む前に、まずこちらを読んでください。問題に合ったプリセットや名前付きジョブがすでに用意されていることがよくあります。
仕組み
2つのオーサリング画面がこれらの属性を書き込み、2つのランタイムが共通のビルダーを通じて読み取ります。この共通部分があるため、プレビューからレンダー結果を予測できます。
flowchart TB
voice["voice track<br/>media file"]
bed["music bed<br/>media file"]
subgraph AUTHOR["Authoring — the only things that write attributes"]
panel["Studio<br/>Voiceover carve control"]
script["scripts/carve.mjs<br/>detects the pair"]
analysis["core/audioCarve.ts<br/>carveProfile · analyseCarveBands<br/>analyseCarveDuck · analyseCarveDynamics"]
panel --> analysis
script --> analysis
end
voice --> analysis
bed --> analysis
subgraph ATTRS["Written onto the bed element"]
carveAttr["data-fx-carve<br/>sources · strength"]
chainAttr["data-fx-chain<br/>peaking xN + gain, tagged fromCarve"]
autoAttr["data-automation<br/>a lane per carved parameter"]
end
analysis --> carveAttr
analysis --> chainAttr
analysis --> autoAttr
subgraph SHARED["One implementation, read by both"]
build["audioFxGraph.ts · buildFxChain"]
sched["audioFxAutomation.ts · scheduleChainAutomation"]
end
chainAttr --> build
autoAttr --> sched
build --> preview["Preview<br/>live AudioContext<br/>attachElementFxChain"]
sched --> preview
build --> render["Render<br/>OfflineAudioContext in the headless browser<br/>applyAudioFxChain"]
sched --> render
preview --> heard["what you hear while scrubbing"]
render --> wav["processed WAV<br/>+ chainTailSeconds so the mix lets the tail through"]
wav --> mix["engine · audioMixer<br/>volume lane baked into the PCM here, not in the graph"]
mix --> out["the rendered mix"]
edit["editing the attribute mid-playback"] -.->|MutationObserver| preview
再生時にカーブ自体の設定が読み込まれることはありません。再生されるのは、カーブによって生成されたチェーンとレーンです。data-fx-carve は、フィルターから強さを推測し直すのではなく、既存のカーブの強さを変更できるようにするためのものです。
カーブを適用したベッドの信号は、まずディップを通り、次にレベルマッチを通り、その後で自分で組み立てたエフェクトを通ります。そのため、追加したリミッターは最後の音量上限として機能します。
flowchart LR
src["decoded bed"] --> p1["peaking<br/>400 Hz"]
p1 --> p2["peaking<br/>1 kHz"]
p2 --> p3["peaking<br/>1.6 kHz"]
p3 --> g["gain<br/>level match"]
g --> hand["your own effects<br/>e.g. limiter"]
hand --> dest["track gain, then out"]
l1["lane fx.n1.gain"] -.->|"envelope of the voice's<br/>level in that band"| p1
l4["lane fx.n4.gain"] -.->|"how far the bed<br/>ducks overall"| g
まず、何が問題なのかを見極めます
以下の表は、「低音がこもって聞こえる」という訴えから始まっています。これは、すでに誰かが音を聴いてそう言ったことを前提としています。ファイルを渡されて「これを直して」と言われても、そのような訴えはなく、音を聴くこともできないため、測定する必要があります。すべてに共通するルールは一つです。
未知の音声を一つだけ聴いて、その絶対スペクトルを診断することはできません。 フォルマントは±10 dB、基本周波数は85〜255 Hz、文末にかけて音量は5〜6 dB下がります。これらはどれも、単独で見れば欠陥のように見えますが、どれも話者の特性です。
比較してください。そして、同じファイル内にあるものと比較します。クリーンなオリジナルがあればそれと、なければ無音部分と比較します。ギャップで聞こえる音はすべて付加されたものであり、そのスペクトルは声ではなくチャンネルの特性です。公開されている平均スペクトルや合成された基準音声との比較は役に立ちません。話者間の違いはほとんどの欠陥より大きく、このガイダンスの根拠となった評価での誤答も、まさにその比較から生じました。
オリジナルがなく、使える無音部分もない場合、静的な音色の欠陥は本質的に特定できません。一つに決めつけてそれをもとに判断を重ねるのではなく、その旨を伝え、当てはまる可能性のある解釈を提示してください。
コマンド、落とし穴、実例付きレシピ:references/diagnosis.md。説明のないファイルを診断する前に読んでください。
症状から始める
帯域と種類がわかったら、音声の問題を特定します。音声の問題の多くは、以下のいずれか一つか二つに当てはまり、それぞれに用意済みの解決策があります。
| 聞こえ方 | 試すもの |
|---|---|
| 低いハム音や衝撃音が下に響く | rumble-cut、または80 Hzのhighpass |
| 低音がこもる、胸に響く | 低音のこもりを抑えるジョブ(200 Hz) |
| こもっていて、段ボール越しに聞こえる | 濁りを抑えるジョブ(250 Hz) |
| 言葉が聞き取りにくい | 明瞭さを加えるジョブ(3 kHz)、またはベッドを削る |
| 耳障りで疲れる | 耳障りさを和らげるジョブ(3.2 kHz) |
| 言葉によって音量に大きな差がある | コンプレッサーの均一化、または音量の均一化 |
| 文と文の間に部屋鳴りがある | room-gate |
| 声と音楽がぶつかり合う | ナレーション用の帯域調整 — どちらにもEQをかけない |
| 音が乾いていて、どこで録音したのか分からない | room-tightまたはroom-natural |
| ただ「素人っぽい」 | 上記のうち四つを順に適用するvoice-clean |
プリセットの全一覧、各プリセットの内容、帯域に関する用語、そして意図的に対象外としているもの(ディエッシング、ノイズ除去、音色の一致)については、references/presets.mdを参照してください。
足す前に引き、フィルターをかけてからレベルを整え、レベルを整えてから相互の関係を調整し、最後に音色と上限を設定します。各ステップで次のステップが捉える音が変わります。ハイパスより先にコンプレッサーを設定すると、低域の響きを追いかけることに時間を費やします。
名前ではなく、問題に応じてエフェクトの種類を選ぶ
フィルター(highpass、lowpass、peaking、lowshelf、highshelf)は、トラックがどの周波数帯域を占めるかを決めます。2つの音源がぶつかっているとき、まず使うべきツールです。ぶつかり合いは帯域で起こるためです。たとえば、ベッドと声がどちらも1–3 kHzを必要としている場合、ベッドからその帯域を削るほうが、全体の音量を下げるよりミックスへの影響をはるかに抑えられます。声にハイパスフィルターをかけるのは、ランブルノイズに対する定番の対処法です。ローパスフィルターは、意図的に音を暗くしたり、こもらせたりします。
ダイナミクス(gain、compressor、limiter、truepeak、gate)は、トラックの音量が時間とともにどう変化するかを決めます。コンプレッションは大きな音と小さな音の差を狭め、小さな音を持ち上げられるようにします。リミッターはピークを設定した上限に向けて下げるもので、それ以外の音は整えません。limiterは音量に追従し、先読みをしないため、高速なピークやサンプル間ピークが上限を超えることがあります。納品時の上限には、先読みを行い、サンプル間ピークを測定するtruepeakを使ってください。波形そのものではなく、4xの推定値を上限に保つため、全帯域ノイズは上限を1.7 dB超えることがあります。厳格な納品上限がある場合は、上限を少なくとも2 dB下に設定してください。ゲートはしきい値を下回る音を取り除きます。これにより、フレーズの合間の部屋鳴りを消せます。gainは通常の音量調整段であり、トラックをほかの音の邪魔にならないよう動かす必要があるときに、オートメーションレーンで調整するものです。
非線形エフェクト(saturate、bitcrush)は波形の形を変え、元の音にはなかった倍音を加えます。補正ではなく、トラックに個性や粗さを加えたいときに使ってください。また、これは音を生み出す処理です。薄い音源をより密度のある音にしますが、よりクリーンにはしません。
時間系エフェクト(delay、reverb、chorus、phaser)は、トラックに空間を与えたり、広がりを加えたりします。余韻やピッチをずらした音が、声に必要な空間を占めてしまうことがあるため、ミックスを最も損ないやすいエフェクトです。ほかの音の_後ろ_に置きたい音に使い、単独で聴いてちょうどよいと感じるよりも、ウェット量を低く保ってください。
エフェクトチェーンは直列です。それぞれのエフェクトは、ひとつ前のエフェクトが出力した音を処理します。そのため、補正用のフィルタリングは前段に、個性を加える処理は中段に、そして上限として実際に機能できるよう、最後にリミッターを配置します。
ボイスオーバーのカーブ
解決する問題。 声の下に音楽を流すと、声が聞き取りにくくなります。反射的に音楽全体の音量を下げると、問題は解決しますが、音楽の存在感がすっかり失われ、ボイスオーバーのあいだずっと音楽が力なく聞こえてしまいます。しかし、声に必要なのはスペクトル全体ではありません。実際に声が占めているわずかな帯域だけで十分です。カーブはその帯域だけを取り除くため、音楽の低域と高域は保たれ、声が聞き取れる状態でも音楽らしさが残ります。
これはエフェクトではなく、関係性です。 設定は処理対象のトラックである ベッド にあり、サイドチェーンコンプレッサーと同じように、どの声を聴くかを指定します。つまり、音量を下げるトラックを選び、何をきっかけに音量を下げるかを指定します。声のトラックにカーブを設定しないでください。 声を自分自身に対してカーブするのは、繊細なミックス上の判断ではなくバグです。
声は一つではなく、すべてが対象です。 sources はリストです。ベッドは通常、ナレーター、インタビューの回答、別のプレゼンターなど、一連の音声の下で流れるためです。測定を始める前に、声はすべてベッド自身のタイムラインに合わせてミックスされます(mixCarveSources)。そのため、一度の分析ですべてをカバーできます。帯域はそこにあるすべての音声から決まり、エンベロープはどれかの声が流れている箇所で立ち上がります。ベッドと同時に再生されない声は、ベッドをマスキングできないため対象外です。
複数のクリップ ID に対してカーブするのは誤りです。クリップをグループ化し、そのグループに対してカーブしてください。 これはヒントではなく、不変条件です。クリップを一つずつ指定する方法は、すべてを漏れなく指定する必要があり、次の編集までしか正しさが保たれません。後から4つ目のナレーションクリップを追加すると、そのクリップはカーブの対象外で再生され、ベッドがその下で音量を下げないままになります。代わりにグループを指定すれば、分析時にメンバーが解決されるため、後からグループに追加されたクリップも sources に触れずに対象になります。
<audio id="vo-intro" data-audio-group="voiceover" …></audio>
<audio id="vo-middle" data-audio-group="voiceover" …></audio>
<audio id="vo-outro" data-audio-group="voiceover" …></audio>
<audio id="music" data-fx-carve='{"enabled":true,"sources":["voiceover"],"strength":0.8}' …></audio>
グループではなく、プレーンなクリップ ID を二つ以上指定した sources リストは、audio_carve_ungrouped_sources リントルールで検出されます。そのままでも機能しますが、クリップを追加すると気づかないうちに劣化する方法です。
カーブのグループは声だけのグループにしてください。ベッド、SFX、音楽は含めないでください。 sources 内のグループ ID は、分析のたびに 現在の すべてのメンバーへ解決されるため、後から適用されるのは指定したグループであり、設定を書いたときに測定されたトラックではありません。問題になるパターンは二つあります。
- ソースグループにベッドを含める。 ベッド自体が声として渡され、自身の内容に対してカーブされます。つまり、「トラックを自身に対してカーブしない」というルールに、次の再分析で違反します。
- 声のグループにSFXや音楽のクリップを含める。 次の分析でサイドチェーンに追加され、属性を書き込んだ実行では測定されていなかったにもかかわらず、ベッドが効果音のヒューッという音の下で音量を下げ始めます。
どちらも、カーブを書き込む時点では見えません。分析では検出した声をミックスしますが、グループのメンバー解決は再実行されません。そのため、最初のパスは本当に正しく、次のパスで初めて誤りになります。役割ごとにグループを分けてください。ベッドには music、ナレーションには voiceover、効果音には sfx を使い、sources に指定したグループには声だけを入れてください。
carve.mjs は、どちらかのケースを検出するとグループ形式の書き込みを拒否し、クリップ ID を記録して、どのメンバーが妨げになったかを標準エラー出力に表示します。続いて audio_carve_ungrouped_sources ルールが配置を指摘するため、CLI が測定範囲より広いカーブを気づかれないまま保存することはありません。
この実行で対象外になった声は、上記のケースには該当せず、グループ形式を妨げません。carve.mjs が分析するのはベッドと重なる声だけです。sources を編集せずに、後から再生されるクリップも対象にできることが、グループを指定する目的だからです。
複数のトラックに一つのバスを使う
上記のとおり、カーブの対象にするにはグループのメンバーであるだけで十分です。ただし、その ID を持つ <hf-audio-group> 要素を追加すると、そのグループは実際のサブミックスバスになり、すべてのメンバーが一つのチェーン、一つのフェーダー、一つのオートメーションタイムラインを共有します。
<hf-audio-group
id="voiceover"
data-label="Voiceover"
data-volume="0.9"
data-fx-chain='{"version":1,"nodes":[
{"type":"compressor","id":"g1","params":{"threshold":-18,"ratio":3}},
{"type":"peaking","id":"g2","params":{"frequency":3000,"gain":2,"q":1}}]}'
></hf-audio-group>
<audio id="vo-intro" data-audio-group="voiceover" …></audio>
<audio id="vo-middle" data-audio-group="voiceover" …></audio>
同じ処理を複数のトラックに適用するなら、バスを使います。 同じコンプレッサーが必要なナレーションのクリップが4つある場合、4つのチェーンを同期させ続ける必要があり、どれかを編集した瞬間にずれが生じます。バスならチェーンは1つだけで、コンプレッサーは各クリップを個別にではなく、声全体を聴きます。シーケンスの3分の1しか聴こえていないコンプレッサーには、そのシーケンスを制御できないため、これが重要です。クリップごとのチェーンは、ノイズの多いテイクに専用のディエッサーが必要な場合など、本当にクリップごとの処理が必要なときに適しています。
| バス上の項目 | 役割 |
|---|---|
data-fx-chain | 合算したメンバー全体にかける1つのチェーン |
data-automation | バス上のエンベロープ。時間はコンポジション基準 |
data-volume | すべてのメンバーに適用する1つのフェーダー(デフォルトは1) |
data-label | 表示名。設定がなければIDを使用します |
data-hidden | すべてのメンバーをミックスから除外します |
グループのオートメーションはクリップ時間ではなく、コンポジション時間が基準です。 バスにはdata-startがありません。メンバーはバスに到達する時点ですでにコンポジション内の位置にあるため、グループレーンのt: 0はクリップの開始ではなく、コンポジションの開始を指します。クリップ上のレーンはクリップ内の時間が基準です。同じ数値でも両者では異なる時点を意味するため、エンベロープをクリップからそのバスへ移す際には、この点を正しく扱う必要があります。
カーブ処理はクリップに設定します。 data-fx-carveはグループ属性ではありません。カーブ処理されるベッドは1つのトラックであり、data-fx-carveを持つのはそのトラックです。前述のルールに従って、グループを指定します。グループとカーブ処理を結び付ける場所はsourcesであり、同じ要素上ではありません。バスにカーブ処理を設定するのは、効果の半分を二重に適用することになります。レベル部分はベッド自体のオーディオを測定しますが、バスにはベッド自体のオーディオがないため、フィルターだけが残ります。さらに、バスとそのメンバーは1つの信号経路なので、ベッドにはバスのフィルターと自身のフィルターの両方が適用されます。audio_group_carve_attr lint ルールでこれを検出できます。
ミックス全体に1つのエフェクトをかける場合は、マスターバスを使います。 クリップが指定できるグループは1つだけなので、全体にかけるリミッターやEQをグループにすることはできません。トップレベルのコンポジションルートにあるdata-fx-chainに設定します。各グループのチェーンとフェーダーの後に、すべてのクリップとグループの合計に対して1回だけ処理されます。一般的な用途は納品時の上限設定です。マスターチェーンの最後にtruepeakを置きます。マスターバスとして読み込まれるのはトップレベルのルートだけです。サブコンポジションルートのdata-fx-chainは、親コンポジション内では適用されません。マスターオートメーションはありません。
1つのクリップはバスではありません。 グループは、複数のトラックに1つのチェーン、1つのフェーダー、1つのクロックを与えるためのものです。1つのクリップをバスで囲んでも、そのクリップ自身のdata-fx-chainですでにできることと変わらず、後で編集する際に変更箇所が2か所に増えるだけです。それでも使う理由が1つだけあります。バスのオートメーションはコンポジション時間を基準にするため、クリップ上のレーンをコンポジション時間で動作させるには、そのクリップだけを含むバスを使います。
ノブは1つです。 strengthは0~1で、カットの深さ、バンド数、幅、声の生のエネルギーより明瞭さをどれだけ優先するか、レベルをどこまで下げられるか、声よりどの程度下を狙うかをすべて決めます。実際のミックスでは、この6つは連動します。穏やかなカーブ処理では少ないバンドを浅くカットしてダッキングも控えめにし、強い処理ではより多くのバンドを深くカットします。そのため、これらはcarveProfileに一度だけ記述する1つの関係性です。carve.mjsのデフォルトは0.8です。250 Hzから2.5 kHzまでの6つのバンドをそれぞれ約7 dB、1.6 kHzでは15 dBカットし、19 dBのレベル調整幅を設けます。ナレーションの下に敷くベッドは、まず声の邪魔にならないようにし、その次に音楽として機能する必要があるためです。0.25(3つのバンドで6 dBカットし、レベル調整幅は6 dB)ではベッドの存在感は保てましたが、それでも声と競合し、実用上は弱すぎると判断されました。0.5ではカットが10 dBに達し、カーブ処理が声のための余地ではなく、エフェクトとして聞こえ始める強さになります。ベッドが主役で声がまばらな場合は、strengthを下げてください。0はスペクトルのみの処理です。バンドは1つだけで、レベルマッチングは行いません。
デフォルトでカーブを適用 — 音楽が声の下で流れる場合は必須です。 ナレーション、アバターの発話、インタビュー、ボイスオーバーなど、声のトラックの下に敷く音楽には、時間があれば行う仕上げではなく、ミックスの仕上げの一部としてカーブを適用します。両方のトラックを配置し、以下のコマンドを実行して(デフォルトの強度は 0.8 です。検出結果が間違っている場合は --bed / --voice を追加してください)、書き込まれた
data-fx-carve、data-fx-chain、data-automation を npx hyperframes check で確認してから、レンダリングします。音量を下げるだけではミックスは完成しません。声と音楽が 1~3 kHz 帯域でぶつかり続け、ボイスオーバー全体を通して音楽の存在感が失われます。音楽の下に声を敷かない場合に限り、カーブを省略してください。たとえば、ミュージックビデオ、タイトルカード、曲に合わせてカットしたモンタージュなどです。
常に声に追従します。 固定モードはありません。固定の深さでは、無音の間も音楽が薄くなります。両方を聴けば、その状態を望む理由はありません。すべての値は、話し声自体の音量に応じたエンベロープになります。無音なら音楽には手を加えず、声が大きくなるとカーブが最大の深さになります。通常のオートメーションとして書き込まれるため、レーンがタイムラインに表示され、後から編集できます。
レベル合わせもその一部です。 スペクトルカーブでは、音楽の音量が単に声より大きい場合は解決できません。そのため、カーブは音楽が声よりどれだけ大きいかも測定し、エンベロープで制御する gain ステージを書き込みます。このエンベロープは意図的にゆっくり戻ります。単語が終わった瞬間に音楽が全音量へ戻ると、機械が操作しているように聞こえるためです。
実行方法。 Studio では、カーブはトラックのエフェクトラックの先頭にある 1 つのモジュールです。声、強度、生成された分析結果が 1 枚のカードにまとまっています。別のトラックが声になり得る場合は常に表示され、上に候補が1 つだけある音楽には、デフォルトの強度でカーブが適用されます。ナレーションの下に敷く音楽にはこれが適切で、変更やオフへの切り替えはこのモジュールから行えます。候補が複数ある場合は、推測せずに選択を待ちます。ヘッドレスの場合 — コンポジションを編集するのではなく作成する場合はこちらを使います。
node <SKILL_DIR>/scripts/carve.mjs --comp index.html
コマンドはこれだけです。声と音楽を自動で検出し、デフォルトの強度でカーブを適用して、判定内容を出力します。
bed music-bed (name looks like music)
voice narration (only track left)
carve strength 0.8, 1 voice
bands 250Hz -7.4dB q2.06, 400Hz -7.4dB q2.06, 630Hz -7.4dB q2.06, 1000Hz -7.4dB q2.06, 1600Hz -14.8dB q2.06, 2500Hz -7.4dB q2.06
level 273-point envelope, floor -19.2 dB
自動判定が間違っている場合は --bed / --voice でトラックを指定します(繰り返し指定できます)。--strength で強度を上げ、--dry-run でレポートのみを表示し、何も書き込まないようにします。
トラックの選び方。 まず名前を使います。すでに指定されている情報であり、判定理由を説明できるためです。core の classifyAudioName は Studio のピッカーと同じ分類器なので、両者の判定が食い違うことはありません。ID またはファイル名が音楽らしい(music、bgm、bed、score など)トラックは音楽と判定されます。それ以外で、その上に再生され、SFX らしくないトラックは声と判定されます。オーディオ要素を優先します。声として使えるオーディオトラックが残っていない場合、またはコンポジション内の B ロールクリップがすべて誰かの発話として扱われてしまう場合にのみ、動画を対象にします。どのトラックが音楽か判断できない場合は、間違ったトラックにカーブを適用せず、処理を拒否します。ID を 1 つ入力するのは簡単です。
パネルと同じ分析関数を使うため、結果も同一です。PATH 上に ffmpeg があり、プロジェクトに @hyperframes/core がインストールされている必要があります(npm i -D @hyperframes/core)。CLI は core を同梱せずにインライン化するため、そこから借りてくることはできません。
書き込まれる内容は、ピーキングフィルターとゲインステージからなる通常のチェーンで、fromCarve のタグが付けられます。このタグが重要です。再実行すると前回のカーブが置き換えられ、手動で作成したエフェクトや描画したレーンはすべて、元の位置のまま保持されます。そのため、新しい強度でカーブを再適用しても安全に繰り返せます。また、data-fx-carve があることで、フィルターから推測するのではなく、設定を読み戻せます。
オートメーション
レーンとは、1つのパラメーターに対するブレークポイントの集合です。{t, v} はクリップ内の秒数と、そのパラメーター固有の単位で表します。ターゲットには、トラックのレベルを指定する volume、またはエフェクトのノブを指定する fx.<nodeId>.<param> を使います。
オートメーションを設定できるのは一部のパラメーターだけで、それ以外に設定したレーンは何もせずに無視されます。 ノブの制御に Web Audio の AudioParam が使われている場合、そのノブはオートメーションに対応しています。ワークレットベースのエフェクトである compressor、limiter、truepeak、gate、bitcrush は AudioParam を一切公開しないため、これらのパラメーターに設定したレーンは動作しません。コンプレッサーの動作を時間とともに変化させたい場合は、代わりにその前段の gain ステージをオートメーション化してください。各パラメーターの対応状況は references/fx-registry.md に記載されています。
検証
ミックスを対象とする静的チェックはほとんどありません。リンターが data-automation を読み取って検出する競合は、次の2つだけです。audio_volume_double_automation は、volume に GSAP トゥイーンも設定されているトラックに音量レーンがある状態です。この場合、レーンが優先され、トゥイーンは無視されます。audio_volume_tween_overrides_gain は、volume がトゥイーンされているトラックに data-volume が設定されている状態です。この場合、トゥイーンの値は絶対値として扱われ、ゲインに倍率を適用するのではなく、その値で置き換えます。チェーンやエフェクトレーンは、ほかには何も検証されません。これらを保証するのはレンダリングです。解析できないチェーンがあると、ミックス全体のレンダリングが失敗します。ドライ信号を黙って書き出すことはありません。もっともらしく聞こえても実際は誤っているミックスを作るより、処理を拒否するほうがよいためです。一方、プレビューは意図的に逆の動作をします。チェーンを読み取れない場合はドライ再生するため、制作を続けられます。
チェーンに存在しないノードを参照するレーンは、エラーにならず読み込み時に削除されるため、nodeId の入力ミスはエンベロープが黙って失われる原因になります。生成された ID を推測せず、チェーンから読み取ってください。
reverb や delay のように余韻があるエフェクトは、レンダリング後のトラックを元の音源より長くします。チェーンはその長さをミックスに伝えます。そのため、リバーブをかけたベッドが data-duration とまったく同じ時点で終わらなくても、想定どおりであり、バグではありません。
それ以外のミックスは、レンダリングして聴いて確認します。音のすき間を作る場合、ベッドがくぼんだように聞こえることなく声が聞き取れ、フレーズの間にはベッドの音量が戻り、一定のままにならないことが重要です。声の下でベッドの音が単に小さくなるのではなく、ノッチがついたように聞こえる場合は、強さが過剰です。これは、音で明らかにわかる唯一の失敗パターンです。