@onjmin/dtm 0.1.29 → 0.1.30

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
@@ -309,17 +309,6 @@ type StreamPlaybackOptions = {
309
309
  * 引数には遅れたノート情報と遅延秒数が渡されます。
310
310
  */
311
311
  onLateSkip?: (note: StreamVoiceNote, delay: number) => void;
312
- /**
313
- * 合成が間に合わず、代替メロディ(楽器)を鳴らす際のコールバック。
314
- * 引数には対象トラック、ノート情報、および発音すべき絶対時刻(AudioContextクロック秒)が渡されます。
315
- */
316
- onFallbackPlayNote?: (track: StreamVoiceTrack, note: StreamVoiceNote, t0: number) => void;
317
- /**
318
- * 遅延判定の閾値(秒)。発音予定時刻よりこの秒数前に合成完了していない場合、
319
- * 遅延するとみなし代替メロディに切り替えます。
320
- * 省略時は 0.15 秒(150ms)です。
321
- */
322
- fallbackThresholdSec?: number;
323
312
  };
324
313
  /**
325
314
  * 歌唱モデルをまとめて管理し、koeデモ式の「先読みストリーミング合成」で歌わせる高レベルヘルパ。
package/dist/index.d.ts CHANGED
@@ -309,17 +309,6 @@ type StreamPlaybackOptions = {
309
309
  * 引数には遅れたノート情報と遅延秒数が渡されます。
310
310
  */
311
311
  onLateSkip?: (note: StreamVoiceNote, delay: number) => void;
312
- /**
313
- * 合成が間に合わず、代替メロディ(楽器)を鳴らす際のコールバック。
314
- * 引数には対象トラック、ノート情報、および発音すべき絶対時刻(AudioContextクロック秒)が渡されます。
315
- */
316
- onFallbackPlayNote?: (track: StreamVoiceTrack, note: StreamVoiceNote, t0: number) => void;
317
- /**
318
- * 遅延判定の閾値(秒)。発音予定時刻よりこの秒数前に合成完了していない場合、
319
- * 遅延するとみなし代替メロディに切り替えます。
320
- * 省略時は 0.15 秒(150ms)です。
321
- */
322
- fallbackThresholdSec?: number;
323
312
  };
