@onjmin/dtm 0.1.59 → 0.1.61
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 +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +20 -7
- package/dist/index.mjs +20 -7
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -406,6 +406,13 @@ type SingingVoices = {
|
|
|
406
406
|
stopStream: () => void;
|
|
407
407
|
/** ストリーム停止+各モデルの内部状態を初期化する。 */
|
|
408
408
|
reset: () => void;
|
|
409
|
+
/**
|
|
410
|
+
* マスタ音量(0〜1のゲイン)をリアルタイムに反映する。
|
|
411
|
+
* 発音時にゲインを焼き込む方式だと再生中の音量変更が既にスケジュール済み・
|
|
412
|
+
* ストリーミング中の音符に効かないため、全モデル共通の GainNode を介して
|
|
413
|
+
* 常時ライブ反映できるようにする。
|
|
414
|
+
*/
|
|
415
|
+
setVolume: (gain: number) => void;
|
|
409
416
|
};
|
|
410
417
|
/** {@link SingingVoices.warm} の既定先合成数(各トラック先頭からの音数)。 */
|
|
411
418
|
declare const PREWARM_NOTES = 3;
|
package/dist/index.d.ts
CHANGED
|
@@ -406,6 +406,13 @@ type SingingVoices = {
|
|
|
406
406
|
stopStream: () => void;
|
|
407
407
|
/** ストリーム停止+各モデルの内部状態を初期化する。 */
|
|
408
408
|
reset: () => void;
|
|
409
|
+
/**
|
|
410
|
+
* マスタ音量(0〜1のゲイン)をリアルタイムに反映する。
|
|
411
|
+
* 発音時にゲインを焼き込む方式だと再生中の音量変更が既にスケジュール済み・
|
|
412
|
+
* ストリーミング中の音符に効かないため、全モデル共通の GainNode を介して
|
|
413
|
+
* 常時ライブ反映できるようにする。
|
|
414
|
+
*/
|
|
415
|
+
setVolume: (gain: number) => void;
|
|
409
416
|
};
|
|
410
417
|
/** {@link SingingVoices.warm} の既定先合成数(各トラック先頭からの音数)。 */
|
|
411
418
|
declare const PREWARM_NOTES = 3;
|
package/dist/index.js
CHANGED
|
@@ -2676,8 +2676,10 @@ var createSingingVoices = (ctx, destination, options = {}) => {
|
|
|
2676
2676
|
for (const [k, v] of Object.entries(options.voicebanks ?? {}))
|
|
2677
2677
|
catalog[k.toLowerCase()] = v;
|
|
2678
2678
|
let streamSession = 0;
|
|
2679
|
+
const masterGain = ctx.createGain();
|
|
2680
|
+
masterGain.connect(destination);
|
|
2679
2681
|
const loaded = /* @__PURE__ */ new Map([
|
|
2680
|
-
[FALLBACK_MODEL, createKlattVoice(ctx,
|
|
2682
|
+
[FALLBACK_MODEL, createKlattVoice(ctx, masterGain)]
|
|
2681
2683
|
]);
|
|
2682
2684
|
const loading = /* @__PURE__ */ new Map();
|
|
2683
2685
|
const load2 = (model) => {
|
|
@@ -2693,7 +2695,7 @@ var createSingingVoices = (ctx, destination, options = {}) => {
|
|
|
2693
2695
|
// マニフェストだけ先読みし、音素PCMは歌う直前にオンデマンド取得する
|
|
2694
2696
|
// (= 初回に .koe 全体をDLしない。モバイル初回ロードの待ちを解消)。
|
|
2695
2697
|
// Blob/File が直接渡されたケース(ローカル読み込み)はそのまま BlobVoiceSource。
|
|
2696
|
-
createKoeVoice(ctx,
|
|
2698
|
+
createKoeVoice(ctx, masterGain, {
|
|
2697
2699
|
koe,
|
|
2698
2700
|
worldlineScriptUrl: options.worldlineScriptUrl,
|
|
2699
2701
|
lightweight: options.lightweight,
|
|
@@ -2830,13 +2832,17 @@ var createSingingVoices = (ctx, destination, options = {}) => {
|
|
|
2830
2832
|
stopStream();
|
|
2831
2833
|
for (const v of loaded.values()) v.reset?.();
|
|
2832
2834
|
};
|
|
2835
|
+
const setVolume = (gain) => {
|
|
2836
|
+
masterGain.gain.value = Math.max(0, gain);
|
|
2837
|
+
};
|
|
2833
2838
|
return {
|
|
2834
2839
|
loadModels,
|
|
2835
2840
|
registerVoicebanks,
|
|
2836
2841
|
warm,
|
|
2837
2842
|
startStream,
|
|
2838
2843
|
stopStream,
|
|
2839
|
-
reset
|
|
2844
|
+
reset,
|
|
2845
|
+
setVolume
|
|
2840
2846
|
};
|
|
2841
2847
|
};
|
|
2842
2848
|
var createVoiceRegistry = (models = {}, fallback = "klatt") => {
|
|
@@ -5605,6 +5611,7 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
5605
5611
|
if (!voices) {
|
|
5606
5612
|
const ctx = ensureCtx();
|
|
5607
5613
|
voices = createSingingVoices(ctx, ctx.destination);
|
|
5614
|
+
voices.setVolume(masterVolume / 100);
|
|
5608
5615
|
}
|
|
5609
5616
|
return voices;
|
|
5610
5617
|
};
|
|
@@ -6350,6 +6357,7 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6350
6357
|
};
|
|
6351
6358
|
const setVolume = (volume) => {
|
|
6352
6359
|
masterVolume = volume;
|
|
6360
|
+
peekVoices()?.setVolume(masterVolume / 100);
|
|
6353
6361
|
};
|
|
6354
6362
|
const buildStreamTracks = () => [...lyricTracks.entries()].map(([index, lt]) => {
|
|
6355
6363
|
const seqTrack = seqTracks.find((t) => Number(t.id) === index);
|
|
@@ -6372,7 +6380,7 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6372
6380
|
return {
|
|
6373
6381
|
id: String(index),
|
|
6374
6382
|
model: lt.model,
|
|
6375
|
-
volume: vocalVolumeToGain(lt.volume ?? DEFAULT_VOCAL_VOLUME) * (trackVolume / 100)
|
|
6383
|
+
volume: vocalVolumeToGain(lt.volume ?? DEFAULT_VOCAL_VOLUME) * (trackVolume / 100),
|
|
6376
6384
|
pan: panToStereo(lt.pan ?? DEFAULT_PAN),
|
|
6377
6385
|
notes
|
|
6378
6386
|
};
|
|
@@ -6606,7 +6614,7 @@ var findZone = (ctx, fontName, zones, pitchs = []) => {
|
|
|
6606
6614
|
for (let i = zones.length - 1; i >= 0; i--)
|
|
6607
6615
|
for (const v of set) {
|
|
6608
6616
|
const zone = zones[i];
|
|
6609
|
-
if (v < zone.keyRangeLow || v > zone.keyRangeHigh
|
|
6617
|
+
if (v < zone.keyRangeLow || v > zone.keyRangeHigh) continue;
|
|
6610
6618
|
set.delete(v);
|
|
6611
6619
|
map.set(v, { ...zone });
|
|
6612
6620
|
}
|
|
@@ -6704,7 +6712,7 @@ var adjustZone = async (ctx, fontName, zone) => {
|
|
|
6704
6712
|
const oldData = oldBuf.getChannelData(ch);
|
|
6705
6713
|
const newData = newBuf.getChannelData(ch);
|
|
6706
6714
|
for (let i = 0; i < attackLength; i++) {
|
|
6707
|
-
const ratio = attackLength >
|
|
6715
|
+
const ratio = attackLength > 1 ? i / (attackLength - 1) : 0;
|
|
6708
6716
|
const m = 1 + (gainMultiplier - 1) * ratio;
|
|
6709
6717
|
newData[i] = oldData[i] * m;
|
|
6710
6718
|
}
|
|
@@ -9029,6 +9037,7 @@ var init = (mountTarget, width = 800, height = 450, config) => {
|
|
|
9029
9037
|
gridCanvas.style.left = `${KEYBOARD_WIDTH}px`;
|
|
9030
9038
|
gridCanvas.style.top = `${HEADER_HEIGHT}px`;
|
|
9031
9039
|
gridCanvas.style.touchAction = "none";
|
|
9040
|
+
gridCanvas.style.userSelect = "none";
|
|
9032
9041
|
const gridCtx = gridCanvas.getContext("2d", { willReadFrequently: true });
|
|
9033
9042
|
if (!gridCtx) throw new Error("Failed to get 2D rendering context for grid.");
|
|
9034
9043
|
g_grid_ctx = gridCtx;
|
|
@@ -10022,6 +10031,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
10022
10031
|
let zoomY = 100;
|
|
10023
10032
|
let bpm = options.defaultBpm ?? DEFAULT_BPM;
|
|
10024
10033
|
let masterVolume = options.masterVolume ?? 50;
|
|
10034
|
+
options.singingVoices?.setVolume(masterVolume / 100);
|
|
10025
10035
|
let drumVolume = options.drumVolume ?? 80;
|
|
10026
10036
|
let currentDrumPattern = refs.drumSelect.value;
|
|
10027
10037
|
let currentInstrument = "";
|
|
@@ -10899,7 +10909,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
10899
10909
|
return {
|
|
10900
10910
|
id: trackState?.config.id,
|
|
10901
10911
|
model: lt.model,
|
|
10902
|
-
volume: vocalVolumeToGain(lt.volume ?? DEFAULT_VOCAL_VOLUME)
|
|
10912
|
+
volume: vocalVolumeToGain(lt.volume ?? DEFAULT_VOCAL_VOLUME),
|
|
10903
10913
|
pan: panToStereo(lt.pan ?? DEFAULT_PAN),
|
|
10904
10914
|
notes
|
|
10905
10915
|
};
|
|
@@ -11908,6 +11918,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
11908
11918
|
refs.masterVolume.addEventListener("input", () => {
|
|
11909
11919
|
masterVolume = Number.parseInt(refs.masterVolume.value, 10) || 0;
|
|
11910
11920
|
refs.masterVolumeLabel.textContent = `${masterVolume}%`;
|
|
11921
|
+
options.singingVoices?.setVolume(masterVolume / 100);
|
|
11911
11922
|
});
|
|
11912
11923
|
refs.drumSelect.addEventListener("change", () => {
|
|
11913
11924
|
currentDrumPattern = refs.drumSelect.value;
|
|
@@ -12784,11 +12795,13 @@ var mountDAW = (target, options = {}) => {
|
|
|
12784
12795
|
masterVolume = clamp3(volume, 0, 100);
|
|
12785
12796
|
refs.masterVolume.value = String(masterVolume);
|
|
12786
12797
|
refs.masterVolumeLabel.textContent = `${masterVolume}%`;
|
|
12798
|
+
options.singingVoices?.setVolume(masterVolume / 100);
|
|
12787
12799
|
},
|
|
12788
12800
|
setVolume: (volume) => {
|
|
12789
12801
|
masterVolume = clamp3(volume, 0, 100);
|
|
12790
12802
|
refs.masterVolume.value = String(masterVolume);
|
|
12791
12803
|
refs.masterVolumeLabel.textContent = `${masterVolume}%`;
|
|
12804
|
+
options.singingVoices?.setVolume(masterVolume / 100);
|
|
12792
12805
|
},
|
|
12793
12806
|
setDrumVolume: (volume) => {
|
|
12794
12807
|
drumVolume = clamp3(volume, 0, 100);
|
package/dist/index.mjs
CHANGED
|
@@ -2554,8 +2554,10 @@ var createSingingVoices = (ctx, destination, options = {}) => {
|
|
|
2554
2554
|
for (const [k, v] of Object.entries(options.voicebanks ?? {}))
|
|
2555
2555
|
catalog[k.toLowerCase()] = v;
|
|
2556
2556
|
let streamSession = 0;
|
|
2557
|
+
const masterGain = ctx.createGain();
|
|
2558
|
+
masterGain.connect(destination);
|
|
2557
2559
|
const loaded = /* @__PURE__ */ new Map([
|
|
2558
|
-
[FALLBACK_MODEL, createKlattVoice(ctx,
|
|
2560
|
+
[FALLBACK_MODEL, createKlattVoice(ctx, masterGain)]
|
|
2559
2561
|
]);
|
|
2560
2562
|
const loading = /* @__PURE__ */ new Map();
|
|
2561
2563
|
const load2 = (model) => {
|
|
@@ -2571,7 +2573,7 @@ var createSingingVoices = (ctx, destination, options = {}) => {
|
|
|
2571
2573
|
// マニフェストだけ先読みし、音素PCMは歌う直前にオンデマンド取得する
|
|
2572
2574
|
// (= 初回に .koe 全体をDLしない。モバイル初回ロードの待ちを解消)。
|
|
2573
2575
|
// Blob/File が直接渡されたケース(ローカル読み込み)はそのまま BlobVoiceSource。
|
|
2574
|
-
createKoeVoice(ctx,
|
|
2576
|
+
createKoeVoice(ctx, masterGain, {
|
|
2575
2577
|
koe,
|
|
2576
2578
|
worldlineScriptUrl: options.worldlineScriptUrl,
|
|
2577
2579
|
lightweight: options.lightweight,
|
|
@@ -2708,13 +2710,17 @@ var createSingingVoices = (ctx, destination, options = {}) => {
|
|
|
2708
2710
|
stopStream();
|
|
2709
2711
|
for (const v of loaded.values()) v.reset?.();
|
|
2710
2712
|
};
|
|
2713
|
+
const setVolume = (gain) => {
|
|
2714
|
+
masterGain.gain.value = Math.max(0, gain);
|
|
2715
|
+
};
|
|
2711
2716
|
return {
|
|
2712
2717
|
loadModels,
|
|
2713
2718
|
registerVoicebanks,
|
|
2714
2719
|
warm,
|
|
2715
2720
|
startStream,
|
|
2716
2721
|
stopStream,
|
|
2717
|
-
reset
|
|
2722
|
+
reset,
|
|
2723
|
+
setVolume
|
|
2718
2724
|
};
|
|
2719
2725
|
};
|
|
2720
2726
|
var createVoiceRegistry = (models = {}, fallback = "klatt") => {
|
|
@@ -5483,6 +5489,7 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
5483
5489
|
if (!voices) {
|
|
5484
5490
|
const ctx = ensureCtx();
|
|
5485
5491
|
voices = createSingingVoices(ctx, ctx.destination);
|
|
5492
|
+
voices.setVolume(masterVolume / 100);
|
|
5486
5493
|
}
|
|
5487
5494
|
return voices;
|
|
5488
5495
|
};
|
|
@@ -6228,6 +6235,7 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6228
6235
|
};
|
|
6229
6236
|
const setVolume = (volume) => {
|
|
6230
6237
|
masterVolume = volume;
|
|
6238
|
+
peekVoices()?.setVolume(masterVolume / 100);
|
|
6231
6239
|
};
|
|
6232
6240
|
const buildStreamTracks = () => [...lyricTracks.entries()].map(([index, lt]) => {
|
|
6233
6241
|
const seqTrack = seqTracks.find((t) => Number(t.id) === index);
|
|
@@ -6250,7 +6258,7 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6250
6258
|
return {
|
|
6251
6259
|
id: String(index),
|
|
6252
6260
|
model: lt.model,
|
|
6253
|
-
volume: vocalVolumeToGain(lt.volume ?? DEFAULT_VOCAL_VOLUME) * (trackVolume / 100)
|
|
6261
|
+
volume: vocalVolumeToGain(lt.volume ?? DEFAULT_VOCAL_VOLUME) * (trackVolume / 100),
|
|
6254
6262
|
pan: panToStereo(lt.pan ?? DEFAULT_PAN),
|
|
6255
6263
|
notes
|
|
6256
6264
|
};
|
|
@@ -6484,7 +6492,7 @@ var findZone = (ctx, fontName, zones, pitchs = []) => {
|
|
|
6484
6492
|
for (let i = zones.length - 1; i >= 0; i--)
|
|
6485
6493
|
for (const v of set) {
|
|
6486
6494
|
const zone = zones[i];
|
|
6487
|
-
if (v < zone.keyRangeLow || v > zone.keyRangeHigh
|
|
6495
|
+
if (v < zone.keyRangeLow || v > zone.keyRangeHigh) continue;
|
|
6488
6496
|
set.delete(v);
|
|
6489
6497
|
map.set(v, { ...zone });
|
|
6490
6498
|
}
|
|
@@ -6582,7 +6590,7 @@ var adjustZone = async (ctx, fontName, zone) => {
|
|
|
6582
6590
|
const oldData = oldBuf.getChannelData(ch);
|
|
6583
6591
|
const newData = newBuf.getChannelData(ch);
|
|
6584
6592
|
for (let i = 0; i < attackLength; i++) {
|
|
6585
|
-
const ratio = attackLength >
|
|
6593
|
+
const ratio = attackLength > 1 ? i / (attackLength - 1) : 0;
|
|
6586
6594
|
const m = 1 + (gainMultiplier - 1) * ratio;
|
|
6587
6595
|
newData[i] = oldData[i] * m;
|
|
6588
6596
|
}
|
|
@@ -8907,6 +8915,7 @@ var init = (mountTarget, width = 800, height = 450, config) => {
|
|
|
8907
8915
|
gridCanvas.style.left = `${KEYBOARD_WIDTH}px`;
|
|
8908
8916
|
gridCanvas.style.top = `${HEADER_HEIGHT}px`;
|
|
8909
8917
|
gridCanvas.style.touchAction = "none";
|
|
8918
|
+
gridCanvas.style.userSelect = "none";
|
|
8910
8919
|
const gridCtx = gridCanvas.getContext("2d", { willReadFrequently: true });
|
|
8911
8920
|
if (!gridCtx) throw new Error("Failed to get 2D rendering context for grid.");
|
|
8912
8921
|
g_grid_ctx = gridCtx;
|
|
@@ -9900,6 +9909,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
9900
9909
|
let zoomY = 100;
|
|
9901
9910
|
let bpm = options.defaultBpm ?? DEFAULT_BPM;
|
|
9902
9911
|
let masterVolume = options.masterVolume ?? 50;
|
|
9912
|
+
options.singingVoices?.setVolume(masterVolume / 100);
|
|
9903
9913
|
let drumVolume = options.drumVolume ?? 80;
|
|
9904
9914
|
let currentDrumPattern = refs.drumSelect.value;
|
|
9905
9915
|
let currentInstrument = "";
|
|
@@ -10777,7 +10787,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
10777
10787
|
return {
|
|
10778
10788
|
id: trackState?.config.id,
|
|
10779
10789
|
model: lt.model,
|
|
10780
|
-
volume: vocalVolumeToGain(lt.volume ?? DEFAULT_VOCAL_VOLUME)
|
|
10790
|
+
volume: vocalVolumeToGain(lt.volume ?? DEFAULT_VOCAL_VOLUME),
|
|
10781
10791
|
pan: panToStereo(lt.pan ?? DEFAULT_PAN),
|
|
10782
10792
|
notes
|
|
10783
10793
|
};
|
|
@@ -11786,6 +11796,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
11786
11796
|
refs.masterVolume.addEventListener("input", () => {
|
|
11787
11797
|
masterVolume = Number.parseInt(refs.masterVolume.value, 10) || 0;
|
|
11788
11798
|
refs.masterVolumeLabel.textContent = `${masterVolume}%`;
|
|
11799
|
+
options.singingVoices?.setVolume(masterVolume / 100);
|
|
11789
11800
|
});
|
|
11790
11801
|
refs.drumSelect.addEventListener("change", () => {
|
|
11791
11802
|
currentDrumPattern = refs.drumSelect.value;
|
|
@@ -12662,11 +12673,13 @@ var mountDAW = (target, options = {}) => {
|
|
|
12662
12673
|
masterVolume = clamp3(volume, 0, 100);
|
|
12663
12674
|
refs.masterVolume.value = String(masterVolume);
|
|
12664
12675
|
refs.masterVolumeLabel.textContent = `${masterVolume}%`;
|
|
12676
|
+
options.singingVoices?.setVolume(masterVolume / 100);
|
|
12665
12677
|
},
|
|
12666
12678
|
setVolume: (volume) => {
|
|
12667
12679
|
masterVolume = clamp3(volume, 0, 100);
|
|
12668
12680
|
refs.masterVolume.value = String(masterVolume);
|
|
12669
12681
|
refs.masterVolumeLabel.textContent = `${masterVolume}%`;
|
|
12682
|
+
options.singingVoices?.setVolume(masterVolume / 100);
|
|
12670
12683
|
},
|
|
12671
12684
|
setDrumVolume: (volume) => {
|
|
12672
12685
|
drumVolume = clamp3(volume, 0, 100);
|
package/package.json
CHANGED