Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Notitie
Als u de landinstellingen wilt verkennen die worden ondersteund voor viseme-id's en vormen wilt combineren, raadpleegt u de lijst met alle ondersteunde landinstellingen. Scalable Vector Graphics (SVG) wordt alleen ondersteund voor de en-US landinstelling.
Een viseme is de visuele beschrijving van een phoneme in gesproken taal. Het definieert de positie van het gezicht en de mond terwijl een persoon spreekt. Elk viseme toont de belangrijkste gezichtsuitdrukkingen voor een specifieke set fonemen.
U kunt visemes gebruiken om de beweging van 2D- en 3D avatarmodellen te beheren, zodat de gezichtsposities het best zijn afgestemd op synthetische spraak. U kunt bijvoorbeeld:
- Maak een virtuele spraakassistent met animatie voor intelligente kiosken en bouw geïntegreerde services voor uw klanten met meerdere modussen.
- Bouw meeslepende nieuwsuitzendingen en verbeter de ervaringen van het publiek met natuurlijke gezichts- en mondbewegingen.
- Genereer interactieve gaming avatars en cartoon personages die kunnen spreken met dynamische inhoud.
- Maak effectievere video's voor taalonderwijs die taalleerders helpen het mondgedrag van elk woord en telefoonme te begrijpen.
- Mensen met gehoorverlies kunnen ook geluiden visueel ontvangen en de spraakinhoud aflezen van zichtbare visemen op een geanimeerd gezicht.
Bekijk deze inleidende video voor meer informatie over visemes.
Algemene werkstroom voor het produceren van viseme met spraak
Neurale tekst naar spraak (Neural TTS) zet invoertekst of SSML (Speech Synthesis Markup Language) om in gesynthetiseerde levensechte spraak. Spraakaudio-uitvoer kan worden vergezeld door viseme-id, Scalable Vector Graphics (SVG) of vormen met elkaar combineren. Met behulp van een 2D- of 3D-renderingengine kunt u deze viseme-gebeurtenissen gebruiken om uw avatar te animeren.
De algemene werkstroom van viseme wordt weergegeven in het volgende stroomdiagram:
Viseme-ID
Viseme-ID betekent een geheel getal dat een viseme specificeert. Wij bieden 22 verschillende visemen aan, die elk de mondpositie voor een specifieke set van fonemen weergeven. Er is geen een-op-een-correspondentie tussen visemen en foneemen. Vaak komen meerdere fonemen overeen met één viseme, omdat ze er hetzelfde uitzien op het gezicht van de spreker bij het uitspreken, zoals s en z. Zie de tabel voor het toewijzen van fonemen aan viseme-ID's voor meer specifieke informatie.
Spraakaudio-uitvoer kan worden vergezeld met viseme-id's en Audio offset. De Audio offset geeft de offsettijdstempel aan die de begintijd van elk viseme vertegenwoordigt, in tikken (100 nanoseconden).
Fonemen toewijzen aan visemen
Visemes verschillen per taal en landinstelling. Elke taalinstelling heeft een set visemen die corresponderen met de specifieke fonemen. De SSML-fonetische alfabetten documentatie mapt viseme-ID's naar de corresponderende IPA-fonemen (International Phonetic Alphabet). In de tabel in deze sectie ziet u een toewijzingsrelatie tussen viseme-id's en mondposities, met typische IPA-phonemes voor elke viseme-id.
| Viseme-ID | IPA | Mondpositie |
|---|---|---|
| 0 | Stilte |
|
| 1 |
æ, ə, ʌ |
|
| 2 | ɑ |
|
| 3 | ɔ |
|
| 4 |
ɛ, ʊ |
|
| 5 | ɝ |
|
| 6 |
j, i, ɪ |
|
| 7 |
w, u |
|
| 8 | o |
|
| 9 | aʊ |
|
| 10 | ɔɪ |
|
| 11 | aɪ |
|
| 12 | h |
|
| 13 | ɹ |
|
| 14 | l |
|
| 15 |
s, z |
|
| 16 |
ʃ, tʃ, dʒ, ʒ |
|
| zeventien | ð |
|
| 18 |
f, v |
|
| 19 |
d, t, n, θ |
|
| 20 |
k, g, ŋ |
|
| 21 |
p, b, m |
|
2D SVG-animatie
Voor 2D-tekens kunt u een teken ontwerpen dat bij uw scenario past en SVG (Scalable Vector Graphics) gebruiken voor elke viseme-id om een op tijd gebaseerde gezichtspositie te krijgen.
Met tijdelijke tags die worden geleverd in een viseme-gebeurtenis, worden deze goed ontworpen SVG's verwerkt met vloeiende wijzigingen en bieden ze een robuuste animatie aan de gebruikers. In de volgende afbeelding ziet u bijvoorbeeld een karakter met rode lippen dat is ontworpen voor taalleren.
Animatie van 3D-vormen combineren
U kunt blendshapes gebruiken om de gezichtsbewegingen van een 3D-personage dat u hebt ontworpen, te besturen.
De JSON-tekenreeks voor mixshapes wordt weergegeven als een tweedimensionale matrix. Elke rij vertegenwoordigt een frame. Elk frame (in 60 FPS) bevat een matrix van 55 gezichtsposities.
Viseme-gebeurtenissen ophalen met de Speech SDK
Als u zicht wilt krijgen op uw gesynthetiseerde spraak, abonneert u zich op de gebeurtenis in de VisemeReceived Speech SDK.
Notitie
Als u uitvoer van SVG- of blendshapes wilt aanvragen, moet u het mstts:viseme element in SSML gebruiken. Zie voor meer informatie het viseme-element in SSML gebruiken.
In het volgende codefragment ziet u hoe u zich kunt abonneren op de viseme-gebeurtenis:
using (var synthesizer = new SpeechSynthesizer(speechConfig, audioConfig))
{
// Subscribes to viseme received event
synthesizer.VisemeReceived += (s, e) =>
{
Console.WriteLine($"Viseme event received. Audio offset: " +
$"{e.AudioOffset / 10000}ms, viseme id: {e.VisemeId}.");
// `Animation` is an xml string for SVG or a json string for blend shapes
var animation = e.Animation;
};
// If VisemeID is the only thing you want, you can also use `SpeakTextAsync()`
var result = await synthesizer.SpeakSsmlAsync(ssml);
}
auto synthesizer = SpeechSynthesizer::FromConfig(speechConfig, audioConfig);
// Subscribes to viseme received event
synthesizer->VisemeReceived += [](const SpeechSynthesisVisemeEventArgs& e)
{
cout << "viseme event received. "
// The unit of e.AudioOffset is tick (1 tick = 100 nanoseconds), divide by 10,000 to convert to milliseconds.
<< "Audio offset: " << e.AudioOffset / 10000 << "ms, "
<< "viseme id: " << e.VisemeId << "." << endl;
// `Animation` is an xml string for SVG or a json string for blend shapes
auto animation = e.Animation;
};
// If VisemeID is the only thing you want, you can also use `SpeakTextAsync()`
auto result = synthesizer->SpeakSsmlAsync(ssml).get();
SpeechSynthesizer synthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
// Subscribes to viseme received event
synthesizer.VisemeReceived.addEventListener((o, e) -> {
// The unit of e.AudioOffset is tick (1 tick = 100 nanoseconds), divide by 10,000 to convert to milliseconds.
System.out.print("Viseme event received. Audio offset: " + e.getAudioOffset() / 10000 + "ms, ");
System.out.println("viseme id: " + e.getVisemeId() + ".");
// `Animation` is an xml string for SVG or a json string for blend shapes
String animation = e.getAnimation();
});
// If VisemeID is the only thing you want, you can also use `SpeakTextAsync()`
SpeechSynthesisResult result = synthesizer.SpeakSsmlAsync(ssml).get();
speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=audio_config)
def viseme_cb(evt):
print("Viseme event received: audio offset: {}ms, viseme id: {}.".format(
evt.audio_offset / 10000, evt.viseme_id))
# `Animation` is an xml string for SVG or a json string for blend shapes
animation = evt.animation
# Subscribes to viseme received event
speech_synthesizer.viseme_received.connect(viseme_cb)
# If VisemeID is the only thing you want, you can also use `speak_text_async()`
result = speech_synthesizer.speak_ssml_async(ssml).get()
var synthesizer = new SpeechSDK.SpeechSynthesizer(speechConfig, audioConfig);
// Subscribes to viseme received event
synthesizer.visemeReceived = function (s, e) {
window.console.log("(Viseme), Audio offset: " + e.audioOffset / 10000 + "ms. Viseme ID: " + e.visemeId);
// `Animation` is an xml string for SVG or a json string for blend shapes
var animation = e.animation;
}
// If VisemeID is the only thing you want, you can also use `speakTextAsync()`
synthesizer.speakSsmlAsync(ssml);
SPXSpeechSynthesizer *synthesizer =
[[SPXSpeechSynthesizer alloc] initWithSpeechConfiguration:speechConfig
audioConfiguration:audioConfig];
// Subscribes to viseme received event
[synthesizer addVisemeReceivedEventHandler: ^ (SPXSpeechSynthesizer *synthesizer, SPXSpeechSynthesisVisemeEventArgs *eventArgs) {
NSLog(@"Viseme event received. Audio offset: %fms, viseme id: %lu.", eventArgs.audioOffset/10000., eventArgs.visemeId);
// `Animation` is an xml string for SVG or a json string for blend shapes
NSString *animation = eventArgs.Animation;
}];
// If VisemeID is the only thing you want, you can also use `SpeakText`
[synthesizer speakSsml:ssml];
Hier volgt een voorbeeld van de viseme-uitvoer.
(Viseme), Viseme ID: 1, Audio offset: 200ms.
(Viseme), Viseme ID: 5, Audio offset: 850ms.
……
(Viseme), Viseme ID: 13, Audio offset: 2350ms.
Nadat u de viseme-uitvoer hebt verkregen, kunt u deze gebeurtenissen gebruiken om tekenanimatie aan te sturen. U kunt uw eigen tekens bouwen en deze automatisch animeren.