324
313
  /**
325
314
  * 歌唱モデルをまとめて管理し、koeデモ式の「先読みストリーミング合成」で歌わせる高レベルヘルパ。
package/dist/index.js CHANGED
@@ -2826,44 +2826,13 @@ var createSingingVoices = (ctx, destination, options = {}) => {
2826
2826
  if (model.renderToCache && model.scheduleCached) {
2827
2827
  const renderToCache = model.renderToCache;
2828
2828
  const scheduleCached = model.scheduleCached;
2829
- const threshold = opts?.fallbackThresholdSec ?? 0.15;
2830
2829
  void (async () => {
2831
- let isTimeout = false;
2832
- let timeoutId;
2833
- const renderPromise = renderToCache(
2830
+ const key = await renderToCache(
2834
2831
  note.syllable,
2835
2832
  prevVowel,
2836
2833
  note.pitch,
2837
2834
  note.durationSec * 1e3
2838
- ).then((key2) => {
2839
- if (timeoutId) clearTimeout(timeoutId);
2840
- return { key: key2, type: "success" };
2841
- });
2842
- const timeoutLimitTime = t0 - threshold;
2843
- const timeoutDelayMs = (timeoutLimitTime - ctx.currentTime) * 1e3;
2844
- const timeoutPromise = new Promise(
2845
- (resolve) => {
2846
- if (timeoutDelayMs <= 0) {
2847
- isTimeout = true;
2848
- resolve({ key: null, type: "timeout" });
2849
- } else {
2850
- timeoutId = setTimeout(() => {
2851
- isTimeout = true;
2852
- resolve({ key: null, type: "timeout" });
2853
- }, timeoutDelayMs);
2854
- }
2855
- }
2856
2835
  );
2857
- const result = await Promise.race([renderPromise, timeoutPromise]);
2858
- if (session !== streamSession) return;
2859
- if (result.type === "timeout") {
2860
- console.warn(
2861
- `[dtm] Synthesizer expected late skip: ${note.syllable.kana} at ${note.startSec}s. Fallback to instrument.`
2862
- );
2863
- opts?.onFallbackPlayNote?.(track, note, t0);
2864
- return;
2865
- }
2866
- const key = result.key;
2867
2836
  if (session !== streamSession) return;
2868
2837
  if (key) {
2869
2838
  const delay = ctx.currentTime - t0;
@@ -2871,10 +2840,9 @@ var createSingingVoices = (ctx, destination, options = {}) => {
2871
2840
  scheduleCached(key, t0, peak, track.pan);
2872
2841
  } else {
2873
2842
  console.warn(
2874
- `[dtm] Synthesizer late skip (safety): ${note.syllable.kana} at ${note.startSec}s (delayed by ${delay.toFixed(3)}s)`
2843
+ `[dtm] Synthesizer late skip: ${note.syllable.kana} at ${note.startSec}s (delayed by ${delay.toFixed(3)}s)`
2875
2844
  );
2876
2845
  opts?.onLateSkip?.(note, delay);
2877
- opts?.onFallbackPlayNote?.(track, note, t0);
2878
2846
  }
2879
2847
  }
2880
2848
  })();
@@ -7162,31 +7130,10 @@ var mountMmlPlayer = (target, mml, options = {}) => {
7162
7130
  if (streaming && !skipSinging) {
7163
7131
  ensureVoices().startStream(tracks, seq.getStartTime(), {
7164
7132
  isAudible: (t) => !mutedTracks.has(Number(t.id)),
7165
- onFallbackPlayNote: (track, note, t0) => {
7133
+ onLateSkip: () => {
7166
7134
  showPlayerMessage(
7167
7135
  "\u97F3\u58F0\u5408\u6210\u304C\u9593\u306B\u5408\u308F\u306A\u3044\u305F\u3081\u3001\u4E00\u90E8\u306E\u767A\u97F3\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u307E\u3057\u305F"
7168
7136
  );
7169
- const trackIdx = Number(track.id);
7170
- if (mutedTracks.has(trackIdx)) return;
7171
- const lt = lyricTracks.get(trackIdx);
7172
- if (!lt) return;
7173
- const relativeWhen = t0 - ensureCtx().currentTime;
7174
- if (relativeWhen > 0) {
7175
- const vol = (lt.volume ?? DEFAULT_VOCAL_VOLUME) / 100 * (trackVolume / 100);
7176
- const e = {
7177
- trackId: track.id ?? "",
7178
- pitch: note.pitch,
7179
- velocity: 100,
7180
- volume: vol,
7181
- when: relativeWhen,
7182
- duration: note.durationSec,
7183
- pan: track.pan
7184
- };
7185
- options.onPlayNote?.(e);
7186
- if (useSynth) ensureSynth().playNote(e);
7187
- }
7188
- },
7189
- onLateSkip: () => {
7190
7137
  }
7191
7138
  });
7192
7139
  }
@@ -8196,27 +8143,7 @@ var mountDAW = (target, options = {}) => {
8196
8143
  sequencer.start(fromStep);
8197
8144
  if (streaming && voices) {
8198
8145
  voices.startStream(streamTracks, sequencer.getStartTime(), {
8199
- isAudible: (t) => !isSolo || t.id === activeTrackId,
8200
- onFallbackPlayNote: (track, note, t0) => {
8201
- if (isSolo && track.id !== activeTrackId) return;
8202
- const relativeWhen = t0 - getAudioTime();
8203
- if (relativeWhen > 0) {
8204
- const trackState = trackStates.find(
8205
- (t) => t.config.id === track.id
8206
- );
8207
- const trackVol = trackState ? trackState.volume : 80;
8208
- const volume = trackVol / 100 * (masterVolume / 100);
8209
- options.onPlayNote?.({
8210
- trackId: track.id ?? "",
8211
- pitch: note.pitch,
8212
- velocity: 100,
8213
- volume,
8214
- when: relativeWhen,
8215
- duration: note.durationSec,
8216
- pan: track.pan
8217
- });
8218
- }
8219
- }
8146
+ isAudible: (t) => !isSolo || t.id === activeTrackId
8220
8147
  });
8221
8148
  }
8222
8149
  updateTransport();
package/dist/index.mjs CHANGED
@@ -2718,44 +2718,13 @@ var createSingingVoices = (ctx, destination, options = {}) => {
2718
2718
  if (model.renderToCache && model.scheduleCached) {
2719
2719
  const renderToCache = model.renderToCache;
2720
2720
  const scheduleCached = model.scheduleCached;
2721
- const threshold = opts?.fallbackThresholdSec ?? 0.15;
2722
2721
  void (async () => {
2723
- let isTimeout = false;
2724
- let timeoutId;
2725
- const renderPromise = renderToCache(
2722
+ const key = await renderToCache(
2726
2723
  note.syllable,
2727
2724
  prevVowel,
2728
2725
  note.pitch,
2729
2726
  note.durationSec * 1e3
2730
- ).then((key2) => {
2731
- if (timeoutId) clearTimeout(timeoutId);
2732
- return { key: key2, type: "success" };
2733
- });
2734
- const timeoutLimitTime = t0 - threshold;
2735
- const timeoutDelayMs = (timeoutLimitTime - ctx.currentTime) * 1e3;
2736
- const timeoutPromise = new Promise(
2737
- (resolve) => {
2738
- if (timeoutDelayMs <= 0) {
2739
- isTimeout = true;
2740
- resolve({ key: null, type: "timeout" });
2741
- } else {
2742
- timeoutId = setTimeout(() => {
2743
- isTimeout = true;
2744
- resolve({ key: null, type: "timeout" });
2745
- }, timeoutDelayMs);
2746
- }
2747
- }
2748
2727
  );
2749
- const result = await Promise.race([renderPromise, timeoutPromise]);
2750
- if (session !== streamSession) return;
2751
- if (result.type === "timeout") {
2752
- console.warn(
2753
- `[dtm] Synthesizer expected late skip: ${note.syllable.kana} at ${note.startSec}s. Fallback to instrument.`
2754
- );
2755
- opts?.onFallbackPlayNote?.(track, note, t0);
2756
- return;
2757
- }
2758
- const key = result.key;
2759
2728
  if (session !== streamSession) return;
2760
2729
  if (key) {
2761
2730
  const delay = ctx.currentTime - t0;
@@ -2763,10 +2732,9 @@ var createSingingVoices = (ctx, destination, options = {}) => {
2763
2732
  scheduleCached(key, t0, peak, track.pan);
2764
2733
  } else {
2765
2734
  console.warn(
2766
- `[dtm] Synthesizer late skip (safety): ${note.syllable.kana} at ${note.startSec}s (delayed by ${delay.toFixed(3)}s)`
2735
+ `[dtm] Synthesizer late skip: ${note.syllable.kana} at ${note.startSec}s (delayed by ${delay.toFixed(3)}s)`
2767
2736
  );
2768
2737
  opts?.onLateSkip?.(note, delay);
2769
- opts?.onFallbackPlayNote?.(track, note, t0);
2770
2738
  }
2771
2739
  }
2772
2740
  })();
@@ -7054,31 +7022,10 @@ var mountMmlPlayer = (target, mml, options = {}) => {
7054
7022
  if (streaming && !skipSinging) {
7055
7023
  ensureVoices().startStream(tracks, seq.getStartTime(), {
7056
7024
  isAudible: (t) => !mutedTracks.has(Number(t.id)),
7057
- onFallbackPlayNote: (track, note, t0) => {
7025
+ onLateSkip: () => {
7058
7026
  showPlayerMessage(
7059
7027
  "\u97F3\u58F0\u5408\u6210\u304C\u9593\u306B\u5408\u308F\u306A\u3044\u305F\u3081\u3001\u4E00\u90E8\u306E\u767A\u97F3\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u307E\u3057\u305F"
7060
7028
  );
7061
- const trackIdx = Number(track.id);
7062
- if (mutedTracks.has(trackIdx)) return;
7063
- const lt = lyricTracks.get(trackIdx);
7064
- if (!lt) return;
7065
- const relativeWhen = t0 - ensureCtx().currentTime;
7066
- if (relativeWhen > 0) {
7067
- const vol = (lt.volume ?? DEFAULT_VOCAL_VOLUME) / 100 * (trackVolume / 100);
7068
- const e = {
7069
- trackId: track.id ?? "",
7070
- pitch: note.pitch,
7071
- velocity: 100,
7072
- volume: vol,
7073
- when: relativeWhen,
7074
- duration: note.durationSec,
7075
- pan: track.pan
7076
- };
7077
- options.onPlayNote?.(e);
7078
- if (useSynth) ensureSynth().playNote(e);
7079
- }
7080
- },
7081
- onLateSkip: () => {
7082
7029
  }
7083
7030
  });
7084
7031
  }
@@ -8088,27 +8035,7 @@ var mountDAW = (target, options = {}) => {
8088
8035
  sequencer.start(fromStep);
8089
8036
  if (streaming && voices) {
8090
8037
  voices.startStream(streamTracks, sequencer.getStartTime(), {
8091
- isAudible: (t) => !isSolo || t.id === activeTrackId,
8092
- onFallbackPlayNote: (track, note, t0) => {
8093
- if (isSolo && track.id !== activeTrackId) return;
8094
- const relativeWhen = t0 - getAudioTime();
8095
- if (relativeWhen > 0) {
8096
- const trackState = trackStates.find(
8097
- (t) => t.config.id === track.id
8098
- );
8099
- const trackVol = trackState ? trackState.volume : 80;
8100
- const volume = trackVol / 100 * (masterVolume / 100);
8101
- options.onPlayNote?.({
8102
- trackId: track.id ?? "",
8103
- pitch: note.pitch,
8104
- velocity: 100,
8105
- volume,
8106
- when: relativeWhen,
8107
- duration: note.durationSec,
8108
- pan: track.pan
8109
- });
8110
- }
8111
- }
8038
+ isAudible: (t) => !isSolo || t.id === activeTrackId
8112
8039
  });
8113
8040
  }
8114
8041
  updateTransport();
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "author": "onjmin",
3
3
  "license": "MIT",
4
4
  "name": "@onjmin/dtm",
5
- "version": "0.1.29",
5
+ "version": "0.1.30",
6
6
  "description": "MMLを中間言語に用いた、モバイルファーストなDAW / ピアノロール打ち込みコンポーネント",
7
7
  "homepage": "https://onjmin.github.io/dtm",
8
8
  "repository": {