-
Notifications
You must be signed in to change notification settings - Fork 0
Reference ALS Scripts
.als(Live セット)を Live を介さずに読み書きするスクリプト群です。すべて node scripts/<名前>.js で実行します。
設計方針(DOM に載せない、実物から起こしたテンプレート、Backup 退避)は 構成と設計方針 を参照。
-
Live で開いているセットは書きません。 Live の
Log.txtから今開いているセットを判定します(scripts/notify.jsのisOpenInLive)。書いても画面に反映されず、Live 側の保存で消えるためです。承知のうえで進めるときだけ--force -
置き換えは Backup 退避してから。 Live 純正の
Backup/<名前> [YYYY-MM-DD HHMMSS].alsと同じ命名で退避します。削除は一切しません - 結果は Live のステータスバーへ通知します(Remote Script 導入時。無ければ標準出力のみ)
- サンプル参照は Loopcloud 直参照(コピーを作りません)
モジュールとして他のスクリプトから使います。
| 関数 | 内容 |
|---|---|
readAls(file) / writeAls(file, xml)
|
gunzip / gzip。展開後の XML が変わらないことだけを保証(gzip のバイト列は Live と一致しなくてよい) |
writeAlsWithBackup(file, xml) |
Backup/ へ退避してから置き換え。退避先のパスを返す |
backupPath(file) |
Live 純正の命名で退避先を作る |
listTracks(xml) |
<Tracks> 直下のトラックを位置つきで列挙 |
resolveTrackTargets(tracks, targets) |
名前の前方一致 / Id で対象を決める |
groupTracks(xml, { name, trackIds }) |
連続したトラックを Group トラックに包む |
verifyRoundTrip(file) |
展開 → 圧縮 → 展開 で XML が変わらないか |
node scripts/als-group.js <入力.als> <出力.als> <グループ名> <対象> ... [--force]
node scripts/als-group.js "Hard Drops.als" out.als "ONE SHOTS" "OS " # 名前の前方一致
node scripts/als-group.js in.als out.als DRUMS 23 24 25 # トラック IdLive の Song API には group_tracks が無いため、ファイル側で行います。MCP ツール live.set.group_tracks はこれを呼んでいます。
プロジェクトフォルダを移動すると、FileRef の RelativePath(.als のあるフォルダからの相対)が旧位置を指して切れます。Live は相対パスを先に見るので、実在のファイルへ向け直せば復旧します。
node scripts/als-repair.js <プロジェクトフォルダ | .als> [--dry-run] [--library <dir>] [--allow-size-mismatch]- 既定のライブラリは
~/Library/Loopcloud/library。ファイル名で索引を引き、索引に無いものはプロジェクト自身のSamples/Imported/Recorded/Processedを探す - 同名が複数あれば
OriginalFileSizeで選ぶ。決められなければ「曖昧」として書かない - サイズ不一致は既定では書かない。
--allow-size-mismatchで受け入れる(Loopcloud の再ダウンロードでメタデータチャンクだけ変わった場合。数 MB 違うものは音の長さが違う可能性があるので一覧を確認する) - 書き換えるのは
RelativePathとPathの値だけ。&を含むパスは XML エスケープする - 見つからない参照(ユーザー自身の録音など)はレポートに残し、触らない
実績: Ambient TRACK Project の 10 セット・3,755 件を向け直し(Issue #19)。
node scripts/als-diff.js <前.als> <後.als> [表示する塊の数]2 つのセットを XML レベルで比較します。生成結果を Live が保存した結果と突き合わせる検証に使います(タグ出現数の差で「クリップが全部消えているのに 108 と報告していた」バグを捕まえた実績があります)。
node scripts/als-generate.js <パックのフォルダ> <出力.als> [--loops <sub>,...] [--oneshots <sub>,...] [--name <セット名>] [--layout folders|songs] [--no-groups]配置(folders レイアウト、既定):
- ループ → フォルダごとにオーディオトラック。クリップはテンポ → キー → 名前の順に縦に並ぶ
- ワンショット → フォルダごとに Drum Rack 入り MIDI トラック。C0(24)から半音ずつ。104 個を超えたら複数ラックに分ける
- フォルダの 1 段下ごとにトラックを分け、ベンダー接頭辞(
HD_など)はトラック名から外す。RIFF/DRUM/BASSのような語は残す - ループ側は
LOOPS、ワンショット側はONE SHOTSのグループにまとめる - ループのフォルダに混ざっていた単発は
OS <名前>の Drum Rack へ、その逆はオーディオトラックへ(ファイル単位の判定は Reference-Loopcloud)
曲キット型(songs レイアウト。Singomakers の Vol.4 以降など):
- シーン = 曲(番号順。シーン名は「番号 キー BPM」、シーンのテンポを有効化)
- 列 = パート(FULL MIX が先頭、
PIANO 1…)。WAV の隣に同じパートの MIDI クリップを置く(.midはmidi-file.jsで読んで KeyTrack / MidiNoteEvent に展開) - 曲番号はファイル名の
Song_01/Kit_01/Theme_01から。SEPT2_WAV_24の 24 は曲番号ではない
テンポ:
-
クリップのテンポはファイルごとの BPM(名前 → WAV の
acidチャンク → Loopcloud DB の順)。WarpMarker の拍数はこの BPM から計算し、1/4 拍のグリッドに 0.02 拍以内で乗るときだけ丸める -
セットのテンポは、最も多い BPM が過半数ならそれ、そうでなければクリップ群の中央値(
sample-meta.jsのcentralBpm)。名前にもacidにも BPM が無いパックは 120
node scripts/extract-templates.jsLive 12.4.5 が保存した実物(クリップ入りオーディオトラック + Drum Rack 入り MIDI トラック + Group を含むセット)から templates/*.xml を起こします。テンプレートはコミット済みなので、通常は実行不要です。Live のバージョンが上がって形式が変わったときに、同じ構成のセットを新しい Live で保存してから実行します。
- AudioClip の長さは拍数。WarpMarker は (0,0) (秒,拍) に加えて「1/32 拍先」をもう 1 つ置く
- DrumBranch の
ReceivingNoteは 128 − MIDI ノート(C0 = 24 → 104) - Simpler の
SampleEnd/SustainLoop.Endはフレーム数 − 1 -
ClipSlotListは MainSequencer と FreezeSequencer で 2 回出る -
LomIdは 0 でよい。OriginalCrcが 0 でも Live は開く - 土台に Live 同梱の
DefaultLiveSet.als(12.1d1 製)を使うと、スキーマ移行に掛かって「破損」扱いになる
| モジュール | 内容 |
|---|---|
audio-info.js |
WAV / AIFF のヘッダからフレーム数・サンプルレート・ビット深度・acid チャンク(ワンショット / ループのフラグ、拍数)を読む。WAVE_FORMAT_EXTENSIBLE、AIFF の sowt / fl32 対応 |
sample-meta.js |
ファイル名から BPM とキー(HD_808Loop_155_E_… / SMD_60_Bb_… / SEP5_Song_01_F_130_BPM / …_C_BPM195_08 / … - 128 bpm / SEPT2_01_93_bpm_D)。並び順(テンポ → キー → 名前)。centralBpm
|
midi-file.js |
Standard MIDI File からノートだけを読む(notes は拍単位、ランニングステータス対応) |
| 関数 | 内容 |
|---|---|
isOpenInLive(file) |
Live の Log.txt から、そのセットを Live が開いているか |
currentLiveDocument() |
Live が最後に開いたセットのパス |
liveMessage(text) |
Remote Script(TCP 3361)経由でステータスバーへ 1 行出す。無ければ何もしない |
notify(text) |
Live へ出しつつ標準出力にも必ず残す |