Skip to content

Reference ALS Scripts

Daisuke Tsukada edited this page Sep 5, 2026 · 2 revisions

.als スクリプト リファレンス

.als(Live セット)を Live を介さずに読み書きするスクリプト群です。すべて node scripts/<名前>.js で実行します。 設計方針(DOM に載せない、実物から起こしたテンプレート、Backup 退避)は 構成と設計方針 を参照。

共通の挙動

  • Live で開いているセットは書きません。 Live の Log.txt から今開いているセットを判定します(scripts/notify.jsisOpenInLive)。書いても画面に反映されず、Live 側の保存で消えるためです。承知のうえで進めるときだけ --force
  • 置き換えは Backup 退避してから。 Live 純正の Backup/<名前> [YYYY-MM-DD HHMMSS].als と同じ命名で退避します。削除は一切しません
  • 結果は Live のステータスバーへ通知します(Remote Script 導入時。無ければ標準出力のみ)
  • サンプル参照は Loopcloud 直参照(コピーを作りません)

als.js — 読み書きの土台

モジュールとして他のスクリプトから使います。

関数 内容
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 が変わらないか

als-group.js — Group 化

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                   # トラック Id

Live の Song API には group_tracks が無いため、ファイル側で行います。MCP ツール live.set.group_tracks はこれを呼んでいます。

als-refs.js / als-repair.js — 参照の修復

プロジェクトフォルダを移動すると、FileRefRelativePath.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 違うものは音の長さが違う可能性があるので一覧を確認する)
  • 書き換えるのは RelativePathPath の値だけ。& を含むパスは XML エスケープする
  • 見つからない参照(ユーザー自身の録音など)はレポートに残し、触らない

実績: Ambient TRACK Project の 10 セット・3,755 件を向け直し(Issue #19)。

als-diff.js — 比較

node scripts/als-diff.js <前.als> <後.als> [表示する塊の数]

2 つのセットを XML レベルで比較します。生成結果を Live が保存した結果と突き合わせる検証に使います(タグ出現数の差で「クリップが全部消えているのに 108 と報告していた」バグを捕まえた実績があります)。

als-generate.js — パックからセットを生成

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 クリップを置く(.midmidi-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.jscentralBpm)。名前にも acid にも BPM が無いパックは 120

extract-templates.js — テンプレートを起こす

node scripts/extract-templates.js

Live 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 / sample-meta.js / midi-file.js — 部品

モジュール 内容
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 は拍単位、ランニングステータス対応)

notify.js — 通知と「今のセット」判定

関数 内容
isOpenInLive(file) Live の Log.txt から、そのセットを Live が開いているか
currentLiveDocument() Live が最後に開いたセットのパス
liveMessage(text) Remote Script(TCP 3361)経由でステータスバーへ 1 行出す。無ければ何もしない
notify(text) Live へ出しつつ標準出力にも必ず残す

Clone this wiki locally