@onjmin/koe 1.0.9 → 1.0.11

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.ts CHANGED
@@ -941,6 +941,12 @@ interface NjdNode {
941
941
  interface FeatureFrame {
942
942
  mora: string;
943
943
  pause: boolean;
944
+ /**
945
+ * For pause frames: the token that produced the pause (「。」「、」「?」, a
946
+ * space, a bracket…). Lets prosody rules pick a pause length per kind.
947
+ * Absent on pauses synthesised from a reading string.
948
+ */
949
+ punctuation?: string;
944
950
  accent_phrase_position?: number;
945
951
  accent_phrase_length?: number;
946
952
  accent_nucleus?: number;
@@ -952,6 +958,13 @@ interface FeatureFrame {
952
958
  pos?: string;
953
959
  pos_group1?: string;
954
960
  }
961
+ /** Pause kinds a punctuation token maps to (see {@link pauseKind}). */
962
+ type PauseKind = "sentence" | "clause" | "space";
963
+ /**
964
+ * Classify the token that produced a pause: sentence-final punctuation, a
965
+ * clause comma, or whitespace / anything else (brackets, symbols).
966
+ */
967
+ declare function pauseKind(punctuation: string | undefined): PauseKind;
955
968
  declare function analyze(nodes: NjdNode[]): {
956
969
  reading: string;
957
970
  features: FeatureFrame[];
@@ -997,6 +1010,14 @@ interface HtsProsody {
997
1010
  * (Open JTalk's upper-case `I`/`U`, e.g. the "su" in "desu"). Pauses are false.
998
1011
  */
999
1012
  devoiced: boolean[];
1013
+ /**
1014
+ * Per feature-frame HTS consonant length in ms (onset of the mora's first
1015
+ * phone to its vowel onset); 0 for pauses and vowel-initial morae. The
1016
+ * planner uses it to end the previous vowel where the consonant starts.
1017
+ */
1018
+ consonantMs: number[];
1019
+ /** Per feature-frame flag: the mora starts with an unvoiced consonant (k, s, t, h, p …). */
1020
+ unvoicedOnset: boolean[];
1000
1021
  /**
1001
1022
  * Optional per feature-frame linear gain (1 = unity) applied to the units of
1002
1023
  * that mora on top of UtauTTS's own volume; filled by `shapeProsody`.
@@ -1018,11 +1039,29 @@ interface AlignHtsOptions {
1018
1039
  */
1019
1040
  kneeCents?: number;
1020
1041
  maxCents?: number;
1042
+ /**
1043
+ * Longest unvoiced run (ms) that is bridged by interpolating F0 from the
1044
+ * voiced frame before it to the one after it. Unvoiced consonants (30–120
1045
+ * ms) are bridged; a longer run is a devoiced vowel plus a pause plus the
1046
+ * next phrase's consonant, and a ramp across it would carry the *next*
1047
+ * phrase's onset pitch back onto the devoiced mora (「ございます」 rendered
1048
+ * with a rising 「す」, since UTAU renders devoiced vowels voiced). Such
1049
+ * runs hold the previous value over their first half and the following
1050
+ * value over their second half. Default 120.
1051
+ */
1052
+ unvoicedBridgeMs?: number;
1021
1053
  }
1022
1054
  /**
1023
1055
  * Align HTS phoneme timing and F0 to the mora/pause sequence in `features`
1024
1056
  * (from `openjtalkAnalyze`). Returns null when the two mora sequences cannot
1025
1057
  * be matched, in which case the caller should fall back to the TCN contour.
1058
+ *
1059
+ * Mora boundaries are the HTS *vowel onsets*: a mora's duration runs from its
1060
+ * vowel onset to the next mora's vowel onset (so the next consonant belongs to
1061
+ * the end of this mora), which is how UtauTTS places units (note start =
1062
+ * vowel onset, consonant pre-uttered). Cutting at consonant onsets instead
1063
+ * would delay the F0 contour by one consonant (40–120 ms) relative to the
1064
+ * rendered vowels and shift every accent fall onto the following mora.
1026
1065
  */
1027
1066
  declare function alignHtsProsody(frames: HtsProsodyFrames, features: FeatureFrame[], options?: AlignHtsOptions): HtsProsody | null;
1028
1067
 
@@ -1035,15 +1074,43 @@ declare function alignHtsProsody(frames: HtsProsodyFrames, features: FeatureFram
1035
1074
  * - question rise: a sentence ending in 「?」 gets at least a minimum rise
1036
1075
  * on its last mora; Open JTalk's interrogative label flag already makes
1037
1076
  * tohoku-f01 rise, so this only tops up voices/sentences that do not
1038
- * - energy envelope: loudness follows pitch (accented morae louder, phrase
1039
- * ends softer), which a plain unit concatenation renders flat
1077
+ * - energy envelope (off by default, see `energyDbPerSemitone`): loudness
1078
+ * follows pitch per mora; the renderer now does this smoothly per frame
1040
1079
  * - devoiced vowels: morae HTS predicted as devoiced (「です」「ます」…) are
1041
1080
  * attenuated so the voiced sample does not shout a vowel the speaker
1042
1081
  * would whisper
1082
+ * - pause length by punctuation: the HTS voice was trained on single
1083
+ * sentences, so it gives 「。」 and 「、」 the same ~300 ms; a reading voice
1084
+ * pauses roughly twice as long at a sentence end
1085
+ * - duration contrast: HTS durations are variance-shrunk (over-smoothed);
1086
+ * stretching them around the utterance mean restores some of the
1087
+ * short-particle / long-final-mora rhythm of natural speech
1043
1088
  *
1044
1089
  * Zero assets, negligible compute; everything is mora-level arithmetic.
1045
1090
  */
1046
1091
  interface ShapeProsodyOptions {
1092
+ /**
1093
+ * Minimum pause length in ms per pause kind (see `pauseKind`); the HTS
1094
+ * pause is kept when it is already longer. The utterance-final pause is
1095
+ * left alone. `null` disables the rule. Defaults: sentence 650, clause 380,
1096
+ * space 500.
1097
+ */
1098
+ pauseMs?: Partial<Record<PauseKind, number>> | null;
1099
+ /**
1100
+ * Expansion of spoken-mora durations around the utterance mean:
1101
+ * `mean + (d − mean) × contrast`. 1 keeps HTS as-is. Default 1.3.
1102
+ */
1103
+ durationContrast?: number;
1104
+ /** Floor for a spoken mora after contrast expansion, in ms. Default 60. */
1105
+ minMoraMs?: number;
1106
+ /**
1107
+ * A mora is never shortened below this fraction of its HTS duration by the
1108
+ * contrast expansion (short morae such as devoiced 「く」 are already at
1109
+ * their minimum). Default 0.85.
1110
+ */
1111
+ minShrink?: number;
1112
+ /** Baseline pitch shift added to the whole curve, in cents. Default 0. */
1113
+ pitchShiftCents?: number;
1047
1114
  /** Treat the utterance as a question (see {@link isQuestion}). Default false. */
1048
1115
  question?: boolean;
1049
1116
  /**
@@ -1055,11 +1122,19 @@ interface ShapeProsodyOptions {
1055
1122
  */
1056
1123
  questionRiseCents?: number;
1057
1124
  /**
1058
- * Loudness coupling: dB per 100 cents of pitch relative to the speaker
1059
- * median. 0 disables the energy envelope. Default 0.5 (≈ +2 dB at +400 cent).
1125
+ * Per-mora loudness coupling: dB per 100 cents of pitch relative to the
1126
+ * speaker median, applied as a step per mora through `moraGains`. Default
1127
+ * 0: `UtauTTSAdapter.renderChunks` applies the same coupling as a smooth
1128
+ * per-frame curve (`energyDbPerSemitone` there), which avoids level steps
1129
+ * at the mora joins. Set this when rendering through something else.
1060
1130
  */
1061
1131
  energyDbPerSemitone?: number;
1062
- /** Linear gain for morae with a devoiced nucleus. Default 0.5 (−6 dB). */
1132
+ /**
1133
+ * Linear gain for morae with a devoiced nucleus, applied to the whole unit
1134
+ * through `moraGains`. Default 1: `UtauTTSAdapter.renderChunks` attenuates
1135
+ * only the vowel part of a devoiced mora (`devoicedDb`), keeping the
1136
+ * consonant burst audible; set this when rendering through something else.
1137
+ */
1063
1138
  devoicedGain?: number;
1064
1139
  /** Clamp for the per-mora gain. Defaults 0.35 … 1.8. */
1065
1140
  minGain?: number;
@@ -1067,6 +1142,17 @@ interface ShapeProsodyOptions {
1067
1142
  }
1068
1143
  /** True when the text ends with a question mark (「?」 or "?"), ignoring closing quotes. */
1069
1144
  declare function isQuestion(text: string): boolean;
1145
+ /**
1146
+ * New per-frame durations: pauses lengthened by kind, spoken morae expanded
1147
+ * around the mean. Pure; returns `durations` itself when nothing changes.
1148
+ */
1149
+ declare function shapeDurations(durations: number[], features: FeatureFrame[], options?: Pick<ShapeProsodyOptions, "pauseMs" | "durationContrast" | "minMoraMs" | "minShrink">): number[];
1150
+ /**
1151
+ * Re-time a cents curve from the `from` durations to the `to` durations with
1152
+ * a piecewise-linear warp (each frame keeps its own contour, stretched or
1153
+ * squeezed to its new length). Frame period unchanged.
1154
+ */
1155
+ declare function warpPitchCurve(cents: number[], frameMs: number, from: number[], to: number[]): number[];
1070
1156
  /**
1071
1157
  * Apply the residual rules to an aligned HTS prosody. Returns a new object;
1072
1158
  * `prosody` is not modified. Pass the result to `plan({ prosody })`: the pitch
@@ -1125,6 +1211,8 @@ interface UtauTTSTimelineUnit {
1125
1211
  x_ms: number;
1126
1212
  y: number;
1127
1213
  }[];
1214
+ /** Set by `UtauTTSAdapter.plan` from `HtsProsody.devoiced`: the nucleus is a devoiced vowel. */
1215
+ devoiced?: boolean;
1128
1216
  }
1129
1217
  /** Whole-phrase placement + F0 curve (`render.WorldlineTimeline`). */
1130
1218
  interface UtauTTSTimeline {
@@ -1215,6 +1303,54 @@ interface UtauTTSRenderOptions {
1215
1303
  chunkUnits?: number;
1216
1304
  /** Crossfade length at a mid-phrase seam in ms. Default 20. */
1217
1305
  seamCrossfadeMs?: number;
1306
+ /**
1307
+ * Even out the loudness of the rendered units. worldline normalises every
1308
+ * unit's level internally (the sample's own level does not reach the
1309
+ * output), but the vowel RMS that comes out still differs by several dB
1310
+ * from unit to unit, which a listener hears as an uneven, choppy line.
1311
+ * Each unit's vowel RMS (middle 35–90 % of its mora) is measured on the
1312
+ * rendered audio and pulled towards `unitLoudnessDb` by a gain curve
1313
+ * interpolated between mora centres, so there is no step at the joins. The
1314
+ * prosodic volume of the unit (accent loudness, devoicing) is kept.
1315
+ * Default true.
1316
+ */
1317
+ normalizeUnitLoudness?: boolean;
1318
+ /**
1319
+ * Reference vowel RMS in dBFS. Because worldline normalises every unit,
1320
+ * the rendered vowel level is bank-independent (≈ −15 dBFS median for a
1321
+ * 単独音 bank at volume 100), so an absolute reference works and keeps the
1322
+ * chunks of a streamed utterance consistent. Default −16.
1323
+ */
1324
+ unitLoudnessDb?: number;
1325
+ /** Largest correction applied to a unit, in dB. Default 6. */
1326
+ unitLoudnessMaxDb?: number;
1327
+ /**
1328
+ * Energy contour: loudness follows the F0 curve, in dB per semitone from
1329
+ * the utterance's median F0, applied as a smooth per-frame gain on the
1330
+ * rendered audio (the accent peak is louder, the phrase end softer, as in
1331
+ * natural speech, where a read sentence loses 10–15 dB over the phrase).
1332
+ * A plain unit concatenation renders every mora at the same level, which
1333
+ * is heard as a bumpy, mechanical line. 0 disables. Default 0.8.
1334
+ */
1335
+ energyDbPerSemitone?: number;
1336
+ /** Clamp for the energy contour, in dB. Default 6. */
1337
+ energyMaxDb?: number;
1338
+ /**
1339
+ * Attenuation of the vowel part of a devoiced mora (Open JTalk's 「です」
1340
+ * 「ます」 「あくた」…), in dB, applied from the vowel onset to the next
1341
+ * unit's consonant so the consonant burst of the devoiced mora itself stays
1342
+ * at full level (attenuating the whole unit made 「あくた」 sound like
1343
+ * 「あた」). 0 disables. Default −9.
1344
+ */
1345
+ devoicedDb?: number;
1346
+ /**
1347
+ * Soft limiter on the rendered audio: samples above this linear level are
1348
+ * compressed smoothly towards full scale (tanh knee). worldline's output
1349
+ * already peaks close to 0 dBFS with a plain plan, and the prosodic gains
1350
+ * push single vowels over; this keeps them from hard-clipping in the
1351
+ * AudioContext. 0 disables. Default 0.8.
1352
+ */
1353
+ outputLimit?: number;
1218
1354
  signal?: AbortSignal;
1219
1355
  gender?: number;
1220
1356
  tension?: number;
@@ -1289,4 +1425,51 @@ declare class UtauTTSAdapter {
1289
1425
  synthesizeText(bank: VoiceBank, text: string, features: FeatureFrame[], options?: UtauTTSOptions & UtauTTSRenderOptions): Promise<Float32Array | null>;
1290
1426
  }
1291
1427
 
1292
- export { type AlignHtsOptions, type AssetFetchOptions, type AssetProgress, type ConsonantClass, type FeatureFrame, type FileResult, type Frames, type FrqData, type GenerateOptions, type GenerateResult, type Grid, type HtsPhoneme, type HtsProsody, type HtsProsodyFrames, type JpreprocessModule, KoeEngine, type KoeEngineOptions, MIN_WORLDLINE_SAMPLES, type Manifest, type MoraPosition, NAIST_JDIC_FILES, type NaistJdicData, type NjdNode, type NoteEvent, type OtoEntry, type PackInput, type PackOutput, type PhonemeEntry, type PlayOptions, type RenderNoteParams, type ShapeProsodyOptions, type SkippedFile, type Syllable, type TrimmedPhoneme, UtauTTSAdapter, type UtauTTSChunk, type UtauTTSOptions, type UtauTTSPlan, type UtauTTSRenderOptions, type UtauTTSTimeline, type UtauTTSTimelineUnit, type UtauTTSUnit, VoiceBank, WORLDLINE_SAMPLE_RATE, type WavData, type WavInput, Worldline, type WorldlineLoadOptions, type ZipFile, alignHtsProsody, analyze$1 as analyze, analyzeWav, detectF0, detectGrid, encodeOto, encodeShiftJis, estimateSequence, estimateSolo, estimateVowelJoin, fetchAsset, fetchAssetBytes, fetchAssetText, formatOto, frqAverageF0InRange, frqFileName, generateOto, generateOtoForFile, initJpreprocessDictionary, isQuestion, leadInFromEntry, loadNaistJdic, locateMora, normalizePcm, noteNameToHz, analyze as openjtalkAnalyze, otoRegion, pack, packKoe, parseFrq, parseFrqAverageF0, parseKoeHeader, parseOto, parseWav, pcmBase, pitchFromAliasSuffix, readWavPcm48k, readingFromFeatures, resample, samplesToMs, shapeProsody, sparse_features, splitKana, suffixFromFolderName, summarise, toHiragana, toInt16, toMono, transcribe, trimToOto, unzipToFileMap, zipFiles };
1428
+ /**
1429
+ * Speaking style: the handful of global knobs the pipeline already has,
1430
+ * bundled so an application can offer "calm / neutral / lively" (or map an
1431
+ * emotion label onto them) without knowing which stage each knob lives in.
1432
+ *
1433
+ * Nothing here needs assets or compute: `speed` goes to
1434
+ * `analyze_prosody(text, speed)`, `intonation` to `alignHtsProsody`,
1435
+ * `pauseScale` / `durationContrast` / `pitchShiftCents` to `shapeProsody`,
1436
+ * `energyDbPerSemitone` to `renderChunks`. A different HTS voice (tohoku-f01
1437
+ * ships happy / sad / angry variants next to neutral) changes the phoneme
1438
+ * durations and F0 themselves and composes with these knobs.
1439
+ */
1440
+ interface SpeakingStyle {
1441
+ /** HTS speaking rate; 1 = the voice model's own rate (~7 morae/s for tohoku-f01). */
1442
+ speed: number;
1443
+ /** F0 excursion scale (`AlignHtsOptions.intonationStrength`). */
1444
+ intonation: number;
1445
+ /** Baseline pitch shift in cents, added to the whole F0 curve. */
1446
+ pitchShiftCents: number;
1447
+ /** Multiplier on the punctuation pause minimums (「。」650 / 「、」380 / space 500 ms at 1). */
1448
+ pauseScale: number;
1449
+ /** Mora-duration contrast expansion around the mean (`ShapeProsodyOptions.durationContrast`). */
1450
+ durationContrast: number;
1451
+ /** Loudness contour strength in dB per semitone (`UtauTTSRenderOptions.energyDbPerSemitone`). */
1452
+ energyDbPerSemitone: number;
1453
+ }
1454
+ type SpeakingStyleName = "neutral" | "calm" | "lively";
1455
+ /**
1456
+ * Presets. `neutral` is the pipeline's defaults; `calm` is a reading /
1457
+ * narration pace (slower, longer sentence pauses, gentler dynamics, slightly
1458
+ * lower baseline); `lively` is the opposite. Values are starting points meant
1459
+ * to be tuned by ear.
1460
+ */
1461
+ declare const SPEAKING_STYLES: Record<SpeakingStyleName, SpeakingStyle>;
1462
+ /** A preset name, or a preset name plus overrides, or a full/partial style over `neutral`. */
1463
+ type SpeakingStyleInput = SpeakingStyleName | (Partial<SpeakingStyle> & {
1464
+ preset?: SpeakingStyleName;
1465
+ });
1466
+ /** Resolve a style input to a complete {@link SpeakingStyle}. */
1467
+ declare function resolveSpeakingStyle(input?: SpeakingStyleInput): SpeakingStyle;
1468
+ /** Options for `alignHtsProsody` that follow the style. */
1469
+ declare function styleAlignOptions(style: SpeakingStyle): AlignHtsOptions;
1470
+ /** Options for `shapeProsody` that follow the style (merge your own, e.g. `question`, on top). */
1471
+ declare function styleShapeOptions(style: SpeakingStyle): ShapeProsodyOptions;
1472
+ /** Options for `renderChunks` / `synthesizeText` that follow the style. */
1473
+ declare function styleRenderOptions(style: SpeakingStyle): UtauTTSRenderOptions;
1474
+
1475
+ export { type AlignHtsOptions, type AssetFetchOptions, type AssetProgress, type ConsonantClass, type FeatureFrame, type FileResult, type Frames, type FrqData, type GenerateOptions, type GenerateResult, type Grid, type HtsPhoneme, type HtsProsody, type HtsProsodyFrames, type JpreprocessModule, KoeEngine, type KoeEngineOptions, MIN_WORLDLINE_SAMPLES, type Manifest, type MoraPosition, NAIST_JDIC_FILES, type NaistJdicData, type NjdNode, type NoteEvent, type OtoEntry, type PackInput, type PackOutput, type PauseKind, type PhonemeEntry, type PlayOptions, type RenderNoteParams, SPEAKING_STYLES, type ShapeProsodyOptions, type SkippedFile, type SpeakingStyle, type SpeakingStyleInput, type SpeakingStyleName, type Syllable, type TrimmedPhoneme, UtauTTSAdapter, type UtauTTSChunk, type UtauTTSOptions, type UtauTTSPlan, type UtauTTSRenderOptions, type UtauTTSTimeline, type UtauTTSTimelineUnit, type UtauTTSUnit, VoiceBank, WORLDLINE_SAMPLE_RATE, type WavData, type WavInput, Worldline, type WorldlineLoadOptions, type ZipFile, alignHtsProsody, analyze$1 as analyze, analyzeWav, detectF0, detectGrid, encodeOto, encodeShiftJis, estimateSequence, estimateSolo, estimateVowelJoin, fetchAsset, fetchAssetBytes, fetchAssetText, formatOto, frqAverageF0InRange, frqFileName, generateOto, generateOtoForFile, initJpreprocessDictionary, isQuestion, leadInFromEntry, loadNaistJdic, locateMora, normalizePcm, noteNameToHz, analyze as openjtalkAnalyze, otoRegion, pack, packKoe, parseFrq, parseFrqAverageF0, parseKoeHeader, parseOto, parseWav, pauseKind, pcmBase, pitchFromAliasSuffix, readWavPcm48k, readingFromFeatures, resample, resolveSpeakingStyle, samplesToMs, shapeDurations, shapeProsody, sparse_features, splitKana, styleAlignOptions, styleRenderOptions, styleShapeOptions, suffixFromFolderName, summarise, toHiragana, toInt16, toMono, transcribe, trimToOto, unzipToFileMap, warpPitchCurve, zipFiles };