@onjmin/dtm 0.1.32 → 0.1.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -407,6 +407,18 @@ type AddNoteOptions = {
407
407
  noteLengthSteps: number;
408
408
  velocity?: number;
409
409
  };
410
+ /** パッチ送受信用ノートデータ(ローカルIDを持たない)。 */
411
+ type NoteData = {
412
+ startStep: number;
413
+ pitch: number;
414
+ durationSteps: number;
415
+ velocity?: number;
416
+ };
417
+ /** パッチ削除指定(startStep + pitch で音符を特定)。 */
418
+ type NoteRemove = {
419
+ startStep: number;
420
+ pitch: number;
421
+ };
410
422
  type PianoRollOptions = {
411
423
  mountTarget: HTMLElement;
412
424
  width?: number;
@@ -563,6 +575,20 @@ type DawOptions = {
563
575
  * 利用側が選択状態を永続化する用途に使う。
564
576
  */
565
577
  onViewStateChange?: (state: DawViewState) => void;
578
+ /**
579
+ * ユーザー操作によってノートが追加・削除されたときに呼ばれる(差分パッチ)。
580
+ * リアルタイム同期のための送信フックとして使う。
581
+ * `applyPatch` による適用時には呼ばれない(エコーループ防止)。
582
+ */
583
+ onNotesPatch?: (trackId: string, added: NoteData[], removed: NoteRemove[]) => void;
584
+ /**
585
+ * 編集をロックするトラックIDの配列。
586
+ * 指定されたトラックへのユーザー操作(音符追加・削除)は無視される。
587
+ * 協力DAWで他人のトラックを誤編集しないために使う。
588
+ */
589
+ lockedTracks?: string[];
590
+ /** 初期アクティブトラックID(未指定なら最初のトラック)。協力DAWで自分のトラックを初期選択するために使う。 */
591
+ initialActiveTrack?: string;
566
592
  parseMidi?: ParseMidiFn;
567
593
  /**
568
594
  * 動作モード({@link DawMode})。
@@ -611,6 +637,22 @@ type DawInstance = {
611
637
  getCurrentPlayStep: () => number;
612
638
  forcePauseAt: (step: number) => void;
613
639
  setLoading?: (loading: boolean) => void;
640
+ /**
641
+ * リモートから受信したパッチをローカルに適用する。
642
+ * `onNotesPatch` は発火しない(エコーループ防止)。
643
+ * 音符の識別は (startStep, pitch) ペアで行う(ローカルIDに依存しない)。
644
+ */
645
+ applyPatch: (trackId: string, added: NoteData[], removed: NoteRemove[]) => void;
646
+ /**
647
+ * 指定トラックの音符をキャンバス上で表示・非表示にする(目ミュート)。
648
+ * 非表示にしても内部データは保持される。
649
+ */
650
+ setTrackVisible: (trackId: string, visible: boolean) => void;
651
+ /**
652
+ * 指定トラックの発音を有効・無効にする(音ミュート)。
653
+ * false にすると onPlayNote が呼ばれなくなる。
654
+ */
655
+ setTrackAudible: (trackId: string, audible: boolean) => void;
614
656
  destroy: () => void;
615
657
  };
616
658
  type LoopPoint = {
@@ -651,6 +693,158 @@ declare const TRACKS_ADVANCED: TrackConfig[];
651
693
  */
652
694
  declare const mountDAW: (target: HTMLElement, options?: DawOptions) => DawInstance;
653
695
 
696
+ /**
697
+ * playMML — DOM非依存(ヘッドレス)の MML 再生関数。
698
+ *
699
+ * mountMmlPlayer が「絵文字・プレイヘッド付きの再生ビュー」なのに対し、こちらは
700
+ * 画面を一切持たず音だけを鳴らす。ゲームの BGM のように「文字列を渡して鳴らし、
701
+ * 止めたいときに止める」用途を想定している。
702
+ *
703
+ * 設計の要点:
704
+ * - 発音そのものは Web Audio のオーディオスレッド上で行われる(未来時刻に予約するため
705
+ * メインスレッドの負荷と独立して鳴る)。スケジューラは createSequencer の先読み方式。
706
+ * - `loop: true` で曲末停止せずシームレスにループ(BGM用)。
707
+ * - AudioContext を外から注入でき、出力先ノード(ゲームのマスターGain/ミキサー)へ繋げる。
708
+ * - タブが非アクティブになったら一時停止する挙動を、ctx の所有権に応じて自動で行う:
709
+ * 内部生成 ctx … 既定で suspend/resume する(自分の ctx なので止めてよい)。
710
+ * 注入 ctx … 既定では触らない(SE 等と共有している可能性があるため)。
711
+ * 代わりに返り値の suspend()/resume() を呼び出し側から叩ける。
712
+ *
713
+ * 歌声合成(@@n 歌詞トラック)はこのヘッドレス関数では未対応(楽器・ドラムのみ)。
714
+ * 歌声が必要なら mountMmlPlayer / createDtmStudio を使う。
715
+ */
716
+
717
+ type PlayMmlOptions = {
718
+ /** ループ設定(true=全体ループ、LoopConfig=特定範囲ループ、false/省略=ループなし) */
719
+ loop?: boolean | LoopConfig;
720
+ /** 再生中にイベントを発火させるタイミング */
721
+ cues?: PlaybackCue[];
722
+ /** キューポイント通過時のコールバック */
723
+ onCue?: (cueId: string) => void;
724
+ /**
725
+ * 使用する AudioContext。省略時は内部生成し、destroy()/stop() で閉じる。
726
+ * onPlayNote で自前シンセを鳴らす場合は、時計をそろえるため自分の ctx を渡すこと。
727
+ */
728
+ audioContext?: AudioContext;
729
+ /** 出力先ノード(省略時は ctx.destination)。ゲームのマスターGain 等へ繋ぐ。 */
730
+ destination?: AudioNode;
731
+ /** 0-100 のマスタ音量。既定は MML の #volume → このオプション → 100 の順で解決。 */
732
+ volume?: number;
733
+ /** BPM未検出時のフォールバック。既定120 */
734
+ defaultBpm?: number;
735
+ /** ドラムパターン辞書。`#drum=<キー>` の解決に使う。既定 DRUM_PATTERNS */
736
+ drumPatterns?: Record<string, DrumPattern>;
737
+ /** 内蔵 square synth を使うか。既定は onPlayNote 未指定なら true */
738
+ synth?: boolean;
739
+ /** メロディックノートの発音要求(自前シンセに繋ぐ)。 */
740
+ onPlayNote?: (e: PlayNoteEvent) => void;
741
+ /** ドラムノートの発音要求。 */
742
+ onPlayDrum?: (e: PlayDrumEvent) => void;
743
+ /** 再生開始時に呼ばれる(追加の resume 処理等に使う)。 */
744
+ onResumeAudio?: () => void | Promise<void>;
745
+ /**
746
+ * タブ非アクティブ時に自動で suspend/resume するか。
747
+ * 既定は「内部生成 ctx のとき true / 注入 ctx のとき false」。
748
+ * 注入 ctx で true にすると、共有 ctx ごと suspend する点に注意。
749
+ */
750
+ pauseWhenHidden?: boolean;
751
+ /** ループ無効時に曲末(または stop())で呼ばれる。 */
752
+ onStop?: () => void;
753
+ };
754
+ type MmlPlayback = {
755
+ /** 再生を止める(ループ中でも停止)。 */
756
+ stop: () => void;
757
+ isPlaying: () => boolean;
758
+ /** マスタ音量を 0-100 で変更する(再生中も即時反映)。 */
759
+ setVolume: (volume: number) => void;
760
+ /** AudioContext を suspend(注入 ctx の場合、共有先も止まる点に注意)。 */
761
+ suspend: () => Promise<void>;
762
+ /** suspend からの復帰。 */
763
+ resume: () => Promise<void>;
764
+ /** 停止し、内部生成 ctx なら閉じてリスナも解除する。 */
765
+ destroy: () => void;
766
+ };
767
+ /**
768
+ * MML 文字列を画面なしで再生する。呼び出した時点で再生を開始する。
769
+ * ブラウザの自動再生ポリシー上、初回はユーザー操作のコールスタック内で呼ぶこと。
770
+ */
771
+ declare const playMML: (mml: string, options?: PlayMmlOptions) => MmlPlayback;
772
+
773
+ /**
774
+ * playSingingMML — 歌声付き(@@n 歌詞トラック)のヘッドレス MML 再生。【未実装スタブ】
775
+ *
776
+ * 楽器・ドラムのみの {@link playMML} とは別関数として切り出す。歌声は重い WORLD 再合成・
777
+ * worker のホスティング・非同期プリロードを伴うため、軽量な playMML に混ぜず分離する方針。
778
+ * 中身は実質「mountMmlPlayer の音響経路(sequencer + 内蔵synth + 歌声ストリーム配線)から
779
+ * DOM を抜いたもの」になる予定。
780
+ *
781
+ * ─────────────────────────────────────────────────────────────────────────
782
+ * 実装メモ / 懸念事項(実装する人へ)
783
+ * ─────────────────────────────────────────────────────────────────────────
784
+ *
785
+ * ■ 全体の構成(実装方針)
786
+ * 1. parseMML(mml, { collectLyrics: true }) で placements / lyrics / meta を取る。
787
+ * 2. 楽器トラックは playMML と同じく seqTracks 化 → createSequencer + createSynth で再生。
788
+ * 3. 歌声は createSingingVoices(ctx, destination, { voiceWorkerUrl }) を生成し、
789
+ * mml-player.ts の buildStreamTracks 相当で StreamVoiceTrack[] を構築。
790
+ * 4. loadModels → warm を await(ここがローディング相当)。完了後に
791
+ * seq.start(0) と voices.startStream(tracks, seq.getStartTime()) を「同じアンカー」で開始。
792
+ * ※ 既存の正準実装は mml-player.ts の startWhenReady()。ほぼそのまま流用できる。
793
+ *
794
+ * ■ 非同期プリロードがあるため、この関数は Promise を返す(fire-and-forget にしない)。
795
+ * loadModels/warm の完了を待ってから resolve する。待機中に stop された場合は起動しない
796
+ * ガードが要る(mml-player.ts の `if (!playing || activePlayer !== instance) return;` 相当)。
797
+ *
798
+ * ■ worker URL は利用側がホストする(必須)。createSingingVoices の voiceWorkerUrl に渡す。
799
+ * 省略時はメインスレッド合成にフォールバックするが、BGM 用途では worker 必須を推奨。
800
+ * あるいは既存の singingVoices インスタンスを注入できるようにする(createDtmStudio と同様)。
801
+ *
802
+ * ■【最大の懸念】シームレスループと歌声ストリームが噛み合わない
803
+ * - 今回 sequencer に入れたループは「先読みタイムラインを永久に再アーム」する方式
804
+ * (sequencer.ts の loopBase += loopLengthSec)。楽器はこれで継ぎ目なくループする。
805
+ * - 一方 startStream は【1セッション制】。startStream を呼び直すと streamSession が増えて
806
+ * 前のループが中断される(lyrics.ts:1402 / 1421)。よって「次周を裏で先行スケジュール」は
807
+ * 前周をキャンセルしてしまうため不可。
808
+ * - さらに先読みは STREAM_LOOKAHEAD_SEC = 1.5 秒(lyrics.ts:1276)。曲末ぎりぎりで
809
+ * startStream を再発行すると、まだ合成待ちだった末尾〜1.5秒の歌が毎周ドロップする。
810
+ * → 「境界で呼び直す」方式は継ぎ目が汚れる/歌が欠ける。採用しないこと。
811
+ *
812
+ * ■【推奨する解】startStream 自体をループ対応にする(lyrics.ts の小改修)
813
+ * sequencer.ts と同じ要領で、startStream({ loopLengthSec }) を受け取り、runTrack の
814
+ * items を一巡したら i=0 に戻して内部オフセットへ loopLengthSec を加算する。
815
+ * 1セッションのまま先読みが途切れず、継ぎ目もドロップも出ない。loopLengthSec は楽器側
816
+ * (sequencer の loopLengthSec)と同一値を共有すれば、伴奏と歌が同周期で永久に揃う。
817
+ * ※ この改修が入るまでは loop:true を歌入りで使うとズレる。下のガード参照。
818
+ *
819
+ * ■ AudioContext / visibility は playMML と同じ方針(ctx 所有権で suspend 権限を分ける)。
820
+ * ただし注入 ctx + 注入 destination を createSingingVoices にもそのまま渡すこと
821
+ * (歌声と楽器を同じミキサーへ流す)。
822
+ *
823
+ * ■ stop/destroy では seq.stop() に加えて voices.stopStream()(+ 内部生成なら ctx.close)
824
+ * とモデルの後始末(reset)を忘れない。
825
+ *
826
+ * 関連: {@link playMML}(楽器のみ), mml-player.ts(DOM版の正準実装), lyrics.ts(歌声合成)。
827
+ */
828
+
829
+ type PlaySingingMmlOptions = PlayMmlOptions & {
830
+ /**
831
+ * 歌声合成 Worker(`voice-worker.js`)のURL。利用側がホストして渡す。
832
+ * 省略時はメインスレッド合成へフォールバック(BGM用途では worker 推奨)。
833
+ */
834
+ voiceWorkerUrl?: string;
835
+ /**
836
+ * 既存の歌唱合成ヘルパを注入する(createDtmStudio と同様の配線を流用したい場合)。
837
+ * 指定時は voiceWorkerUrl より優先し、内部で createSingingVoices しない。
838
+ */
839
+ singingVoices?: SingingVoices;
840
+ };
841
+ /**
842
+ * 歌声付き MML を画面なしで再生する。【未実装】
843
+ *
844
+ * @throws 現状は常に未実装エラーを投げる。実装方針は本ファイル冒頭の実装メモを参照。
845
+ */
846
+ declare const playSingingMML: (_mml: string, _options?: PlaySingingMmlOptions) => Promise<MmlPlayback>;
847
+
654
848
  /**
655
849
  * インラインSVGアイコン。外部アイコンフォント(MDI等)への依存を避けるため、
656
850
  * 必要最小限のパスをライブラリ内に同梱する。
@@ -908,184 +1102,6 @@ type ExportMidiOptions = {
908
1102
  */
909
1103
  declare const exportMIDI: (options: ExportMidiOptions) => Blob;
910
1104
 
911
- /**
912
- * playMML — DOM非依存(ヘッドレス)の MML 再生関数。
913
- *
914
- * mountMmlPlayer が「絵文字・プレイヘッド付きの再生ビュー」なのに対し、こちらは
915
- * 画面を一切持たず音だけを鳴らす。ゲームの BGM のように「文字列を渡して鳴らし、
916
- * 止めたいときに止める」用途を想定している。
917
- *
918
- * 設計の要点:
919
- * - 発音そのものは Web Audio のオーディオスレッド上で行われる(未来時刻に予約するため
920
- * メインスレッドの負荷と独立して鳴る)。スケジューラは createSequencer の先読み方式。
921
- * - `loop: true` で曲末停止せずシームレスにループ(BGM用)。
922
- * - AudioContext を外から注入でき、出力先ノード(ゲームのマスターGain/ミキサー)へ繋げる。
923
- * - タブが非アクティブになったら一時停止する挙動を、ctx の所有権に応じて自動で行う:
924
- * 内部生成 ctx … 既定で suspend/resume する(自分の ctx なので止めてよい)。
925
- * 注入 ctx … 既定では触らない(SE 等と共有している可能性があるため)。
926
- * 代わりに返り値の suspend()/resume() を呼び出し側から叩ける。
927
- *
928
- * 歌声合成(@@n 歌詞トラック)はこのヘッドレス関数では未対応(楽器・ドラムのみ)。
929
- * 歌声が必要なら mountMmlPlayer / createDtmStudio を使う。
930
- */
931
-
932
- type PlayMmlOptions = {
933
- /** ループ設定(true=全体ループ、LoopConfig=特定範囲ループ、false/省略=ループなし) */
934
- loop?: boolean | LoopConfig;
935
- /** 再生中にイベントを発火させるタイミング */
936
- cues?: PlaybackCue[];
937
- /** キューポイント通過時のコールバック */
938
- onCue?: (cueId: string) => void;
939
- /**
940
- * 使用する AudioContext。省略時は内部生成し、destroy()/stop() で閉じる。
941
- * onPlayNote で自前シンセを鳴らす場合は、時計をそろえるため自分の ctx を渡すこと。
942
- */
943
- audioContext?: AudioContext;
944
- /** 出力先ノード(省略時は ctx.destination)。ゲームのマスターGain 等へ繋ぐ。 */
945
- destination?: AudioNode;
946
- /** 0-100 のマスタ音量。既定は MML の #volume → このオプション → 100 の順で解決。 */
947
- volume?: number;
948
- /** BPM未検出時のフォールバック。既定120 */
949
- defaultBpm?: number;
950
- /** ドラムパターン辞書。`#drum=<キー>` の解決に使う。既定 DRUM_PATTERNS */
951
- drumPatterns?: Record<string, DrumPattern>;
952
- /** 内蔵 square synth を使うか。既定は onPlayNote 未指定なら true */
953
- synth?: boolean;
954
- /** メロディックノートの発音要求(自前シンセに繋ぐ)。 */
955
- onPlayNote?: (e: PlayNoteEvent) => void;
956
- /** ドラムノートの発音要求。 */
957
- onPlayDrum?: (e: PlayDrumEvent) => void;
958
- /** 再生開始時に呼ばれる(追加の resume 処理等に使う)。 */
959
- onResumeAudio?: () => void | Promise<void>;
960
- /**
961
- * タブ非アクティブ時に自動で suspend/resume するか。
962
- * 既定は「内部生成 ctx のとき true / 注入 ctx のとき false」。
963
- * 注入 ctx で true にすると、共有 ctx ごと suspend する点に注意。
964
- */
965
- pauseWhenHidden?: boolean;
966
- /** ループ無効時に曲末(または stop())で呼ばれる。 */
967
- onStop?: () => void;
968
- };
969
- type MmlPlayback = {
970
- /** 再生を止める(ループ中でも停止)。 */
971
- stop: () => void;
972
- isPlaying: () => boolean;
973
- /** マスタ音量を 0-100 で変更する(再生中も即時反映)。 */
974
- setVolume: (volume: number) => void;
975
- /** AudioContext を suspend(注入 ctx の場合、共有先も止まる点に注意)。 */
976
- suspend: () => Promise<void>;
977
- /** suspend からの復帰。 */
978
- resume: () => Promise<void>;
979
- /** 停止し、内部生成 ctx なら閉じてリスナも解除する。 */
980
- destroy: () => void;
981
- };
982
- /**
983
- * MML 文字列を画面なしで再生する。呼び出した時点で再生を開始する。
984
- * ブラウザの自動再生ポリシー上、初回はユーザー操作のコールスタック内で呼ぶこと。
985
- */
986
- declare const playMML: (mml: string, options?: PlayMmlOptions) => MmlPlayback;
987
-
988
- /**
989
- * playSingingMML — 歌声付き(@@n 歌詞トラック)のヘッドレス MML 再生。【未実装スタブ】
990
- *
991
- * 楽器・ドラムのみの {@link playMML} とは別関数として切り出す。歌声は重い WORLD 再合成・
992
- * worker のホスティング・非同期プリロードを伴うため、軽量な playMML に混ぜず分離する方針。
993
- * 中身は実質「mountMmlPlayer の音響経路(sequencer + 内蔵synth + 歌声ストリーム配線)から
994
- * DOM を抜いたもの」になる予定。
995
- *
996
- * ─────────────────────────────────────────────────────────────────────────
997
- * 実装メモ / 懸念事項(実装する人へ)
998
- * ─────────────────────────────────────────────────────────────────────────
999
- *
1000
- * ■ 全体の構成(実装方針)
1001
- * 1. parseMML(mml, { collectLyrics: true }) で placements / lyrics / meta を取る。
1002
- * 2. 楽器トラックは playMML と同じく seqTracks 化 → createSequencer + createSynth で再生。
1003
- * 3. 歌声は createSingingVoices(ctx, destination, { voiceWorkerUrl }) を生成し、
1004
- * mml-player.ts の buildStreamTracks 相当で StreamVoiceTrack[] を構築。
1005
- * 4. loadModels → warm を await(ここがローディング相当)。完了後に
1006
- * seq.start(0) と voices.startStream(tracks, seq.getStartTime()) を「同じアンカー」で開始。
1007
- * ※ 既存の正準実装は mml-player.ts の startWhenReady()。ほぼそのまま流用できる。
1008
- *
1009
- * ■ 非同期プリロードがあるため、この関数は Promise を返す(fire-and-forget にしない)。
1010
- * loadModels/warm の完了を待ってから resolve する。待機中に stop された場合は起動しない
1011
- * ガードが要る(mml-player.ts の `if (!playing || activePlayer !== instance) return;` 相当)。
1012
- *
1013
- * ■ worker URL は利用側がホストする(必須)。createSingingVoices の voiceWorkerUrl に渡す。
1014
- * 省略時はメインスレッド合成にフォールバックするが、BGM 用途では worker 必須を推奨。
1015
- * あるいは既存の singingVoices インスタンスを注入できるようにする(createDtmStudio と同様)。
1016
- *
1017
- * ■【最大の懸念】シームレスループと歌声ストリームが噛み合わない
1018
- * - 今回 sequencer に入れたループは「先読みタイムラインを永久に再アーム」する方式
1019
- * (sequencer.ts の loopBase += loopLengthSec)。楽器はこれで継ぎ目なくループする。
1020
- * - 一方 startStream は【1セッション制】。startStream を呼び直すと streamSession が増えて
1021
- * 前のループが中断される(lyrics.ts:1402 / 1421)。よって「次周を裏で先行スケジュール」は
1022
- * 前周をキャンセルしてしまうため不可。
1023
- * - さらに先読みは STREAM_LOOKAHEAD_SEC = 1.5 秒(lyrics.ts:1276)。曲末ぎりぎりで
1024
- * startStream を再発行すると、まだ合成待ちだった末尾〜1.5秒の歌が毎周ドロップする。
1025
- * → 「境界で呼び直す」方式は継ぎ目が汚れる/歌が欠ける。採用しないこと。
1026
- *
1027
- * ■【推奨する解】startStream 自体をループ対応にする(lyrics.ts の小改修)
1028
- * sequencer.ts と同じ要領で、startStream({ loopLengthSec }) を受け取り、runTrack の
1029
- * items を一巡したら i=0 に戻して内部オフセットへ loopLengthSec を加算する。
1030
- * 1セッションのまま先読みが途切れず、継ぎ目もドロップも出ない。loopLengthSec は楽器側
1031
- * (sequencer の loopLengthSec)と同一値を共有すれば、伴奏と歌が同周期で永久に揃う。
1032
- * ※ この改修が入るまでは loop:true を歌入りで使うとズレる。下のガード参照。
1033
- *
1034
- * ■ AudioContext / visibility は playMML と同じ方針(ctx 所有権で suspend 権限を分ける)。
1035
- * ただし注入 ctx + 注入 destination を createSingingVoices にもそのまま渡すこと
1036
- * (歌声と楽器を同じミキサーへ流す)。
1037
- *
1038
- * ■ stop/destroy では seq.stop() に加えて voices.stopStream()(+ 内部生成なら ctx.close)
1039
- * とモデルの後始末(reset)を忘れない。
1040
- *
1041
- * 関連: {@link playMML}(楽器のみ), mml-player.ts(DOM版の正準実装), lyrics.ts(歌声合成)。
1042
- */
1043
-
1044
- type PlaySingingMmlOptions = PlayMmlOptions & {
1045
- /**
1046
- * 歌声合成 Worker(`voice-worker.js`)のURL。利用側がホストして渡す。
1047
- * 省略時はメインスレッド合成へフォールバック(BGM用途では worker 推奨)。
1048
- */
1049
- voiceWorkerUrl?: string;
1050
- /**
1051
- * 既存の歌唱合成ヘルパを注入する(createDtmStudio と同様の配線を流用したい場合)。
1052
- * 指定時は voiceWorkerUrl より優先し、内部で createSingingVoices しない。
1053
- */
1054
- singingVoices?: SingingVoices;
1055
- };
1056
- /**
1057
- * 歌声付き MML を画面なしで再生する。【未実装】
1058
- *
1059
- * @throws 現状は常に未実装エラーを投げる。実装方針は本ファイル冒頭の実装メモを参照。
1060
- */
1061
- declare const playSingingMML: (_mml: string, _options?: PlaySingingMmlOptions) => Promise<MmlPlayback>;
1062
-
1063
- /**
1064
- * 内蔵の簡易square-wave synth + ノイズ系ドラム音。
1065
- *
1066
- * もともと mml-player.ts の中にインラインで持っていたものを、DOM非依存の発音器として
1067
- * 切り出したもの。これにより mountMmlPlayer(DOMビュー)と playMML(ヘッドレス)の双方が
1068
- * 同じ発音ロジックを共有できる。
1069
- *
1070
- * 設計上、AudioContext と出力先ノードは「外から渡す」。これは利用側が自前のマスターGain /
1071
- * ミキサーへルーティングしたり、SE と AudioContext を共有したりできるようにするため。
1072
- */
1073
-
1074
- /** MIDIピッチ番号 → 周波数(Hz)。A4(69)=440Hz 基準。 */
1075
- declare const freqFromPitch: (pitch: number) => number;
1076
- type Synth = {
1077
- /** メロディックノートを発音する(PlayNoteEvent.when は ctx.currentTime からの相対秒) */
1078
- playNote: (e: PlayNoteEvent) => void;
1079
- /** ドラムノートを発音する(General MIDI のドラムキー番号で音色を分岐) */
1080
- playDrum: (e: PlayDrumEvent) => void;
1081
- };
1082
- /**
1083
- * AudioContext と出力先ノードを束ねた発音器を作る。
1084
- * @param ctx 発音に使う AudioContext
1085
- * @param destination 接続先(省略時は ctx.destination)。ゲーム側ミキサーへ繋ぐ用途。
1086
- */
1087
- declare const createSynth: (ctx: AudioContext, destination?: AudioNode) => Synth;
1088
-
1089
1105
  /**
1090
1106
  * MML文字列を解析し、トラックごとのノート配置へ復元するローダ。
1091
1107
  *
@@ -1219,6 +1235,13 @@ type MmlPlayerOptions = {
1219
1235
  embedUrl?: string;
1220
1236
  /** 利用規約への同意画面の表示をスキップするかどうか */
1221
1237
  skipConsent?: boolean;
1238
+ /**
1239
+ * 「MMLを表示」「MMLコピー」押下時に呼ばれる MML 取得コールバック。
1240
+ * 省略時は mountMmlPlayer に渡した mml をそのまま使う。
1241
+ * DAW と連携する場合は `() => daw.getMML().full` を渡すと
1242
+ * 常に最新の full フォーマット(メタ行・#end; 込み)を返せる。
1243
+ */
1244
+ getMml?: () => string;
1222
1245
  };
1223
1246
  type MmlPlayerInstance = {
1224
1247
  play: () => void;
@@ -1435,12 +1458,6 @@ type DtmStudioEngines = {
1435
1458
  SoundFont_list?: SoundFontListEngine;
1436
1459
  parseMidi?: DawOptions["parseMidi"];
1437
1460
  };
1438
- /** 既定の取得元URL(rpgen3 / jsDelivr)。options.cdn で個別に上書きできる。 */
1439
- declare const DEFAULT_CDN: {
1440
- readonly soundFont: "https://rpgen3.github.io/soundfont/mjs/surikov/SoundFont.mjs";
1441
- readonly soundFontDrum: "https://rpgen3.github.io/soundfont/mjs/surikov/SoundFont_drum.mjs";
1442
- readonly soundFontList: "https://rpgen3.github.io/soundfont/mjs/surikov/SoundFont_list.mjs";
1443
- };
1444
1461
  type DtmStudioOptions = {
1445
1462
  /** 既存の AudioContext を使う(未指定なら内部生成)。 */
1446
1463
  audioContext?: AudioContext;
@@ -1456,10 +1473,20 @@ type DtmStudioOptions = {
1456
1473
  voiceWorkerUrl?: string | null;
1457
1474
  /** 初期の楽器プリセットキー(INSTRUMENT_PRESETS)。既定 "retro_game"。 */
1458
1475
  defaultPreset?: string;
1459
- /** 外部エンジンの注入(指定したものは CDN 取得をスキップ)。 */
1476
+ /** 外部エンジンの注入(指定したものは組み込み実装をスキップ)。 */
1460
1477
  engines?: DtmStudioEngines;
1461
- /** CDN URL の上書き。 */
1462
- cdn?: Partial<typeof DEFAULT_CDN>;
1478
+ /**
1479
+ * koe音源(.koe)のベースURL。
1480
+ * Discord Activity など CSP 制限下で `/.proxy/koe` を渡すと
1481
+ * worker 内の fetch も同オリジン経由になり CSP を通過できる。
1482
+ */
1483
+ koeBaseUrl?: string;
1484
+ /**
1485
+ * worldline.js(WORLDボコーダ)のURL。
1486
+ * Discord Activity など CSP 制限下で `/.proxy/koe-lib/demo/world/worldline.js`
1487
+ * を渡すと worker 内の importScripts も同オリジン経由になり CSP を通過できる。
1488
+ */
1489
+ worldlineScriptUrl?: string;
1463
1490
  /** 有効化する機能。既定はすべて true。 */
1464
1491
  features?: {
1465
1492
  /** MIDIファイル読み込み。 */
@@ -1614,6 +1641,32 @@ declare const DAW_CSS = "\n@font-face {\n font-family: 'k8x12';\n src: url('ht
1614
1641
  */
1615
1642
  declare const injectStyles: (doc?: Document) => void;
1616
1643
 
1644
+ /**
1645
+ * 内蔵の簡易square-wave synth + ノイズ系ドラム音。
1646
+ *
1647
+ * もともと mml-player.ts の中にインラインで持っていたものを、DOM非依存の発音器として
1648
+ * 切り出したもの。これにより mountMmlPlayer(DOMビュー)と playMML(ヘッドレス)の双方が
1649
+ * 同じ発音ロジックを共有できる。
1650
+ *
1651
+ * 設計上、AudioContext と出力先ノードは「外から渡す」。これは利用側が自前のマスターGain /
1652
+ * ミキサーへルーティングしたり、SE と AudioContext を共有したりできるようにするため。
1653
+ */
1654
+
1655
+ /** MIDIピッチ番号 → 周波数(Hz)。A4(69)=440Hz 基準。 */
1656
+ declare const freqFromPitch: (pitch: number) => number;
1657
+ type Synth = {
1658
+ /** メロディックノートを発音する(PlayNoteEvent.when は ctx.currentTime からの相対秒) */
1659
+ playNote: (e: PlayNoteEvent) => void;
1660
+ /** ドラムノートを発音する(General MIDI のドラムキー番号で音色を分岐) */
1661
+ playDrum: (e: PlayDrumEvent) => void;
1662
+ };
1663
+ /**
1664
+ * AudioContext と出力先ノードを束ねた発音器を作る。
1665
+ * @param ctx 発音に使う AudioContext
1666
+ * @param destination 接続先(省略時は ctx.destination)。ゲーム側ミキサーへ繋ぐ用途。
1667
+ */
1668
+ declare const createSynth: (ctx: AudioContext, destination?: AudioNode) => Synth;
1669
+
1617
1670
  declare const VOICE_IMAGES: Record<string, string>;
1618
1671
 
1619
- export { type AddNoteOptions, type ApplyChordOptions, type ChordPatternType, type ChordPlacement, type ConsumedSyllable, type CoreEventHandlers, DAW_CSS, DEFAULT_BPM, DEFAULT_GATE, DEFAULT_PAN, DEFAULT_PLAYBACK_VELOCITY, DEFAULT_STEPS_PER_BAR, DEFAULT_VELOCITY, DEFAULT_VOCAL_VOLUME, DRUM_FONT, DRUM_KEYS, DRUM_PATTERNS, type DawInstance, type DawMode, type DawOptions, type DawViewState, type DrumPattern, type DtmStudio, type DtmStudioEngines, type DtmStudioOptions, type ExportMidiOptions, INSTRUMENT_PRESETS, type InstrumentPreset, KOE_BASE_URL, KOE_VOICEBANKS, KOE_VOICEBANK_LABELS, KOE_VOICEBANK_TERMS, type KoeVoiceOptions, LinkedList, type LoopConfig, type LoopPoint, type LyricSyllable, type LyricTrack, type LyricsConductor, MAX_VOCAL_VOLUME, MMLCore, type MMLDisplayToken, type MMLNotePlacement, MML_END_MARKER, type MidiExtraction, type MidiNotePlacement, type MidiTrackAnalysis, type MmlMeta, type MmlPlayback, type MmlPlayerInstance, type MmlPlayerOptions, type ModeSwitchInstance, type ModeSwitchOptions, type MountEditorOptions, type MountPlayerOptions, type Note, PITCH_MAP, PREWARM_NOTES, type ParseMMLOptions, type ParseMidiFn, type ParsedMML, type PianoRollInstance, type PianoRollOptions, type PitchToken, type PlayDrumEvent, type PlayMmlOptions, type PlayNoteEvent, type PlaySingingMmlOptions, type PlaybackCue, type PlaybackState, type PresetSelectInstance, type PresetSelectOptions, type PreviewSoundCallback, type RenderConfig, type Sequencer, type SequencerOptions, type SequencerTrack, type SingingVoices, type SingingVoicesOptions, type StreamPlaybackOptions, type StreamVoiceNote, type StreamVoiceTrack, type Synth, TRACKS_ADVANCED, TRACKS_SIMPLE, type ToolMode, type TrackConfig, VOICE_IMAGES, VOICE_IMAGE_KEY, type VoiceModel, type VoiceRegistry, analyzeMidiTracks, applyHarmonicFilter, applyMonophonic, buildChordPlacements, buildNameToKeyMapping, collectPitchTokens, createAudioContext, createDtmStudio, createKlattVoice, createKoeVoice, createLyricsConductor, createPianoRoll, createSequencer, createSingingVoices, createSynth, createVoiceRegistry, decodeMml, decomposeToMonophonic, drawGrid, drawHeader, drawKeyboard, drawNotes, drawSelectedNotes, drawSelectionRect, encodeMml, exportMIDI, extractMidiPlacements, extractMidiPlacementsByTrack, fetchSoundFontList, formatMmlMeta, freqFromPitch, generateRandomPattern, getDrawOffset, getGridCanvas, getGridContext, getGridPosition, getHeaderCanvas, getMidiBPM, getRenderConfig, getXY, icon, init, injectStyles, isChordHeavyTrack, koeUrl, mountDAW, mountMmlPlayer, normalizeLyrics, onClick, panToStereo, parseLyrics, parseMML, parseMmlMeta, playMML, playSingingMML, setDrawOffset, shiftNotes, stripLyrics, stripMmlMeta, vocalVolumeToGain };
1672
+ export { type AddNoteOptions, type ApplyChordOptions, type ChordPatternType, type ChordPlacement, type ConsumedSyllable, type CoreEventHandlers, DAW_CSS, DEFAULT_BPM, DEFAULT_GATE, DEFAULT_PAN, DEFAULT_PLAYBACK_VELOCITY, DEFAULT_STEPS_PER_BAR, DEFAULT_VELOCITY, DEFAULT_VOCAL_VOLUME, DRUM_FONT, DRUM_KEYS, DRUM_PATTERNS, type DawInstance, type DawMode, type DawOptions, type DawViewState, type DrumPattern, type DtmStudio, type DtmStudioEngines, type DtmStudioOptions, type ExportMidiOptions, INSTRUMENT_PRESETS, type InstrumentPreset, KOE_BASE_URL, KOE_VOICEBANKS, KOE_VOICEBANK_LABELS, KOE_VOICEBANK_TERMS, type KoeVoiceOptions, LinkedList, type LoopConfig, type LoopPoint, type LyricSyllable, type LyricTrack, type LyricsConductor, MAX_VOCAL_VOLUME, MMLCore, type MMLDisplayToken, type MMLNotePlacement, MML_END_MARKER, type MidiExtraction, type MidiNotePlacement, type MidiTrackAnalysis, type MmlMeta, type MmlPlayback, type MmlPlayerInstance, type MmlPlayerOptions, type ModeSwitchInstance, type ModeSwitchOptions, type MountEditorOptions, type MountPlayerOptions, type Note, type NoteData, type NoteRemove, PITCH_MAP, PREWARM_NOTES, type ParseMMLOptions, type ParseMidiFn, type ParsedMML, type PianoRollInstance, type PianoRollOptions, type PitchToken, type PlayDrumEvent, type PlayMmlOptions, type PlayNoteEvent, type PlaySingingMmlOptions, type PlaybackCue, type PlaybackState, type PresetSelectInstance, type PresetSelectOptions, type PreviewSoundCallback, type RenderConfig, type Sequencer, type SequencerOptions, type SequencerTrack, type SingingVoices, type SingingVoicesOptions, type StreamPlaybackOptions, type StreamVoiceNote, type StreamVoiceTrack, type Synth, TRACKS_ADVANCED, TRACKS_SIMPLE, type ToolMode, type TrackConfig, VOICE_IMAGES, VOICE_IMAGE_KEY, type VoiceModel, type VoiceRegistry, analyzeMidiTracks, applyHarmonicFilter, applyMonophonic, buildChordPlacements, buildNameToKeyMapping, collectPitchTokens, createAudioContext, createDtmStudio, createKlattVoice, createKoeVoice, createLyricsConductor, createPianoRoll, createSequencer, createSingingVoices, createSynth, createVoiceRegistry, decodeMml, decomposeToMonophonic, drawGrid, drawHeader, drawKeyboard, drawNotes, drawSelectedNotes, drawSelectionRect, encodeMml, exportMIDI, extractMidiPlacements, extractMidiPlacementsByTrack, fetchSoundFontList, formatMmlMeta, freqFromPitch, generateRandomPattern, getDrawOffset, getGridCanvas, getGridContext, getGridPosition, getHeaderCanvas, getMidiBPM, getRenderConfig, getXY, icon, init, injectStyles, isChordHeavyTrack, koeUrl, mountDAW, mountMmlPlayer, normalizeLyrics, onClick, panToStereo, parseLyrics, parseMML, parseMmlMeta, playMML, playSingingMML, setDrawOffset, shiftNotes, stripLyrics, stripMmlMeta, vocalVolumeToGain };