cantor-digitalis 0.0.1
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/LICENSE +15 -0
- package/README.md +164 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1486 -0
- package/dist/index.js.map +1 -0
- package/dist/nodes/anti-resonance.d.ts +58 -0
- package/dist/nodes/anti-resonance.d.ts.map +1 -0
- package/dist/nodes/formant-bank.d.ts +76 -0
- package/dist/nodes/formant-bank.d.ts.map +1 -0
- package/dist/nodes/formant-resonator.d.ts +67 -0
- package/dist/nodes/formant-resonator.d.ts.map +1 -0
- package/dist/nodes/gain.d.ts +16 -0
- package/dist/nodes/gain.d.ts.map +1 -0
- package/dist/nodes/glottal-flow-derivative.d.ts +119 -0
- package/dist/nodes/glottal-flow-derivative.d.ts.map +1 -0
- package/dist/nodes/glottal-formant.d.ts +64 -0
- package/dist/nodes/glottal-formant.d.ts.map +1 -0
- package/dist/nodes/noise-source.d.ts +51 -0
- package/dist/nodes/noise-source.d.ts.map +1 -0
- package/dist/nodes/pulse-train.d.ts +51 -0
- package/dist/nodes/pulse-train.d.ts.map +1 -0
- package/dist/nodes/spectral-tilt.d.ts +69 -0
- package/dist/nodes/spectral-tilt.d.ts.map +1 -0
- package/dist/nodes/types.d.ts +10 -0
- package/dist/nodes/types.d.ts.map +1 -0
- package/dist/nodes/vocal-tract.d.ts +83 -0
- package/dist/nodes/vocal-tract.d.ts.map +1 -0
- package/dist/nodes/voice.d.ts +102 -0
- package/dist/nodes/voice.d.ts.map +1 -0
- package/dist/parameters/index.d.ts +111 -0
- package/dist/parameters/index.d.ts.map +1 -0
- package/dist/parameters/vowels.d.ts +28 -0
- package/dist/parameters/vowels.d.ts.map +1 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Edward Browncross
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
11
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
14
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
+
PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Cantor Digitalis
|
|
2
|
+
|
|
3
|
+
A Web Audio implementation of the Cantor Digitalis voice synthesizer, a physically-informed source-filter model for singing voice synthesis.
|
|
4
|
+
|
|
5
|
+
This library is an implementation of the synthesis pipeline described in [L Feugère et al., 2017](https://hal.sorbonne-universite.fr/hal-01461822v1/document). The research and signal processing design are the work of the original authors; this project provides a web-based implementation using the Web Audio API.
|
|
6
|
+
|
|
7
|
+
> Lionel Feugère, Christophe d’Alessandro, Boris Doval, Olivier Perrotin. Cantor Digitalis: chironomic
|
|
8
|
+
> parametric synthesis of singing. EURASIP Journal on Audio, Speech, and Music Processing, 2017,
|
|
9
|
+
> 22, pp.30. ff10.1186/s13636-016-0098-5ff. ffhal-01461822f
|
|
10
|
+
|
|
11
|
+
The paper also describes a stylus-based interface for real-time control of the synthesizer, which is out of the scope of this library. See the original paper for details.
|
|
12
|
+
|
|
13
|
+
## Live Demo
|
|
14
|
+
|
|
15
|
+
To hear the synthesizer in action, see the [demo app](https://edwardbrowncross.github.io/cantor-digitalis/) (source code found in example directory).
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install cantor-digitalis
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { Voice, generateSynthParams } from "cantor-digitalis";
|
|
27
|
+
|
|
28
|
+
const ctx = new AudioContext();
|
|
29
|
+
|
|
30
|
+
// Define voice parameters
|
|
31
|
+
const params = {
|
|
32
|
+
pitch: 0.5,
|
|
33
|
+
pitchOffset: 60, // MIDI note (C4)
|
|
34
|
+
vocalEffort: 0.7,
|
|
35
|
+
vowelHeight: 0.5, // 0 = close (/i/, /u/), 1 = open (/a/)
|
|
36
|
+
vowelBackness: 0.5, // 0 = back (/u/), 1 = front (/i/)
|
|
37
|
+
tenseness: 0.5,
|
|
38
|
+
breathiness: 0.02,
|
|
39
|
+
roughness: 0.01,
|
|
40
|
+
vocalTractSize: 0.3,
|
|
41
|
+
isFalsetto: false,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// Create and start the voice
|
|
45
|
+
const synthParams = generateSynthParams(params);
|
|
46
|
+
const voice = await Voice.create(ctx, synthParams);
|
|
47
|
+
voice.out.connect(ctx.destination);
|
|
48
|
+
voice.start();
|
|
49
|
+
|
|
50
|
+
// Update parameters in real-time
|
|
51
|
+
params.vowelHeight = 0.8;
|
|
52
|
+
const newSynthParams = generateSynthParams(params);
|
|
53
|
+
voice.update(newSynthParams);
|
|
54
|
+
|
|
55
|
+
// Stop when done
|
|
56
|
+
voice.stop();
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Parameter Architecture
|
|
60
|
+
|
|
61
|
+
The synthesizer uses two layers of parameters:
|
|
62
|
+
|
|
63
|
+
**Perceptual Parameters** (shown in the first table below) are high-level, intuitive controls like `pitch`, `vocalEffort`, and `vowelHeight`. These map to how we perceive and describe voices.
|
|
64
|
+
|
|
65
|
+
**Synth Parameters** are the low-level values that directly control the audio processing: fundamental frequency (`f0`), formant frequencies (`F1`–`F6`), glottal formant bandwidth (`Bg`), spectral tilt (`Tl1`, `Tl2`), etc. These correspond to the physical and acoustic properties described in the research paper.
|
|
66
|
+
|
|
67
|
+
The conversion from perceptual parameters to synth parameters is described in section 4 of the referenced paper. For most use cases, set perceptual parameters and convert these to synth parameters via `generateSynthParams()`. For lower-level control of the sound, access the synth-level parameters directly.
|
|
68
|
+
|
|
69
|
+
Additionally, the synthesizer exposes `AudioParam` objects for the synth-level parameters for sample-accurate automation. Theses can be used for sample-accurate automation (vibrato, pitch glides, amplitude envelopes etc.)
|
|
70
|
+
|
|
71
|
+
### Perceptual Parameters
|
|
72
|
+
|
|
73
|
+
| Parameter | Range | Description |
|
|
74
|
+
|-----------|-------|-------------|
|
|
75
|
+
| `pitch` | 0–1 | Normalized position within pitch range |
|
|
76
|
+
| `pitchOffset` | MIDI | Base pitch as MIDI note number |
|
|
77
|
+
| `vocalEffort` | 0–1 | Perceived loudness/force |
|
|
78
|
+
| `vowelHeight` | 0–1 | Tongue height: close to open |
|
|
79
|
+
| `vowelBackness` | 0–1 | Tongue position: back to front |
|
|
80
|
+
| `tenseness` | 0–1 | Vocal fold adduction |
|
|
81
|
+
| `breathiness` | 0–1 | Aspiration noise amount |
|
|
82
|
+
| `roughness` | 0–1 | Jitter and shimmer |
|
|
83
|
+
| `vocalTractSize` | 0–1 | Vocal tract scaling (child to giant) |
|
|
84
|
+
| `isFalsetto` | bool | Laryngeal mechanism (M1/M2) |
|
|
85
|
+
|
|
86
|
+
### Synth Parameters
|
|
87
|
+
|
|
88
|
+
These low-level parameters directly control the audio processing and correspond to the physical/acoustic properties in the research paper.
|
|
89
|
+
|
|
90
|
+
#### Voice Source
|
|
91
|
+
|
|
92
|
+
| Parameter | Symbol | Unit | Description |
|
|
93
|
+
|-----------|--------|------|-------------|
|
|
94
|
+
| `f0` | f₀ | Hz | Fundamental frequency (pitch) |
|
|
95
|
+
| `Fg` | Fg | Hz | Glottal formant centre frequency |
|
|
96
|
+
| `Bg` | Bg | Hz | Glottal formant bandwidth |
|
|
97
|
+
| `Ag` | Ag | — | Voice source amplitude |
|
|
98
|
+
| `Tl1` | Tl₁ | dB | Spectral tilt (1st stage attenuation at 3 kHz) |
|
|
99
|
+
| `Tl2` | Tl₂ | dB | Spectral tilt (2nd stage attenuation at 3 kHz) |
|
|
100
|
+
| `An` | An | — | Aspiration noise amplitude |
|
|
101
|
+
| `jitterDepth` | — | — | Pitch perturbation depth (0–0.3) |
|
|
102
|
+
| `shimmerDepth` | — | — | Amplitude perturbation depth (0–1) |
|
|
103
|
+
|
|
104
|
+
#### Vocal Tract
|
|
105
|
+
|
|
106
|
+
| Parameter | Symbol | Unit | Description |
|
|
107
|
+
|-----------|--------|------|-------------|
|
|
108
|
+
| `F` (formants[0–5]) | F1–F6 | Hz | Formant centre frequencies |
|
|
109
|
+
| `B` (formants[0–5]) | B1–B6 | Hz | Formant bandwidths |
|
|
110
|
+
| `A` (formants[0–5]) | A1–A6 | — | Formant amplitudes |
|
|
111
|
+
| `F_BQ` | F_BQ | Hz | Anti-resonance centre frequency (~4700 Hz) |
|
|
112
|
+
| `Q_BQ` | Q_BQ | — | Anti-resonance quality factor (fixed 2.5) |
|
|
113
|
+
|
|
114
|
+
## Direct AudioParam Control
|
|
115
|
+
|
|
116
|
+
For sample-accurate automation, access AudioParams directly:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
const now = ctx.currentTime;
|
|
120
|
+
|
|
121
|
+
// Pitch glide
|
|
122
|
+
voice.source.pulseTrainNode.f0.setValueAtTime(220, now);
|
|
123
|
+
voice.source.pulseTrainNode.f0.exponentialRampToValueAtTime(440, now + 0.5);
|
|
124
|
+
|
|
125
|
+
// Formant sweep
|
|
126
|
+
voice.tract.formants[0].F.linearRampToValueAtTime(800, now + 0.3);
|
|
127
|
+
|
|
128
|
+
// Amplitude envelope
|
|
129
|
+
voice.source.glottalFormantNode.Ag.setTargetAtTime(0, now, 0.1);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Component Architecture
|
|
133
|
+
|
|
134
|
+
For advanced use cases, the individual components of the synthesis pipeline can be instantiated and connected independently. Each component corresponds to a module described in the research paper.
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
Voice
|
|
138
|
+
├── source: GlottalFlowDerivative §3.2 Voice source model
|
|
139
|
+
│ ├── pulseTrainNode: PulseTrain §3.1 Periodic impulse generator
|
|
140
|
+
│ ├── glottalFormantNode: GlottalFormant §3.2.1 Glottal pulse shaping filter
|
|
141
|
+
│ ├── spectralTiltNode: SpectralTilt §3.2.2 High-frequency roll-off
|
|
142
|
+
│ └── noiseSourceNode: NoiseSource §3.2.3 Aspiration noise
|
|
143
|
+
├── tract: VocalTract §3.3 Vocal tract model
|
|
144
|
+
│ ├── formants[0–5]: FormantResonator §3.3.1 Parallel resonant filters
|
|
145
|
+
│ └── antiResonanceNode: AntiResonance §3.3.2 Hypo-pharynx notch filter
|
|
146
|
+
└── outputGain: Gain
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import { PulseTrain, FormantResonator } from "cantor-digitalis";
|
|
151
|
+
|
|
152
|
+
// Create individual components
|
|
153
|
+
const pulseTrain = await PulseTrain.create(ctx, { f0: 220, jitterDepth: 0, shimmerDepth: 0 });
|
|
154
|
+
const formant = await FormantResonator.create(ctx, { F: 500, B: 100, A: 1 });
|
|
155
|
+
|
|
156
|
+
// Connect manually
|
|
157
|
+
pulseTrain.out.connect(formant.in);
|
|
158
|
+
formant.out.connect(ctx.destination);
|
|
159
|
+
pulseTrain.start();
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## License
|
|
163
|
+
|
|
164
|
+
ISC
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cantor Digitalis - Web Voice Synthesizer
|
|
3
|
+
*
|
|
4
|
+
* A physically-informed source-filter model for singing voice synthesis
|
|
5
|
+
* using the Web Audio API.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
export { Voice } from "./nodes/voice";
|
|
10
|
+
export { generateSynthParams } from "./parameters";
|
|
11
|
+
export type { PerceptualParams, SynthParams, SynthFormant, SynthFeatures } from "./parameters";
|
|
12
|
+
export { interpolateFormants, vowels } from "./parameters/vowels";
|
|
13
|
+
export type { Formant, VowelData } from "./parameters/vowels";
|
|
14
|
+
export type { Node } from "./nodes/types";
|
|
15
|
+
export { GlottalFlowDerivative } from "./nodes/glottal-flow-derivative";
|
|
16
|
+
export type { GlottalFlowDerivativeParams } from "./nodes/glottal-flow-derivative";
|
|
17
|
+
export { VocalTract } from "./nodes/vocal-tract";
|
|
18
|
+
export type { VocalTractParams } from "./nodes/vocal-tract";
|
|
19
|
+
export { PulseTrain } from "./nodes/pulse-train";
|
|
20
|
+
export type { PulseTrainParams } from "./nodes/pulse-train";
|
|
21
|
+
export { GlottalFormant } from "./nodes/glottal-formant";
|
|
22
|
+
export type { GlottalFormantParams } from "./nodes/glottal-formant";
|
|
23
|
+
export { SpectralTilt } from "./nodes/spectral-tilt";
|
|
24
|
+
export type { SpectralTiltParams } from "./nodes/spectral-tilt";
|
|
25
|
+
export { NoiseSource } from "./nodes/noise-source";
|
|
26
|
+
export type { NoiseSourceParams } from "./nodes/noise-source";
|
|
27
|
+
export { FormantBank } from "./nodes/formant-bank";
|
|
28
|
+
export type { FormantBankParams } from "./nodes/formant-bank";
|
|
29
|
+
export { FormantResonator } from "./nodes/formant-resonator";
|
|
30
|
+
export type { FormantResonatorParams } from "./nodes/formant-resonator";
|
|
31
|
+
export { AntiResonance } from "./nodes/anti-resonance";
|
|
32
|
+
export type { AntiResonanceParams } from "./nodes/anti-resonance";
|
|
33
|
+
export { Gain } from "./nodes/gain";
|
|
34
|
+
export type { GainParams } from "./nodes/gain";
|
|
35
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAGtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAG9D,YAAY,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAG1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,YAAY,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAEnF,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,YAAY,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAEpE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,YAAY,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,YAAY,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAExE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,YAAY,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAElE,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|