Spraaksynthese van tekst
Referentiedocumentatiepakket (NuGet) | Aanvullende voorbeelden op GitHub |
In deze handleiding leert u algemene ontwerppatronen voor het uitvoeren van tekst-naar-spraaksynthese.
Zie Wat is tekst naar spraak voor meer informatie over de volgende gebieden ?
- Antwoorden krijgen als in-memory streams.
- Voorbeeldsnelheid en bitsnelheid van uitvoer aanpassen.
- Syntheseaanvragen verzenden met behulp van Speech Synthesis Markup Language (SSML).
- Neurale stemmen gebruiken.
- Abonneren op gebeurtenissen en reageren op resultaten.
Synthesetaal en spraak selecteren
De functie tekst-naar-spraak in de Speech-service ondersteunt meer dan 400 stemmen en meer dan 140 talen en varianten. U kunt de volledige lijst ophalen of ze uitproberen in de spraakgalerie.
Geef de taal of stem op van SpeechConfig
uw invoertekst en gebruik de opgegeven stem. In het volgende codefragment ziet u hoe deze techniek werkt:
static async Task SynthesizeAudioAsync()
{
var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
// Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
speechConfig.SpeechSynthesisLanguage = "en-US";
speechConfig.SpeechSynthesisVoiceName = "en-US-AvaMultilingualNeural";
}
Alle neurale stemmen zijn meertalige en vloeiende taal en Engels. Als de invoertekst in het Engels bijvoorbeeld 'Ik ben enthousiast om tekst naar spraak te proberen' is en u selecteert es-ES-ElviraNeural
, wordt de tekst in het Engels gesproken met een Spaans accent.
Als de stem de taal van de invoertekst niet spreekt, maakt de Speech-service geen gesynthetiseerde audio. Zie Taal- en spraakondersteuning voor de Speech-service voor een volledige lijst met ondersteunde neurale stemmen.
Notitie
De standaardstem is de eerste stem die per landinstelling wordt geretourneerd vanuit de Voice List-API.
De stem die spreekt, wordt als volgt bepaald in volgorde van prioriteit:
- Als u dit niet instelt
SpeechSynthesisVoiceName
ofSpeechSynthesisLanguage
, wordt de standaardstem vooren-US
gesproken tekst gebruikt. - Als u alleen instelt
SpeechSynthesisLanguage
, spreekt de standaardstem voor de opgegeven landinstelling. - Als beide
SpeechSynthesisVoiceName
zijnSpeechSynthesisLanguage
ingesteld, wordt deSpeechSynthesisLanguage
instelling genegeerd. De stem die u opgeeft met behulp vanSpeechSynthesisVoiceName
spreekt. - Als het spraakelement is ingesteld met behulp van Speech Synthesis Markup Language (SSML), worden de
SpeechSynthesisVoiceName
enSpeechSynthesisLanguage
instellingen genegeerd.
Samengevat kan de volgorde van prioriteit worden beschreven als:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Resultaat |
---|---|---|---|
✗ | ✗ | ✗ | Standaardstem voor en-US spreken |
✗ | ✔ | ✗ | Standaardstem voor de opgegeven landinstelling spreekt. |
✔ | ✔ | ✗ | De stem die u opgeeft met behulp van SpeechSynthesisVoiceName spreekt. |
✔ | ✔ | ✔ | De stem die u opgeeft met behulp van SSML spreekt. |
Spraak synthetiseren naar een bestand
Maak een SpeechSynthesizer-object . Dit object dat wordt weergegeven in de volgende codefragmenten voert tekst uit naar spraakconversies en uitvoer naar luidsprekers, bestanden of andere uitvoerstromen. SpeechSynthesizer
accepteert als parameters:
- Het SpeechConfig-object dat u in de vorige stap hebt gemaakt.
- Een AudioConfig-object dat aangeeft hoe uitvoerresultaten moeten worden verwerkt.
Maak een
AudioConfig
exemplaar om de uitvoer automatisch naar een .wav-bestand te schrijven met behulp van deFromWavFileOutput()
functie. Instantieer het met eenusing
instructie.static async Task SynthesizeAudioAsync() { var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion"); using var audioConfig = AudioConfig.FromWavFileOutput("path/to/write/file.wav"); }
Met een
using
-instructie in deze context worden niet-beheerde resources automatisch verwijderd en wordt het object na verwijdering buiten gebruik gesteld.Instantieer een
SpeechSynthesizer
exemplaar met een andereusing
instructie. Geef uwspeechConfig
object en hetaudioConfig
object door als parameters. Als u spraak wilt omzetten en naar een bestand wilt schrijven, voert u deze uitSpeakTextAsync()
met een tekenreeks tekst.
static async Task SynthesizeAudioAsync()
{
var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
using var audioConfig = AudioConfig.FromWavFileOutput("path/to/write/file.wav");
using var speechSynthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
await speechSynthesizer.SpeakTextAsync("I'm excited to try text to speech");
}
Wanneer u het programma uitvoert, wordt er een gesynthetiseerd .wav-bestand gemaakt, dat wordt geschreven naar de locatie die u opgeeft. Dit resultaat is een goed voorbeeld van het meest eenvoudige gebruik. Vervolgens kunt u de uitvoer aanpassen en het uitvoerantwoord verwerken als een stroom in het geheugen voor het werken met aangepaste scenario's.
Synthetiseren naar de uitvoer van de luidspreker
Als u gesynthetiseerde spraak wilt uitvoeren naar het huidige actieve uitvoerapparaat zoals een luidspreker, laat u de AudioConfig
parameter weg wanneer u het SpeechSynthesizer
exemplaar maakt. Hier volgt een voorbeeld:
static async Task SynthesizeAudioAsync()
{
var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
using var speechSynthesizer = new SpeechSynthesizer(speechConfig);
await speechSynthesizer.SpeakTextAsync("I'm excited to try text to speech");
}
Een resultaat ophalen als een stroom in het geheugen
U kunt de resulterende audiogegevens gebruiken als een in-memory stream in plaats van rechtstreeks naar een bestand te schrijven. Met een in-memory stream kunt u aangepast gedrag bouwen:
- Abstract de resulterende bytematrix als een zoekbare stroom voor aangepaste downstreamservices.
- Integreer het resultaat met andere API's of services.
- Wijzig de audiogegevens, schrijf aangepaste .wav headers en voer gerelateerde taken uit.
U kunt deze wijziging aanbrengen in het vorige voorbeeld. Verwijder eerst het AudioConfig
blok, omdat u het uitvoergedrag vanaf dit punt handmatig beheert voor meer controle. Geef null
deze door AudioConfig
in de SpeechSynthesizer
constructor.
Notitie
Het doorgeven null
voor AudioConfig
, in plaats van deze weg te laten zoals in het vorige voorbeeld van de luidsprekeruitvoer, speelt de audio niet standaard af op het huidige actieve uitvoerapparaat.
Sla het resultaat op in een SpeechSynthesisResult-variabele . De AudioData
eigenschap bevat een byte []
exemplaar voor de uitvoergegevens. U kunt met dit byte []
exemplaar handmatig werken of u kunt de Klasse AudioDataStream gebruiken om de stroom in het geheugen te beheren.
In dit voorbeeld gebruikt u de AudioDataStream.FromResult()
statische functie om een stroom op te halen uit het resultaat:
static async Task SynthesizeAudioAsync()
{
var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
using var speechSynthesizer = new SpeechSynthesizer(speechConfig, null);
var result = await speechSynthesizer.SpeakTextAsync("I'm excited to try text to speech");
using var stream = AudioDataStream.FromResult(result);
}
Op dit moment kunt u elk aangepast gedrag implementeren met behulp van het resulterende stream
object.
Audio-indeling aanpassen
U kunt kenmerken voor audio-uitvoer aanpassen, waaronder:
- Audiobestandstype
- Samplefrequentie
- Bitdiepte
Als u de audio-indeling wilt wijzigen, gebruikt u de functie SetSpeechSynthesisOutputFormat()
op het SpeechConfig
-object. Deze functie verwacht een exemplaar van het enum
type SpeechSynthesisOutputFormat. Gebruik de enum
optie om de uitvoerindeling te selecteren. Zie de lijst met audio-indelingen voor beschikbare indelingen.
Er zijn verschillende opties voor verschillende bestandstypen, afhankelijk van uw vereisten. Onbewerkte indelingen Raw24Khz16BitMonoPcm
bevatten standaard geen audioheaders. Gebruik onbewerkte indelingen alleen in een van deze situaties:
- U weet dat uw downstream-implementatie een onbewerkte bitstream kan decoderen.
- U bent van plan om handmatig headers te bouwen op basis van factoren zoals bitdiepte, samplefrequentie en aantal kanalen.
In dit voorbeeld wordt de RIFF-indeling Riff24Khz16BitMonoPcm
met hoge kwaliteit opgegeven door het object in te SpeechConfig
stellenSpeechSynthesisOutputFormat
. Net als in het voorbeeld in de vorige sectie gebruikt u AudioDataStream om een stroom in het geheugen van het resultaat op te halen en vervolgens naar een bestand te schrijven.
static async Task SynthesizeAudioAsync()
{
var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
speechConfig.SetSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm);
using var speechSynthesizer = new SpeechSynthesizer(speechConfig, null);
var result = await speechSynthesizer.SpeakTextAsync("I'm excited to try text to speech");
using var stream = AudioDataStream.FromResult(result);
await stream.SaveToWaveFileAsync("path/to/write/file.wav");
}
Wanneer u het programma uitvoert, wordt er een .wav-bestand naar het opgegeven pad geschreven.
SSML gebruiken om spraakkenmerken aan te passen
U kunt SSML gebruiken om de toonhoogte, uitspraak, spreeksnelheid, volume en andere aspecten in de tekst naar spraakuitvoer af te stemmen door uw aanvragen vanuit een XML-schema in te dienen. In deze sectie ziet u een voorbeeld van het wijzigen van de stem. Zie het overzicht van Speech Synthesis Markup Language voor meer informatie.
Als u SSML wilt gaan gebruiken voor aanpassing, moet u een kleine wijziging aanbrengen waarmee de stem wordt gewijzigd.
Maak een nieuw XML-bestand voor de SSML-configuratie in de hoofdprojectmap.
<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US"> <voice name="en-US-AvaMultilingualNeural"> When you're on the freeway, it's a good idea to use a GPS. </voice> </speak>
In dit voorbeeld wordt het bestand ssml.xml. Het hoofdelement is altijd
<speak>
. Als u de tekst in een<voice>
element terugloopt, kunt u de stem wijzigen met behulp van dename
parameter. Zie Ondersteunde talen voor de volledige lijst met ondersteunde neurale stemmen.Wijzig de aanvraag voor spraaksynthese om te verwijzen naar uw XML-bestand. De aanvraag is doorgaans hetzelfde, maar in plaats van de functie
SpeakTextAsync()
gebruikt uSpeakSsmlAsync()
. Deze functie verwacht een XML-tekenreeks. Laad eerst uw SSML-configuratie als een tekenreeks met behulp vanFile.ReadAllText()
. Vanaf dit punt is het resultaatobject precies hetzelfde als eerdere voorbeelden.Notitie
Als u Visual Studio gebruikt, vindt uw buildconfiguratie waarschijnlijk niet standaard uw XML-bestand. Klik met de rechtermuisknop op het XML-bestand en selecteer Eigenschappen. Bouwactie wijzigen in inhoud. Wijzig Kopiëren naar Uitvoermap om altijd te kopiëren.
public static async Task SynthesizeAudioAsync() { var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion"); using var speechSynthesizer = new SpeechSynthesizer(speechConfig, null); var ssml = File.ReadAllText("./ssml.xml"); var result = await speechSynthesizer.SpeakSsmlAsync(ssml); using var stream = AudioDataStream.FromResult(result); await stream.SaveToWaveFileAsync("path/to/write/file.wav"); }
Notitie
Als u de stem wilt wijzigen zonder SSML te gebruiken, kunt u de eigenschap SpeechConfig
instellen met behulp van SpeechConfig.SpeechSynthesisVoiceName = "en-US-AvaMultilingualNeural";
.
Abonneren op synthesizer-evenementen
Mogelijk wilt u meer inzichten over de tekst naar spraakverwerking en resultaten. U wilt bijvoorbeeld weten wanneer de synthesizer start en stopt, of misschien wilt u weten over andere gebeurtenissen die tijdens de synthese zijn aangetroffen.
Tijdens het gebruik van speechSynthesizer voor tekst-naar-spraak kunt u zich abonneren op de gebeurtenissen in deze tabel:
Gebeurtenis | Beschrijving | Gebruiksscenario |
---|---|---|
BookmarkReached |
Signalen dat een bladwijzer is bereikt. Voor het activeren van een gebeurtenis die een bladwijzer heeft bereikt, is een bookmark element vereist in de SSML. Deze gebeurtenis rapporteert de verstreken tijd van de uitvoeraudio tussen het begin van de synthese en het bookmark element. De eigenschap van Text de gebeurtenis is de tekenreekswaarde die u hebt ingesteld in het kenmerk van mark de bladwijzer. De bookmark elementen worden niet gesproken. |
U kunt het bookmark element gebruiken om aangepaste markeringen in SSML in te voegen om de verschuiving van elke markering in de audiostream op te halen. Het bookmark element kan worden gebruikt om te verwijzen naar een specifieke locatie in de tekst- of tagvolgorde. |
SynthesisCanceled |
Signalen dat de spraaksynthese is geannuleerd. | U kunt bevestigen wanneer synthese wordt geannuleerd. |
SynthesisCompleted |
Signalen dat spraaksynthese is voltooid. | U kunt bevestigen wanneer de synthese is voltooid. |
SynthesisStarted |
Signalen dat spraaksynthese is gestart. | U kunt bevestigen wanneer de synthese is gestart. |
Synthesizing |
Signalen dat spraaksynthese gaande is. Deze gebeurtenis wordt geactiveerd telkens wanneer de SDK een audiosegment van de Speech-service ontvangt. | U kunt controleren wanneer de synthese wordt uitgevoerd. |
VisemeReceived |
Signalen dat er een visemegebeurtenis is ontvangen. | Visemes worden vaak gebruikt om de belangrijkste poses in geobserveerde spraak te vertegenwoordigen. Belangrijke poses zijn onder andere de positie van de lippen, de kaak en de tong bij het produceren van een bepaald telefoonme. U kunt visemes gebruiken om het gezicht van een teken te animeren terwijl spraakaudio wordt afgespeeld. |
WordBoundary |
Signalen dat een woordgrens is ontvangen. Deze gebeurtenis wordt aan het begin van elk nieuw gesproken woord, leesteken en zin gegenereerd. De gebeurtenis rapporteert de tijdsverschil van het huidige woord, in tikken, vanaf het begin van de uitvoeraudio. Deze gebeurtenis rapporteert ook de tekenpositie in de invoertekst of SSML direct voordat het woord wordt gesproken. | Deze gebeurtenis wordt vaak gebruikt om relatieve posities van de tekst en bijbehorende audio te verkrijgen. Misschien wilt u meer weten over een nieuw woord en vervolgens actie ondernemen op basis van de timing. U kunt bijvoorbeeld informatie krijgen waarmee u kunt bepalen wanneer en hoe lang woorden moeten worden gemarkeerd terwijl ze worden gesproken. |
Notitie
Gebeurtenissen worden gegenereerd wanneer de uitvoeraudiogegevens beschikbaar komen, wat sneller is dan afspelen op een uitvoerapparaat. De beller moet streaming en realtime synchroniseren.
Hier volgt een voorbeeld waarin wordt getoond hoe u zich kunt abonneren op gebeurtenissen voor spraaksynthese.
Belangrijk
Als u een API-sleutel gebruikt, slaat u deze veilig op ergens anders op, zoals in Azure Key Vault. Neem de API-sleutel niet rechtstreeks in uw code op en plaats deze nooit openbaar.
Zie Aanvragen verifiëren bij Azure AI-services voor meer informatie over beveiliging van AI-services.
U kunt de instructies in de quickstart volgen, maar de inhoud van dat Program.cs bestand vervangen door de volgende C#-code:
using Microsoft.CognitiveServices.Speech;
class Program
{
// This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
static string speechKey = Environment.GetEnvironmentVariable("SPEECH_KEY");
static string speechRegion = Environment.GetEnvironmentVariable("SPEECH_REGION");
async static Task Main(string[] args)
{
var speechConfig = SpeechConfig.FromSubscription(speechKey, speechRegion);
var speechSynthesisVoiceName = "en-US-AvaMultilingualNeural";
var ssml = @$"<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>
<voice name='{speechSynthesisVoiceName}'>
<mstts:viseme type='redlips_front'/>
The rainbow has seven colors: <bookmark mark='colors_list_begin'/>Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark='colors_list_end'/>.
</voice>
</speak>";
// Required for sentence-level WordBoundary events
speechConfig.SetProperty(PropertyId.SpeechServiceResponse_RequestSentenceBoundary, "true");
using (var speechSynthesizer = new SpeechSynthesizer(speechConfig))
{
// Subscribe to events
speechSynthesizer.BookmarkReached += (s, e) =>
{
Console.WriteLine($"BookmarkReached event:" +
$"\r\n\tAudioOffset: {(e.AudioOffset + 5000) / 10000}ms" +
$"\r\n\tText: \"{e.Text}\".");
};
speechSynthesizer.SynthesisCanceled += (s, e) =>
{
Console.WriteLine("SynthesisCanceled event");
};
speechSynthesizer.SynthesisCompleted += (s, e) =>
{
Console.WriteLine($"SynthesisCompleted event:" +
$"\r\n\tAudioData: {e.Result.AudioData.Length} bytes" +
$"\r\n\tAudioDuration: {e.Result.AudioDuration}");
};
speechSynthesizer.SynthesisStarted += (s, e) =>
{
Console.WriteLine("SynthesisStarted event");
};
speechSynthesizer.Synthesizing += (s, e) =>
{
Console.WriteLine($"Synthesizing event:" +
$"\r\n\tAudioData: {e.Result.AudioData.Length} bytes");
};
speechSynthesizer.VisemeReceived += (s, e) =>
{
Console.WriteLine($"VisemeReceived event:" +
$"\r\n\tAudioOffset: {(e.AudioOffset + 5000) / 10000}ms" +
$"\r\n\tVisemeId: {e.VisemeId}");
};
speechSynthesizer.WordBoundary += (s, e) =>
{
Console.WriteLine($"WordBoundary event:" +
// Word, Punctuation, or Sentence
$"\r\n\tBoundaryType: {e.BoundaryType}" +
$"\r\n\tAudioOffset: {(e.AudioOffset + 5000) / 10000}ms" +
$"\r\n\tDuration: {e.Duration}" +
$"\r\n\tText: \"{e.Text}\"" +
$"\r\n\tTextOffset: {e.TextOffset}" +
$"\r\n\tWordLength: {e.WordLength}");
};
// Synthesize the SSML
Console.WriteLine($"SSML to synthesize: \r\n{ssml}");
var speechSynthesisResult = await speechSynthesizer.SpeakSsmlAsync(ssml);
// Output the results
switch (speechSynthesisResult.Reason)
{
case ResultReason.SynthesizingAudioCompleted:
Console.WriteLine("SynthesizingAudioCompleted result");
break;
case ResultReason.Canceled:
var cancellation = SpeechSynthesisCancellationDetails.FromResult(speechSynthesisResult);
Console.WriteLine($"CANCELED: Reason={cancellation.Reason}");
if (cancellation.Reason == CancellationReason.Error)
{
Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}");
Console.WriteLine($"CANCELED: ErrorDetails=[{cancellation.ErrorDetails}]");
Console.WriteLine($"CANCELED: Did you set the speech resource key and region values?");
}
break;
default:
break;
}
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
U vindt meer tekst naar spraakvoorbeelden op GitHub.
Een aangepast eindpunt gebruiken
Het aangepaste eindpunt is functioneel identiek aan het standaardeindpunt dat wordt gebruikt voor tekst-naar-spraakaanvragen.
Een verschil is dat het EndpointId
moet worden opgegeven om uw aangepaste stem te gebruiken via de Speech SDK. U kunt beginnen met de snelstartgids voor tekst naar spraak en vervolgens de code bijwerken met de EndpointId
en SpeechSynthesisVoiceName
.
var speechConfig = SpeechConfig.FromSubscription(speechKey, speechRegion);
speechConfig.SpeechSynthesisVoiceName = "YourCustomVoiceName";
speechConfig.EndpointId = "YourEndpointId";
Als u een aangepaste stem wilt gebruiken via Speech Synthesis Markup Language (SSML), geeft u de modelnaam op als de spraaknaam. In dit voorbeeld wordt de YourCustomVoiceName
stem gebruikt.
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
<voice name="YourCustomVoiceName">
This is the text that is spoken.
</voice>
</speak>
Een container uitvoeren en gebruiken
Spraakcontainers bieden websocket-api's voor query-eindpunten die toegankelijk zijn via de Speech SDK en Speech CLI. De Speech SDK en Speech CLI maken standaard gebruik van de openbare Speech-service. Als u de container wilt gebruiken, moet u de initialisatiemethode wijzigen. Gebruik een containerhost-URL in plaats van sleutel en regio.
Zie Speech-containers installeren en uitvoeren met Docker voor meer informatie over containers.
Referentiedocumentatiepakket (NuGet) | Aanvullende voorbeelden op GitHub |
In deze handleiding leert u algemene ontwerppatronen voor het uitvoeren van tekst-naar-spraaksynthese.
Zie Wat is tekst naar spraak voor meer informatie over de volgende gebieden ?
- Antwoorden krijgen als in-memory streams.
- Voorbeeldsnelheid en bitsnelheid van uitvoer aanpassen.
- Syntheseaanvragen verzenden met behulp van Speech Synthesis Markup Language (SSML).
- Neurale stemmen gebruiken.
- Abonneren op gebeurtenissen en reageren op resultaten.
Synthesetaal en spraak selecteren
De functie tekst-naar-spraak in de Speech-service ondersteunt meer dan 400 stemmen en meer dan 140 talen en varianten. Raadpleeg de volledige lijst met ondersteunde tekst naar spraakinstellingen of probeer deze in de spraakgalerie.
Geef de taal of stem van de SpeechConfig-klasse op die overeenkomt met de invoertekst en gebruik de opgegeven stem. In het volgende codefragment ziet u hoe deze techniek werkt:
void synthesizeSpeech()
{
auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
// Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
speechConfig->SetSpeechSynthesisLanguage("en-US");
speechConfig->SetSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural");
}
Alle neurale stemmen zijn meertalige en vloeiende taal en Engels. Als de invoertekst in het Engels bijvoorbeeld 'Ik ben enthousiast om tekst naar spraak te proberen' is en u selecteert es-ES-ElviraNeural
, wordt de tekst in het Engels gesproken met een Spaans accent.
Als de stem de taal van de invoertekst niet spreekt, maakt de Speech-service geen gesynthetiseerde audio. Zie Taal- en spraakondersteuning voor de Speech-service voor een volledige lijst met ondersteunde neurale stemmen.
Notitie
De standaardstem is de eerste stem die per landinstelling wordt geretourneerd vanuit de Voice List-API.
De stem die spreekt, wordt als volgt bepaald in volgorde van prioriteit:
- Als u dit niet instelt
SpeechSynthesisVoiceName
ofSpeechSynthesisLanguage
, wordt de standaardstem vooren-US
gesproken tekst gebruikt. - Als u alleen instelt
SpeechSynthesisLanguage
, spreekt de standaardstem voor de opgegeven landinstelling. - Als beide
SpeechSynthesisVoiceName
zijnSpeechSynthesisLanguage
ingesteld, wordt deSpeechSynthesisLanguage
instelling genegeerd. De stem die u opgeeft met behulp vanSpeechSynthesisVoiceName
spreekt. - Als het spraakelement is ingesteld met behulp van Speech Synthesis Markup Language (SSML), worden de
SpeechSynthesisVoiceName
enSpeechSynthesisLanguage
instellingen genegeerd.
Samengevat kan de volgorde van prioriteit worden beschreven als:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Resultaat |
---|---|---|---|
✗ | ✗ | ✗ | Standaardstem voor en-US spreken |
✗ | ✔ | ✗ | Standaardstem voor de opgegeven landinstelling spreekt. |
✔ | ✔ | ✗ | De stem die u opgeeft met behulp van SpeechSynthesisVoiceName spreekt. |
✔ | ✔ | ✔ | De stem die u opgeeft met behulp van SSML spreekt. |
Spraak synthetiseren naar een bestand
Maak een SpeechSynthesizer-object . Dit object dat wordt weergegeven in de volgende codefragmenten voert tekst uit naar spraakconversies en uitvoer naar luidsprekers, bestanden of andere uitvoerstromen. SpeechSynthesizer
accepteert als parameters:
- Het SpeechConfig-object dat u in de vorige stap hebt gemaakt.
- Een AudioConfig-object dat aangeeft hoe uitvoerresultaten moeten worden verwerkt.
Maak een
AudioConfig
exemplaar om de uitvoer automatisch naar een .wav-bestand te schrijven met behulp van deFromWavFileOutput()
functie:void synthesizeSpeech() { auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion"); auto audioConfig = AudioConfig::FromWavFileOutput("path/to/write/file.wav"); }
Instantieer een
SpeechSynthesizer
exemplaar. Geef uwspeechConfig
object en hetaudioConfig
object door als parameters. Als u spraak wilt omzetten en naar een bestand wilt schrijven, voert u deze uitSpeakTextAsync()
met een tekenreeks tekst.void synthesizeSpeech() { auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion"); auto audioConfig = AudioConfig::FromWavFileOutput("path/to/write/file.wav"); auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig, audioConfig); auto result = speechSynthesizer->SpeakTextAsync("A simple test to write to a file.").get(); }
Wanneer u het programma uitvoert, wordt er een gesynthetiseerd .wav-bestand gemaakt, dat wordt geschreven naar de locatie die u opgeeft. Dit resultaat is een goed voorbeeld van het meest eenvoudige gebruik. Vervolgens kunt u de uitvoer aanpassen en het uitvoerantwoord verwerken als een stroom in het geheugen voor het werken met aangepaste scenario's.
Synthetiseren naar de uitvoer van de luidspreker
Als u gesynthetiseerde spraak wilt uitvoeren naar het huidige actieve uitvoerapparaat zoals een luidspreker, laat u de AudioConfig
parameter weg wanneer u het SpeechSynthesizer
exemplaar maakt. Hier volgt een voorbeeld:
void synthesizeSpeech()
{
auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig);
auto result = speechSynthesizer->SpeakTextAsync("I'm excited to try text to speech").get();
}
Een resultaat ophalen als een stroom in het geheugen
U kunt de resulterende audiogegevens gebruiken als een in-memory stream in plaats van rechtstreeks naar een bestand te schrijven. Met een in-memory stream kunt u aangepast gedrag bouwen:
- Abstract de resulterende bytematrix als een zoekbare stroom voor aangepaste downstreamservices.
- Integreer het resultaat met andere API's of services.
- Wijzig de audiogegevens, schrijf aangepaste .wav headers en voer gerelateerde taken uit.
U kunt deze wijziging aanbrengen in het vorige voorbeeld. Verwijder eerst het AudioConfig
blok, omdat u het uitvoergedrag vanaf dit punt handmatig beheert voor meer controle. Geef NULL
deze door AudioConfig
in de SpeechSynthesizer
constructor.
Notitie
Het doorgeven NULL
voor AudioConfig
, in plaats van deze weg te laten zoals in het vorige voorbeeld van de luidsprekeruitvoer, speelt de audio niet standaard af op het huidige actieve uitvoerapparaat.
Sla het resultaat op in een SpeechSynthesisResult-variabele . De GetAudioData
getter retourneert een byte []
exemplaar voor de uitvoergegevens. U kunt met dit byte []
exemplaar handmatig werken of u kunt de Klasse AudioDataStream gebruiken om de stroom in het geheugen te beheren.
In dit voorbeeld gebruikt u de AudioDataStream.FromResult()
statische functie om een stroom op te halen uit het resultaat:
void synthesizeSpeech()
{
auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig);
auto result = speechSynthesizer->SpeakTextAsync("Getting the response as an in-memory stream.").get();
auto stream = AudioDataStream::FromResult(result);
}
Op dit moment kunt u elk aangepast gedrag implementeren met behulp van het resulterende stream
object.
Audio-indeling aanpassen
U kunt kenmerken voor audio-uitvoer aanpassen, waaronder:
- Audiobestandstype
- Samplefrequentie
- Bitdiepte
Als u de audio-indeling wilt wijzigen, gebruikt u de SetSpeechSynthesisOutputFormat()
functie voor het SpeechConfig
object. Deze functie verwacht een exemplaar van het enum
type SpeechSynthesisOutputFormat. Gebruik de enum
optie om de uitvoerindeling te selecteren. Zie de lijst met audio-indelingen voor beschikbare indelingen.
Er zijn verschillende opties voor verschillende bestandstypen, afhankelijk van uw vereisten. Onbewerkte indelingen Raw24Khz16BitMonoPcm
bevatten standaard geen audioheaders. Gebruik onbewerkte indelingen alleen in een van deze situaties:
- U weet dat uw downstream-implementatie een onbewerkte bitstream kan decoderen.
- U bent van plan om handmatig headers te bouwen op basis van factoren zoals bitdiepte, samplefrequentie en aantal kanalen.
In dit voorbeeld wordt de RIFF-indeling Riff24Khz16BitMonoPcm
met hoge kwaliteit opgegeven door het object in te SpeechConfig
stellenSpeechSynthesisOutputFormat
. Net als in het voorbeeld in de vorige sectie, gebruikt u AudioDataStream
om een stroom in het geheugen van het resultaat te verkrijgen en vervolgens naar een bestand te schrijven.
void synthesizeSpeech()
{
auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
speechConfig->SetSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat::Riff24Khz16BitMonoPcm);
auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig);
auto result = speechSynthesizer->SpeakTextAsync("A simple test to write to a file.").get();
auto stream = AudioDataStream::FromResult(result);
stream->SaveToWavFileAsync("path/to/write/file.wav").get();
}
Wanneer u het programma uitvoert, wordt er een .wav-bestand naar het opgegeven pad geschreven.
SSML gebruiken om spraakkenmerken aan te passen
U kunt SSML gebruiken om de toonhoogte, uitspraak, spreeksnelheid, volume en andere aspecten in de tekst naar spraakuitvoer af te stemmen door uw aanvragen vanuit een XML-schema in te dienen. In deze sectie ziet u een voorbeeld van het wijzigen van de stem. Zie het overzicht van Speech Synthesis Markup Language voor meer informatie.
Als u SSML wilt gaan gebruiken voor aanpassing, moet u een kleine wijziging aanbrengen waarmee de stem wordt gewijzigd.
Maak een nieuw XML-bestand voor de SSML-configuratie in de hoofdprojectmap.
<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US"> <voice name="en-US-AvaMultilingualNeural"> When you're on the freeway, it's a good idea to use a GPS. </voice> </speak>
In dit voorbeeld wordt het bestand ssml.xml. Het hoofdelement is altijd
<speak>
. Als u de tekst in een<voice>
element terugloopt, kunt u de stem wijzigen met behulp van dename
parameter. Zie Ondersteunde talen voor de volledige lijst met ondersteunde neurale stemmen.Wijzig de aanvraag voor spraaksynthese om te verwijzen naar uw XML-bestand. De aanvraag is meestal hetzelfde. In plaats van de
SpeakTextAsync()
functie te gebruiken, gebruiktSpeakSsmlAsync()
u . Deze functie verwacht een XML-tekenreeks. Laad eerst uw SSML-configuratie als een tekenreeks. Vanaf dit punt is het resultaatobject precies hetzelfde als eerdere voorbeelden.void synthesizeSpeech() { auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion"); auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig); std::ifstream file("./ssml.xml"); std::string ssml, line; while (std::getline(file, line)) { ssml += line; ssml.push_back('\n'); } auto result = speechSynthesizer->SpeakSsmlAsync(ssml).get(); auto stream = AudioDataStream::FromResult(result); stream->SaveToWavFileAsync("path/to/write/file.wav").get(); }
Notitie
Als u de stem wilt wijzigen zonder SSML te gebruiken, kunt u de eigenschap SpeechConfig
instellen met behulp van SpeechConfig.SetSpeechSynthesisVoiceName("en-US-AndrewMultilingualNeural")
.
Abonneren op synthesizer-evenementen
Mogelijk wilt u meer inzichten over de tekst naar spraakverwerking en resultaten. U wilt bijvoorbeeld weten wanneer de synthesizer start en stopt, of misschien wilt u weten over andere gebeurtenissen die tijdens de synthese zijn aangetroffen.
Tijdens het gebruik van speechSynthesizer voor tekst-naar-spraak kunt u zich abonneren op de gebeurtenissen in deze tabel:
Gebeurtenis | Beschrijving | Gebruiksscenario |
---|---|---|
BookmarkReached |
Signalen dat een bladwijzer is bereikt. Voor het activeren van een gebeurtenis die een bladwijzer heeft bereikt, is een bookmark element vereist in de SSML. Deze gebeurtenis rapporteert de verstreken tijd van de uitvoeraudio tussen het begin van de synthese en het bookmark element. De eigenschap van Text de gebeurtenis is de tekenreekswaarde die u hebt ingesteld in het kenmerk van mark de bladwijzer. De bookmark elementen worden niet gesproken. |
U kunt het bookmark element gebruiken om aangepaste markeringen in SSML in te voegen om de verschuiving van elke markering in de audiostream op te halen. Het bookmark element kan worden gebruikt om te verwijzen naar een specifieke locatie in de tekst- of tagvolgorde. |
SynthesisCanceled |
Signalen dat de spraaksynthese is geannuleerd. | U kunt bevestigen wanneer synthese wordt geannuleerd. |
SynthesisCompleted |
Signalen dat spraaksynthese is voltooid. | U kunt bevestigen wanneer de synthese is voltooid. |
SynthesisStarted |
Signalen dat spraaksynthese is gestart. | U kunt bevestigen wanneer de synthese is gestart. |
Synthesizing |
Signalen dat spraaksynthese gaande is. Deze gebeurtenis wordt geactiveerd telkens wanneer de SDK een audiosegment van de Speech-service ontvangt. | U kunt controleren wanneer de synthese wordt uitgevoerd. |
VisemeReceived |
Signalen dat er een visemegebeurtenis is ontvangen. | Visemes worden vaak gebruikt om de belangrijkste poses in geobserveerde spraak te vertegenwoordigen. Belangrijke poses zijn onder andere de positie van de lippen, de kaak en de tong bij het produceren van een bepaald telefoonme. U kunt visemes gebruiken om het gezicht van een teken te animeren terwijl spraakaudio wordt afgespeeld. |
WordBoundary |
Signalen dat een woordgrens is ontvangen. Deze gebeurtenis wordt aan het begin van elk nieuw gesproken woord, leesteken en zin gegenereerd. De gebeurtenis rapporteert de tijdsverschil van het huidige woord, in tikken, vanaf het begin van de uitvoeraudio. Deze gebeurtenis rapporteert ook de tekenpositie in de invoertekst of SSML direct voordat het woord wordt gesproken. | Deze gebeurtenis wordt vaak gebruikt om relatieve posities van de tekst en bijbehorende audio te verkrijgen. Misschien wilt u meer weten over een nieuw woord en vervolgens actie ondernemen op basis van de timing. U kunt bijvoorbeeld informatie krijgen waarmee u kunt bepalen wanneer en hoe lang woorden moeten worden gemarkeerd terwijl ze worden gesproken. |
Notitie
Gebeurtenissen worden gegenereerd wanneer de uitvoeraudiogegevens beschikbaar komen, wat sneller is dan afspelen op een uitvoerapparaat. De beller moet streaming en realtime synchroniseren.
Hier volgt een voorbeeld waarin wordt getoond hoe u zich kunt abonneren op gebeurtenissen voor spraaksynthese.
Belangrijk
Als u een API-sleutel gebruikt, slaat u deze veilig op ergens anders op, zoals in Azure Key Vault. Neem de API-sleutel niet rechtstreeks in uw code op en plaats deze nooit openbaar.
Zie Aanvragen verifiëren bij Azure AI-services voor meer informatie over beveiliging van AI-services.
U kunt de instructies in de quickstart volgen, maar de inhoud van dat main.cpp bestand vervangen door de volgende code:
#include <iostream>
#include <stdlib.h>
#include <speechapi_cxx.h>
using namespace Microsoft::CognitiveServices::Speech;
using namespace Microsoft::CognitiveServices::Speech::Audio;
std::string getEnvironmentVariable(const char* name);
int main()
{
// This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
auto speechKey = getEnvironmentVariable("SPEECH_KEY");
auto speechRegion = getEnvironmentVariable("SPEECH_REGION");
if ((size(speechKey) == 0) || (size(speechRegion) == 0)) {
std::cout << "Please set both SPEECH_KEY and SPEECH_REGION environment variables." << std::endl;
return -1;
}
auto speechConfig = SpeechConfig::FromSubscription(speechKey, speechRegion);
// Required for WordBoundary event sentences.
speechConfig->SetProperty(PropertyId::SpeechServiceResponse_RequestSentenceBoundary, "true");
const auto ssml = R"(<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>
<voice name = 'en-US-AvaMultilingualNeural'>
<mstts:viseme type = 'redlips_front' />
The rainbow has seven colors : <bookmark mark = 'colors_list_begin' />Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark = 'colors_list_end' />.
</voice>
</speak>)";
auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig);
// Subscribe to events
speechSynthesizer->BookmarkReached += [](const SpeechSynthesisBookmarkEventArgs& e)
{
std::cout << "Bookmark reached. "
<< "\r\n\tAudioOffset: " << round(e.AudioOffset / 10000) << "ms"
<< "\r\n\tText: " << e.Text << std::endl;
};
speechSynthesizer->SynthesisCanceled += [](const SpeechSynthesisEventArgs& e)
{
std::cout << "SynthesisCanceled event" << std::endl;
};
speechSynthesizer->SynthesisCompleted += [](const SpeechSynthesisEventArgs& e)
{
auto audioDuration = std::chrono::duration_cast<std::chrono::milliseconds>(e.Result->AudioDuration).count();
std::cout << "SynthesisCompleted event:"
<< "\r\n\tAudioData: " << e.Result->GetAudioData()->size() << "bytes"
<< "\r\n\tAudioDuration: " << audioDuration << std::endl;
};
speechSynthesizer->SynthesisStarted += [](const SpeechSynthesisEventArgs& e)
{
std::cout << "SynthesisStarted event" << std::endl;
};
speechSynthesizer->Synthesizing += [](const SpeechSynthesisEventArgs& e)
{
std::cout << "Synthesizing event:"
<< "\r\n\tAudioData: " << e.Result->GetAudioData()->size() << "bytes" << std::endl;
};
speechSynthesizer->VisemeReceived += [](const SpeechSynthesisVisemeEventArgs& e)
{
std::cout << "VisemeReceived event:"
<< "\r\n\tAudioOffset: " << round(e.AudioOffset / 10000) << "ms"
<< "\r\n\tVisemeId: " << e.VisemeId << std::endl;
};
speechSynthesizer->WordBoundary += [](const SpeechSynthesisWordBoundaryEventArgs& e)
{
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(e.Duration).count();
auto boundaryType = "";
switch (e.BoundaryType) {
case SpeechSynthesisBoundaryType::Punctuation:
boundaryType = "Punctuation";
break;
case SpeechSynthesisBoundaryType::Sentence:
boundaryType = "Sentence";
break;
case SpeechSynthesisBoundaryType::Word:
boundaryType = "Word";
break;
}
std::cout << "WordBoundary event:"
// Word, Punctuation, or Sentence
<< "\r\n\tBoundaryType: " << boundaryType
<< "\r\n\tAudioOffset: " << round(e.AudioOffset / 10000) << "ms"
<< "\r\n\tDuration: " << duration
<< "\r\n\tText: \"" << e.Text << "\""
<< "\r\n\tTextOffset: " << e.TextOffset
<< "\r\n\tWordLength: " << e.WordLength << std::endl;
};
auto result = speechSynthesizer->SpeakSsmlAsync(ssml).get();
// Checks result.
if (result->Reason == ResultReason::SynthesizingAudioCompleted)
{
std::cout << "SynthesizingAudioCompleted result" << std::endl;
}
else if (result->Reason == ResultReason::Canceled)
{
auto cancellation = SpeechSynthesisCancellationDetails::FromResult(result);
std::cout << "CANCELED: Reason=" << (int)cancellation->Reason << std::endl;
if (cancellation->Reason == CancellationReason::Error)
{
std::cout << "CANCELED: ErrorCode=" << (int)cancellation->ErrorCode << std::endl;
std::cout << "CANCELED: ErrorDetails=[" << cancellation->ErrorDetails << "]" << std::endl;
std::cout << "CANCELED: Did you set the speech resource key and region values?" << std::endl;
}
}
std::cout << "Press enter to exit..." << std::endl;
std::cin.get();
}
std::string getEnvironmentVariable(const char* name)
{
#if defined(_MSC_VER)
size_t requiredSize = 0;
(void)getenv_s(&requiredSize, nullptr, 0, name);
if (requiredSize == 0)
{
return "";
}
auto buffer = std::make_unique<char[]>(requiredSize);
(void)getenv_s(&requiredSize, buffer.get(), requiredSize, name);
return buffer.get();
#else
auto value = getenv(name);
return value ? value : "";
#endif
}
U vindt meer tekst naar spraakvoorbeelden op GitHub.
Een aangepast eindpunt gebruiken
Het aangepaste eindpunt is functioneel identiek aan het standaardeindpunt dat wordt gebruikt voor tekst-naar-spraakaanvragen.
Een verschil is dat het EndpointId
moet worden opgegeven om uw aangepaste stem te gebruiken via de Speech SDK. U kunt beginnen met de snelstartgids voor tekst naar spraak en vervolgens de code bijwerken met de EndpointId
en SpeechSynthesisVoiceName
.
auto speechConfig = SpeechConfig::FromSubscription(speechKey, speechRegion);
speechConfig->SetSpeechSynthesisVoiceName("YourCustomVoiceName");
speechConfig->SetEndpointId("YourEndpointId");
Als u een aangepaste stem wilt gebruiken via Speech Synthesis Markup Language (SSML), geeft u de modelnaam op als de spraaknaam. In dit voorbeeld wordt de YourCustomVoiceName
stem gebruikt.
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
<voice name="YourCustomVoiceName">
This is the text that is spoken.
</voice>
</speak>
Een container uitvoeren en gebruiken
Spraakcontainers bieden websocket-api's voor query-eindpunten die toegankelijk zijn via de Speech SDK en Speech CLI. De Speech SDK en Speech CLI maken standaard gebruik van de openbare Speech-service. Als u de container wilt gebruiken, moet u de initialisatiemethode wijzigen. Gebruik een containerhost-URL in plaats van sleutel en regio.
Zie Speech-containers installeren en uitvoeren met Docker voor meer informatie over containers.
Referentiedocumentatiepakket (Go) | Aanvullende voorbeelden op GitHub |
In deze handleiding leert u algemene ontwerppatronen voor het uitvoeren van tekst-naar-spraaksynthese.
Zie Wat is tekst naar spraak voor meer informatie over de volgende gebieden ?
- Antwoorden krijgen als in-memory streams.
- Voorbeeldsnelheid en bitsnelheid van uitvoer aanpassen.
- Syntheseaanvragen verzenden met behulp van Speech Synthesis Markup Language (SSML).
- Neurale stemmen gebruiken.
- Abonneren op gebeurtenissen en reageren op resultaten.
Vereisten
- Een Azure-abonnement. U kunt er gratis een maken.
- Maak een spraakresource in Azure Portal.
- Haal de spraakresourcesleutel en -regio op. Nadat uw Spraak-resource is geïmplementeerd, selecteert u Ga naar de resource om sleutels weer te geven en te beheren.
De Speech-SDK installeren
Voordat u iets kunt doen, moet u de Speech SDK voor Go installeren.
Tekst naar spraak naar spreker
Gebruik het volgende codevoorbeeld om spraaksynthese uit te voeren op uw standaardapparaat voor audio-uitvoer. Vervang de variabelen subscription
en region
door uw spraaksleutel en locatie/regio. Als u het script uitvoert, wordt de invoertekst voor de standaardluidspreker weergegeven.
package main
import (
"bufio"
"fmt"
"os"
"strings"
"time"
"github.com/Microsoft/cognitive-services-speech-sdk-go/audio"
"github.com/Microsoft/cognitive-services-speech-sdk-go/common"
"github.com/Microsoft/cognitive-services-speech-sdk-go/speech"
)
func synthesizeStartedHandler(event speech.SpeechSynthesisEventArgs) {
defer event.Close()
fmt.Println("Synthesis started.")
}
func synthesizingHandler(event speech.SpeechSynthesisEventArgs) {
defer event.Close()
fmt.Printf("Synthesizing, audio chunk size %d.\n", len(event.Result.AudioData))
}
func synthesizedHandler(event speech.SpeechSynthesisEventArgs) {
defer event.Close()
fmt.Printf("Synthesized, audio length %d.\n", len(event.Result.AudioData))
}
func cancelledHandler(event speech.SpeechSynthesisEventArgs) {
defer event.Close()
fmt.Println("Received a cancellation.")
}
func main() {
subscription := "YourSpeechKey"
region := "YourSpeechRegion"
audioConfig, err := audio.NewAudioConfigFromDefaultSpeakerOutput()
if err != nil {
fmt.Println("Got an error: ", err)
return
}
defer audioConfig.Close()
speechConfig, err := speech.NewSpeechConfigFromSubscription(subscription, region)
if err != nil {
fmt.Println("Got an error: ", err)
return
}
defer speechConfig.Close()
speechSynthesizer, err := speech.NewSpeechSynthesizerFromConfig(speechConfig, audioConfig)
if err != nil {
fmt.Println("Got an error: ", err)
return
}
defer speechSynthesizer.Close()
speechSynthesizer.SynthesisStarted(synthesizeStartedHandler)
speechSynthesizer.Synthesizing(synthesizingHandler)
speechSynthesizer.SynthesisCompleted(synthesizedHandler)
speechSynthesizer.SynthesisCanceled(cancelledHandler)
for {
fmt.Printf("Enter some text that you want to speak, or enter empty text to exit.\n> ")
text, _ := bufio.NewReader(os.Stdin).ReadString('\n')
text = strings.TrimSuffix(text, "\n")
if len(text) == 0 {
break
}
task := speechSynthesizer.SpeakTextAsync(text)
var outcome speech.SpeechSynthesisOutcome
select {
case outcome = <-task:
case <-time.After(60 * time.Second):
fmt.Println("Timed out")
return
}
defer outcome.Close()
if outcome.Error != nil {
fmt.Println("Got an error: ", outcome.Error)
return
}
if outcome.Result.Reason == common.SynthesizingAudioCompleted {
fmt.Printf("Speech synthesized to speaker for text [%s].\n", text)
} else {
cancellation, _ := speech.NewCancellationDetailsFromSpeechSynthesisResult(outcome.Result)
fmt.Printf("CANCELED: Reason=%d.\n", cancellation.Reason)
if cancellation.Reason == common.Error {
fmt.Printf("CANCELED: ErrorCode=%d\nCANCELED: ErrorDetails=[%s]\nCANCELED: Did you set the speech resource key and region values?\n",
cancellation.ErrorCode,
cancellation.ErrorDetails)
}
}
}
}
Voer de volgende opdrachten uit om een go.mod-bestand te maken dat is gekoppeld aan onderdelen die worden gehost op GitHub:
go mod init quickstart
go get github.com/Microsoft/cognitive-services-speech-sdk-go
Bouw nu de code en voer deze uit:
go build
go run quickstart
Zie de SpeechConfig
en SpeechSynthesizer
referentiedocumenten voor gedetailleerde informatie over de klassen.
Tekst naar spraak naar in-memory stream
U kunt de resulterende audiogegevens gebruiken als een in-memory stream in plaats van rechtstreeks naar een bestand te schrijven. Met een in-memory stream kunt u aangepast gedrag bouwen:
- Abstract de resulterende bytematrix als een zoekbare stroom voor aangepaste downstreamservices.
- Integreer het resultaat met andere API's of services.
- Wijzig de audiogegevens, schrijf aangepaste .wav headers en voer gerelateerde taken uit.
U kunt deze wijziging aanbrengen in het vorige voorbeeld. Verwijder het AudioConfig
blok, omdat u het uitvoergedrag vanaf dit punt handmatig beheert voor een betere controle. Geef nil
vervolgens de AudioConfig
SpeechSynthesizer
constructor door.
Notitie
AudioConfig
Als u dit doorgeeftnil
, in plaats van deze weg te laten zoals u in het vorige voorbeeld van de luidsprekeruitvoer hebt gedaan, wordt de audio niet standaard afgespeeld op het huidige actieve uitvoerapparaat.
Sla het resultaat op in een SpeechSynthesisResult
variabele. De AudioData
eigenschap retourneert een []byte
exemplaar voor de uitvoergegevens. U kunt met dit []byte
exemplaar handmatig werken of u kunt de AudioDataStream
klasse gebruiken om de stroom in het geheugen te beheren.
In dit voorbeeld gebruikt u de NewAudioDataStreamFromSpeechSynthesisResult()
statische functie om een stroom op te halen uit het resultaat.
Vervang de variabelen subscription
en region
door uw spraaksleutel en locatie/regio:
package main
import (
"bufio"
"fmt"
"io"
"os"
"strings"
"time"
"github.com/Microsoft/cognitive-services-speech-sdk-go/speech"
)
func synthesizeStartedHandler(event speech.SpeechSynthesisEventArgs) {
defer event.Close()
fmt.Println("Synthesis started.")
}
func synthesizingHandler(event speech.SpeechSynthesisEventArgs) {
defer event.Close()
fmt.Printf("Synthesizing, audio chunk size %d.\n", len(event.Result.AudioData))
}
func synthesizedHandler(event speech.SpeechSynthesisEventArgs) {
defer event.Close()
fmt.Printf("Synthesized, audio length %d.\n", len(event.Result.AudioData))
}
func cancelledHandler(event speech.SpeechSynthesisEventArgs) {
defer event.Close()
fmt.Println("Received a cancellation.")
}
func main() {
subscription := "YourSpeechKey"
region := "YourSpeechRegion"
speechConfig, err := speech.NewSpeechConfigFromSubscription(subscription, region)
if err != nil {
fmt.Println("Got an error: ", err)
return
}
defer speechConfig.Close()
speechSynthesizer, err := speech.NewSpeechSynthesizerFromConfig(speechConfig, nil)
if err != nil {
fmt.Println("Got an error: ", err)
return
}
defer speechSynthesizer.Close()
speechSynthesizer.SynthesisStarted(synthesizeStartedHandler)
speechSynthesizer.Synthesizing(synthesizingHandler)
speechSynthesizer.SynthesisCompleted(synthesizedHandler)
speechSynthesizer.SynthesisCanceled(cancelledHandler)
for {
fmt.Printf("Enter some text that you want to speak, or enter empty text to exit.\n> ")
text, _ := bufio.NewReader(os.Stdin).ReadString('\n')
text = strings.TrimSuffix(text, "\n")
if len(text) == 0 {
break
}
// StartSpeakingTextAsync sends the result to channel when the synthesis starts.
task := speechSynthesizer.StartSpeakingTextAsync(text)
var outcome speech.SpeechSynthesisOutcome
select {
case outcome = <-task:
case <-time.After(60 * time.Second):
fmt.Println("Timed out")
return
}
defer outcome.Close()
if outcome.Error != nil {
fmt.Println("Got an error: ", outcome.Error)
return
}
// In most cases, we want to streaming receive the audio to lower the latency.
// We can use AudioDataStream to do so.
stream, err := speech.NewAudioDataStreamFromSpeechSynthesisResult(outcome.Result)
defer stream.Close()
if err != nil {
fmt.Println("Got an error: ", err)
return
}
var all_audio []byte
audio_chunk := make([]byte, 2048)
for {
n, err := stream.Read(audio_chunk)
if err == io.EOF {
break
}
all_audio = append(all_audio, audio_chunk[:n]...)
}
fmt.Printf("Read [%d] bytes from audio data stream.\n", len(all_audio))
}
}
Voer de volgende opdrachten uit om een go.mod-bestand te maken dat is gekoppeld aan onderdelen die worden gehost op GitHub:
go mod init quickstart
go get github.com/Microsoft/cognitive-services-speech-sdk-go
Bouw nu de code en voer deze uit:
go build
go run quickstart
Zie de SpeechConfig
en SpeechSynthesizer
referentiedocumenten voor gedetailleerde informatie over de klassen.
Synthesetaal en spraak selecteren
De functie tekst-naar-spraak in de Speech-service ondersteunt meer dan 400 stemmen en meer dan 140 talen en varianten. U kunt de volledige lijst ophalen of ze uitproberen in de spraakgalerie.
Geef de taal of stem op van SpeechConfig
uw invoertekst en gebruik de opgegeven stem:
speechConfig, err := speech.NewSpeechConfigFromSubscription(key, region)
if err != nil {
fmt.Println("Got an error: ", err)
return
}
defer speechConfig.Close()
speechConfig.SetSpeechSynthesisLanguage("en-US")
speechConfig.SetSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural")
Alle neurale stemmen zijn meertalige en vloeiende taal en Engels. Als de invoertekst in het Engels bijvoorbeeld 'Ik ben enthousiast om tekst naar spraak te proberen' is en u selecteert es-ES-ElviraNeural
, wordt de tekst in het Engels gesproken met een Spaans accent.
Als de stem de taal van de invoertekst niet spreekt, maakt de Speech-service geen gesynthetiseerde audio. Zie Taal- en spraakondersteuning voor de Speech-service voor een volledige lijst met ondersteunde neurale stemmen.
Notitie
De standaardstem is de eerste stem die per landinstelling wordt geretourneerd vanuit de Voice List-API.
De stem die spreekt, wordt als volgt bepaald in volgorde van prioriteit:
- Als u dit niet instelt
SpeechSynthesisVoiceName
ofSpeechSynthesisLanguage
, wordt de standaardstem vooren-US
gesproken tekst gebruikt. - Als u alleen instelt
SpeechSynthesisLanguage
, spreekt de standaardstem voor de opgegeven landinstelling. - Als beide
SpeechSynthesisVoiceName
zijnSpeechSynthesisLanguage
ingesteld, wordt deSpeechSynthesisLanguage
instelling genegeerd. De stem die u opgeeft met behulp vanSpeechSynthesisVoiceName
spreekt. - Als het spraakelement is ingesteld met behulp van Speech Synthesis Markup Language (SSML), worden de
SpeechSynthesisVoiceName
enSpeechSynthesisLanguage
instellingen genegeerd.
Samengevat kan de volgorde van prioriteit worden beschreven als:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Resultaat |
---|---|---|---|
✗ | ✗ | ✗ | Standaardstem voor en-US spreken |
✗ | ✔ | ✗ | Standaardstem voor de opgegeven landinstelling spreekt. |
✔ | ✔ | ✗ | De stem die u opgeeft met behulp van SpeechSynthesisVoiceName spreekt. |
✔ | ✔ | ✔ | De stem die u opgeeft met behulp van SSML spreekt. |
SSML gebruiken om spraakkenmerken aan te passen
U kunt SSML (Speech Synthesis Markup Language) gebruiken om de toonhoogte, uitspraak, spreeksnelheid, volume en meer in de tekst af te stemmen op spraakuitvoer door uw aanvragen vanuit een XML-schema in te dienen. In deze sectie ziet u een voorbeeld van het wijzigen van de stem. Zie het overzicht van Speech Synthesis Markup Language voor meer informatie.
Als u SSML wilt gaan gebruiken voor aanpassing, moet u een kleine wijziging aanbrengen waarmee de stem wordt gewijzigd.
Maak eerst een nieuw XML-bestand voor de SSML-configuratie in de hoofdprojectmap. In dit voorbeeld is het ssml.xml
. Het hoofdelement is altijd <speak>
. Als u de tekst in een <voice>
element terugloopt, kunt u de stem wijzigen met behulp van de name
parameter. Zie Ondersteunde talen voor de volledige lijst met ondersteunde neurale stemmen.
<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
<voice name="en-US-AvaMultilingualNeural">
When you're on the freeway, it's a good idea to use a GPS.
</voice>
</speak>
Vervolgens moet u de aanvraag voor spraaksynthese wijzigen om te verwijzen naar uw XML-bestand. De aanvraag is doorgaans hetzelfde, maar in plaats van de functie SpeakTextAsync()
gebruikt u SpeakSsmlAsync()
. Deze functie verwacht een XML-tekenreeks, dus u laadt eerst uw SSML-configuratie als een tekenreeks. Vanaf dit punt is het resultaatobject precies hetzelfde als eerdere voorbeelden.
Notitie
Als u de stem wilt instellen zonder SSML te gebruiken, kunt u de eigenschap SpeechConfig
instellen met behulp van speechConfig.SetSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural")
.
Abonneren op synthesizer-evenementen
Mogelijk wilt u meer inzichten over de tekst naar spraakverwerking en resultaten. U wilt bijvoorbeeld weten wanneer de synthesizer start en stopt, of misschien wilt u weten over andere gebeurtenissen die tijdens de synthese zijn aangetroffen.
Tijdens het gebruik van speechSynthesizer voor tekst-naar-spraak kunt u zich abonneren op de gebeurtenissen in deze tabel:
Gebeurtenis | Beschrijving | Gebruiksscenario |
---|---|---|
BookmarkReached |
Signalen dat een bladwijzer is bereikt. Voor het activeren van een gebeurtenis die een bladwijzer heeft bereikt, is een bookmark element vereist in de SSML. Deze gebeurtenis rapporteert de verstreken tijd van de uitvoeraudio tussen het begin van de synthese en het bookmark element. De eigenschap van Text de gebeurtenis is de tekenreekswaarde die u hebt ingesteld in het kenmerk van mark de bladwijzer. De bookmark elementen worden niet gesproken. |
U kunt het bookmark element gebruiken om aangepaste markeringen in SSML in te voegen om de verschuiving van elke markering in de audiostream op te halen. Het bookmark element kan worden gebruikt om te verwijzen naar een specifieke locatie in de tekst- of tagvolgorde. |
SynthesisCanceled |
Signalen dat de spraaksynthese is geannuleerd. | U kunt bevestigen wanneer synthese wordt geannuleerd. |
SynthesisCompleted |
Signalen dat spraaksynthese is voltooid. | U kunt bevestigen wanneer de synthese is voltooid. |
SynthesisStarted |
Signalen dat spraaksynthese is gestart. | U kunt bevestigen wanneer de synthese is gestart. |
Synthesizing |
Signalen dat spraaksynthese gaande is. Deze gebeurtenis wordt geactiveerd telkens wanneer de SDK een audiosegment van de Speech-service ontvangt. | U kunt controleren wanneer de synthese wordt uitgevoerd. |
VisemeReceived |
Signalen dat er een visemegebeurtenis is ontvangen. | Visemes worden vaak gebruikt om de belangrijkste poses in geobserveerde spraak te vertegenwoordigen. Belangrijke poses zijn onder andere de positie van de lippen, de kaak en de tong bij het produceren van een bepaald telefoonme. U kunt visemes gebruiken om het gezicht van een teken te animeren terwijl spraakaudio wordt afgespeeld. |
WordBoundary |
Signalen dat een woordgrens is ontvangen. Deze gebeurtenis wordt aan het begin van elk nieuw gesproken woord, leesteken en zin gegenereerd. De gebeurtenis rapporteert de tijdsverschil van het huidige woord, in tikken, vanaf het begin van de uitvoeraudio. Deze gebeurtenis rapporteert ook de tekenpositie in de invoertekst of SSML direct voordat het woord wordt gesproken. | Deze gebeurtenis wordt vaak gebruikt om relatieve posities van de tekst en bijbehorende audio te verkrijgen. Misschien wilt u meer weten over een nieuw woord en vervolgens actie ondernemen op basis van de timing. U kunt bijvoorbeeld informatie krijgen waarmee u kunt bepalen wanneer en hoe lang woorden moeten worden gemarkeerd terwijl ze worden gesproken. |
Notitie
Gebeurtenissen worden gegenereerd wanneer de uitvoeraudiogegevens beschikbaar komen, wat sneller is dan afspelen op een uitvoerapparaat. De beller moet streaming en realtime synchroniseren.
Hier volgt een voorbeeld waarin wordt getoond hoe u zich kunt abonneren op gebeurtenissen voor spraaksynthese.
Belangrijk
Als u een API-sleutel gebruikt, slaat u deze veilig op ergens anders op, zoals in Azure Key Vault. Neem de API-sleutel niet rechtstreeks in uw code op en plaats deze nooit openbaar.
Zie Aanvragen verifiëren bij Azure AI-services voor meer informatie over beveiliging van AI-services.
U kunt de instructies in de quickstart volgen, maar de inhoud van dat speech-synthesis.go
bestand vervangen door de volgende Go-code:
package main
import (
"fmt"
"os"
"time"
"github.com/Microsoft/cognitive-services-speech-sdk-go/audio"
"github.com/Microsoft/cognitive-services-speech-sdk-go/common"
"github.com/Microsoft/cognitive-services-speech-sdk-go/speech"
)
func bookmarkReachedHandler(event speech.SpeechSynthesisBookmarkEventArgs) {
defer event.Close()
fmt.Println("BookmarkReached event")
}
func synthesisCanceledHandler(event speech.SpeechSynthesisEventArgs) {
defer event.Close()
fmt.Println("SynthesisCanceled event")
}
func synthesisCompletedHandler(event speech.SpeechSynthesisEventArgs) {
defer event.Close()
fmt.Println("SynthesisCompleted event")
fmt.Printf("\tAudioData: %d bytes\n", len(event.Result.AudioData))
fmt.Printf("\tAudioDuration: %d\n", event.Result.AudioDuration)
}
func synthesisStartedHandler(event speech.SpeechSynthesisEventArgs) {
defer event.Close()
fmt.Println("SynthesisStarted event")
}
func synthesizingHandler(event speech.SpeechSynthesisEventArgs) {
defer event.Close()
fmt.Println("Synthesizing event")
fmt.Printf("\tAudioData %d bytes\n", len(event.Result.AudioData))
}
func visemeReceivedHandler(event speech.SpeechSynthesisVisemeEventArgs) {
defer event.Close()
fmt.Println("VisemeReceived event")
fmt.Printf("\tAudioOffset: %dms\n", (event.AudioOffset+5000)/10000)
fmt.Printf("\tVisemeID %d\n", event.VisemeID)
}
func wordBoundaryHandler(event speech.SpeechSynthesisWordBoundaryEventArgs) {
defer event.Close()
boundaryType := ""
switch event.BoundaryType {
case 0:
boundaryType = "Word"
case 1:
boundaryType = "Punctuation"
case 2:
boundaryType = "Sentence"
}
fmt.Println("WordBoundary event")
fmt.Printf("\tBoundaryType %v\n", boundaryType)
fmt.Printf("\tAudioOffset: %dms\n", (event.AudioOffset+5000)/10000)
fmt.Printf("\tDuration %d\n", event.Duration)
fmt.Printf("\tText %s\n", event.Text)
fmt.Printf("\tTextOffset %d\n", event.TextOffset)
fmt.Printf("\tWordLength %d\n", event.WordLength)
}
func main() {
// This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
speechKey := os.Getenv("SPEECH_KEY")
speechRegion := os.Getenv("SPEECH_REGION")
audioConfig, err := audio.NewAudioConfigFromDefaultSpeakerOutput()
if err != nil {
fmt.Println("Got an error: ", err)
return
}
defer audioConfig.Close()
speechConfig, err := speech.NewSpeechConfigFromSubscription(speechKey, speechRegion)
if err != nil {
fmt.Println("Got an error: ", err)
return
}
defer speechConfig.Close()
// Required for WordBoundary event sentences.
speechConfig.SetProperty(common.SpeechServiceResponseRequestSentenceBoundary, "true")
speechSynthesizer, err := speech.NewSpeechSynthesizerFromConfig(speechConfig, audioConfig)
if err != nil {
fmt.Println("Got an error: ", err)
return
}
defer speechSynthesizer.Close()
speechSynthesizer.BookmarkReached(bookmarkReachedHandler)
speechSynthesizer.SynthesisCanceled(synthesisCanceledHandler)
speechSynthesizer.SynthesisCompleted(synthesisCompletedHandler)
speechSynthesizer.SynthesisStarted(synthesisStartedHandler)
speechSynthesizer.Synthesizing(synthesizingHandler)
speechSynthesizer.VisemeReceived(visemeReceivedHandler)
speechSynthesizer.WordBoundary(wordBoundaryHandler)
speechSynthesisVoiceName := "en-US-AvaMultilingualNeural"
ssml := fmt.Sprintf(`<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>
<voice name='%s'>
<mstts:viseme type='redlips_front'/>
The rainbow has seven colors: <bookmark mark='colors_list_begin'/>Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark='colors_list_end'/>.
</voice>
</speak>`, speechSynthesisVoiceName)
// Synthesize the SSML
fmt.Printf("SSML to synthesize: \n\t%s\n", ssml)
task := speechSynthesizer.SpeakSsmlAsync(ssml)
var outcome speech.SpeechSynthesisOutcome
select {
case outcome = <-task:
case <-time.After(60 * time.Second):
fmt.Println("Timed out")
return
}
defer outcome.Close()
if outcome.Error != nil {
fmt.Println("Got an error: ", outcome.Error)
return
}
if outcome.Result.Reason == common.SynthesizingAudioCompleted {
fmt.Println("SynthesizingAudioCompleted result")
} else {
cancellation, _ := speech.NewCancellationDetailsFromSpeechSynthesisResult(outcome.Result)
fmt.Printf("CANCELED: Reason=%d.\n", cancellation.Reason)
if cancellation.Reason == common.Error {
fmt.Printf("CANCELED: ErrorCode=%d\nCANCELED: ErrorDetails=[%s]\nCANCELED: Did you set the speech resource key and region values?\n",
cancellation.ErrorCode,
cancellation.ErrorDetails)
}
}
}
U vindt meer tekst naar spraakvoorbeelden op GitHub.
Een container uitvoeren en gebruiken
Spraakcontainers bieden websocket-api's voor query-eindpunten die toegankelijk zijn via de Speech SDK en Speech CLI. De Speech SDK en Speech CLI maken standaard gebruik van de openbare Speech-service. Als u de container wilt gebruiken, moet u de initialisatiemethode wijzigen. Gebruik een containerhost-URL in plaats van sleutel en regio.
Zie Speech-containers installeren en uitvoeren met Docker voor meer informatie over containers.
Referentiedocumentatie | Aanvullende voorbeelden op GitHub
In deze handleiding leert u algemene ontwerppatronen voor het uitvoeren van tekst-naar-spraaksynthese.
Zie Wat is tekst naar spraak voor meer informatie over de volgende gebieden ?
- Antwoorden krijgen als in-memory streams.
- Voorbeeldsnelheid en bitsnelheid van uitvoer aanpassen.
- Syntheseaanvragen verzenden met behulp van Speech Synthesis Markup Language (SSML).
- Neurale stemmen gebruiken.
- Abonneren op gebeurtenissen en reageren op resultaten.
Synthesetaal en spraak selecteren
De functie tekst-naar-spraak in de Speech-service ondersteunt meer dan 400 stemmen en meer dan 140 talen en varianten. U kunt de volledige lijst ophalen of ze uitproberen in de spraakgalerie.
Geef de taal of stem van SpeechConfig op die overeenkomt met uw invoertekst en gebruik de opgegeven stem. In het volgende codefragment ziet u hoe deze techniek werkt:
public static void main(String[] args) {
SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
// Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
speechConfig.setSpeechSynthesisLanguage("en-US");
speechConfig.setSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural");
}
Alle neurale stemmen zijn meertalige en vloeiende taal en Engels. Als de invoertekst in het Engels bijvoorbeeld 'Ik ben enthousiast om tekst naar spraak te proberen' is en u selecteert es-ES-ElviraNeural
, wordt de tekst in het Engels gesproken met een Spaans accent.
Als de stem de taal van de invoertekst niet spreekt, maakt de Speech-service geen gesynthetiseerde audio. Zie Taal- en spraakondersteuning voor de Speech-service voor een volledige lijst met ondersteunde neurale stemmen.
Notitie
De standaardstem is de eerste stem die per landinstelling wordt geretourneerd vanuit de Voice List-API.
De stem die spreekt, wordt als volgt bepaald in volgorde van prioriteit:
- Als u dit niet instelt
SpeechSynthesisVoiceName
ofSpeechSynthesisLanguage
, wordt de standaardstem vooren-US
gesproken tekst gebruikt. - Als u alleen instelt
SpeechSynthesisLanguage
, spreekt de standaardstem voor de opgegeven landinstelling. - Als beide
SpeechSynthesisVoiceName
zijnSpeechSynthesisLanguage
ingesteld, wordt deSpeechSynthesisLanguage
instelling genegeerd. De stem die u hebt opgegeven met behulp vanSpeechSynthesisVoiceName
spreekt. - Als het spraakelement is ingesteld met behulp van Speech Synthesis Markup Language (SSML), worden de
SpeechSynthesisVoiceName
enSpeechSynthesisLanguage
instellingen genegeerd.
Samengevat kan de volgorde van prioriteit worden beschreven als:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Resultaat |
---|---|---|---|
✗ | ✗ | ✗ | Standaardstem voor en-US spreken |
✗ | ✔ | ✗ | Standaardstem voor de opgegeven landinstelling spreekt. |
✔ | ✔ | ✗ | De stem die u opgeeft met behulp van SpeechSynthesisVoiceName spreekt. |
✔ | ✔ | ✔ | De stem die u opgeeft met behulp van SSML spreekt. |
Spraak synthetiseren naar een bestand
Maak een SpeechSynthesizer
object. Met dit object wordt tekst uitgevoerd naar spraakconversies en uitvoer naar luidsprekers, bestanden of andere uitvoerstromen. SpeechSynthesizer
accepteert als parameters:
- Het
SpeechConfig
object dat u in de vorige stap hebt gemaakt. - Een
AudioConfig
object dat aangeeft hoe uitvoerresultaten moeten worden verwerkt.
Maak een
AudioConfig
exemplaar om de uitvoer automatisch naar een .wav-bestand te schrijven met behulp van defromWavFileOutput()
statische functie:public static void main(String[] args) { SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion"); AudioConfig audioConfig = AudioConfig.fromWavFileOutput("path/to/write/file.wav"); }
Instantieer een
SpeechSynthesizer
exemplaar. Geef uwspeechConfig
object en hetaudioConfig
object door als parameters. Als u spraak wilt omzetten en naar een bestand wilt schrijven, voert u deze uitSpeakText()
met een tekenreeks tekst.public static void main(String[] args) { SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion"); AudioConfig audioConfig = AudioConfig.fromWavFileOutput("path/to/write/file.wav"); SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig, audioConfig); speechSynthesizer.SpeakText("I'm excited to try text to speech"); }
Wanneer u het programma uitvoert, wordt er een gesynthetiseerd .wav-bestand gemaakt, dat wordt geschreven naar de locatie die u opgeeft. Dit resultaat is een goed voorbeeld van het meest eenvoudige gebruik. Vervolgens kunt u de uitvoer aanpassen en het uitvoerantwoord verwerken als een stroom in het geheugen voor het werken met aangepaste scenario's.
Synthetiseren naar de uitvoer van de luidspreker
Mogelijk wilt u meer inzichten over de tekst naar spraakverwerking en resultaten. U wilt bijvoorbeeld weten wanneer de synthesizer start en stopt, of misschien wilt u weten over andere gebeurtenissen die tijdens de synthese zijn aangetroffen.
Als u gesynthetiseerde spraak wilt uitvoeren naar het huidige actieve uitvoerapparaat zoals een luidspreker, instantiëren AudioConfig
met behulp van de fromDefaultSpeakerOutput()
statische functie. Hier volgt een voorbeeld:
public static void main(String[] args) {
SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
AudioConfig audioConfig = AudioConfig.fromDefaultSpeakerOutput();
SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
speechSynthesizer.SpeakText("I'm excited to try text to speech");
}
Een resultaat ophalen als een stroom in het geheugen
U kunt de resulterende audiogegevens gebruiken als een in-memory stream in plaats van rechtstreeks naar een bestand te schrijven. Met een in-memory stream kunt u aangepast gedrag bouwen:
- Abstract de resulterende bytematrix als een zoekbare stroom voor aangepaste downstreamservices.
- Integreer het resultaat met andere API's of services.
- Wijzig de audiogegevens, schrijf aangepaste .wav headers en voer gerelateerde taken uit.
U kunt deze wijziging aanbrengen in het vorige voorbeeld. Verwijder eerst het AudioConfig
blok, omdat u het uitvoergedrag vanaf dit punt handmatig beheert voor meer controle. Geef null
vervolgens de AudioConfig
SpeechSynthesizer
constructor door.
Notitie
Het doorgeven null
van AudioConfig
, in plaats van het weglaten zoals u in het vorige voorbeeld van de luidsprekeruitvoer hebt gedaan, speelt de audio niet standaard af op het huidige actieve uitvoerapparaat.
Sla het resultaat op in een SpeechSynthesisResult
variabele. De SpeechSynthesisResult.getAudioData()
functie retourneert een byte []
exemplaar van de uitvoergegevens. U kunt met dit byte []
exemplaar handmatig werken of u kunt de AudioDataStream
klasse gebruiken om de stroom in het geheugen te beheren.
In dit voorbeeld gebruikt u de AudioDataStream.fromResult()
statische functie om een stroom op te halen uit het resultaat:
public static void main(String[] args) {
SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig, null);
SpeechSynthesisResult result = speechSynthesizer.SpeakText("I'm excited to try text to speech");
AudioDataStream stream = AudioDataStream.fromResult(result);
System.out.print(stream.getStatus());
}
Op dit moment kunt u elk aangepast gedrag implementeren met behulp van het resulterende stream
object.
Audio-indeling aanpassen
U kunt kenmerken voor audio-uitvoer aanpassen, waaronder:
- Audiobestandstype
- Samplefrequentie
- Bitdiepte
Als u de audio-indeling wilt wijzigen, gebruikt u de functie setSpeechSynthesisOutputFormat()
op het SpeechConfig
-object. Deze functie verwacht een exemplaar van het enum
type SpeechSynthesisOutputFormat. Gebruik de enum
optie om de uitvoerindeling te selecteren. Zie de lijst met audio-indelingen voor beschikbare indelingen.
Er zijn verschillende opties voor verschillende bestandstypen, afhankelijk van uw vereisten. Onbewerkte indelingen Raw24Khz16BitMonoPcm
bevatten standaard geen audioheaders. Gebruik onbewerkte indelingen alleen in een van deze situaties:
- U weet dat uw downstream-implementatie een onbewerkte bitstream kan decoderen.
- U bent van plan om handmatig headers te bouwen op basis van factoren zoals bitdiepte, samplefrequentie en aantal kanalen.
In dit voorbeeld wordt de RIFF-indeling Riff24Khz16BitMonoPcm
met hoge kwaliteit opgegeven door het object in te SpeechConfig
stellenSpeechSynthesisOutputFormat
. Net als in het voorbeeld in de vorige sectie, gebruikt u AudioDataStream
om een stroom in het geheugen van het resultaat te verkrijgen en vervolgens naar een bestand te schrijven.
public static void main(String[] args) {
SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
// set the output format
speechConfig.setSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm);
SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig, null);
SpeechSynthesisResult result = speechSynthesizer.SpeakText("I'm excited to try text to speech");
AudioDataStream stream = AudioDataStream.fromResult(result);
stream.saveToWavFile("path/to/write/file.wav");
}
Wanneer u het programma uitvoert, wordt er een .wav-bestand naar het opgegeven pad geschreven.
SSML gebruiken om spraakkenmerken aan te passen
U kunt SSML gebruiken om de toonhoogte, uitspraak, spreeksnelheid, volume en andere aspecten in de tekst naar spraakuitvoer af te stemmen door uw aanvragen vanuit een XML-schema in te dienen. In deze sectie ziet u een voorbeeld van het wijzigen van de stem. Zie het SSML-artikel voor meer informatie.
Als u SSML wilt gaan gebruiken voor aanpassing, moet u een kleine wijziging aanbrengen waarmee de stem wordt gewijzigd.
Maak een nieuw XML-bestand voor de SSML-configuratie in de hoofdprojectmap.
<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US"> <voice name="en-US-AvaMultilingualNeural"> When you're on the freeway, it's a good idea to use a GPS. </voice> </speak>
In dit voorbeeld wordt het bestand ssml.xml. Het hoofdelement is altijd
<speak>
. Als u de tekst in een<voice>
element terugloopt, kunt u de stem wijzigen met behulp van dename
parameter. Zie Ondersteunde talen voor de volledige lijst met ondersteunde neurale stemmen.Wijzig de aanvraag voor spraaksynthese om te verwijzen naar uw XML-bestand. De aanvraag is meestal hetzelfde. In plaats van de
SpeakText()
functie te gebruiken, gebruiktSpeakSsml()
u . Deze functie verwacht een XML-tekenreeks, dus maak eerst een functie om een XML-bestand te laden en als een tekenreeks te retourneren:private static String xmlToString(String filePath) { File file = new File(filePath); StringBuilder fileContents = new StringBuilder((int)file.length()); try (Scanner scanner = new Scanner(file)) { while(scanner.hasNextLine()) { fileContents.append(scanner.nextLine() + System.lineSeparator()); } return fileContents.toString().trim(); } catch (FileNotFoundException ex) { return "File not found."; } }
Op dit moment is het resultaatobject precies hetzelfde als de vorige voorbeelden:
public static void main(String[] args) { SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion"); SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig, null); String ssml = xmlToString("ssml.xml"); SpeechSynthesisResult result = speechSynthesizer.SpeakSsml(ssml); AudioDataStream stream = AudioDataStream.fromResult(result); stream.saveToWavFile("path/to/write/file.wav"); }
Notitie
Als u de stem wilt wijzigen zonder SSML te gebruiken, stelt u de eigenschap SpeechConfig
in met behulp van SpeechConfig.setSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural");
.
Abonneren op synthesizer-evenementen
Mogelijk wilt u meer inzichten over de tekst naar spraakverwerking en resultaten. U wilt bijvoorbeeld weten wanneer de synthesizer start en stopt, of misschien wilt u weten over andere gebeurtenissen die tijdens de synthese zijn aangetroffen.
Tijdens het gebruik van speechSynthesizer voor tekst-naar-spraak kunt u zich abonneren op de gebeurtenissen in deze tabel:
Gebeurtenis | Beschrijving | Gebruiksscenario |
---|---|---|
BookmarkReached |
Signalen dat een bladwijzer is bereikt. Voor het activeren van een gebeurtenis die een bladwijzer heeft bereikt, is een bookmark element vereist in de SSML. Deze gebeurtenis rapporteert de verstreken tijd van de uitvoeraudio tussen het begin van de synthese en het bookmark element. De eigenschap van Text de gebeurtenis is de tekenreekswaarde die u hebt ingesteld in het kenmerk van mark de bladwijzer. De bookmark elementen worden niet gesproken. |
U kunt het bookmark element gebruiken om aangepaste markeringen in SSML in te voegen om de verschuiving van elke markering in de audiostream op te halen. Het bookmark element kan worden gebruikt om te verwijzen naar een specifieke locatie in de tekst- of tagvolgorde. |
SynthesisCanceled |
Signalen dat de spraaksynthese is geannuleerd. | U kunt bevestigen wanneer synthese wordt geannuleerd. |
SynthesisCompleted |
Signalen dat spraaksynthese is voltooid. | U kunt bevestigen wanneer de synthese is voltooid. |
SynthesisStarted |
Signalen dat spraaksynthese is gestart. | U kunt bevestigen wanneer de synthese is gestart. |
Synthesizing |
Signalen dat spraaksynthese gaande is. Deze gebeurtenis wordt geactiveerd telkens wanneer de SDK een audiosegment van de Speech-service ontvangt. | U kunt controleren wanneer de synthese wordt uitgevoerd. |
VisemeReceived |
Signalen dat er een visemegebeurtenis is ontvangen. | Visemes worden vaak gebruikt om de belangrijkste poses in geobserveerde spraak te vertegenwoordigen. Belangrijke poses zijn onder andere de positie van de lippen, de kaak en de tong bij het produceren van een bepaald telefoonme. U kunt visemes gebruiken om het gezicht van een teken te animeren terwijl spraakaudio wordt afgespeeld. |
WordBoundary |
Signalen dat een woordgrens is ontvangen. Deze gebeurtenis wordt aan het begin van elk nieuw gesproken woord, leesteken en zin gegenereerd. De gebeurtenis rapporteert de tijdsverschil van het huidige woord, in tikken, vanaf het begin van de uitvoeraudio. Deze gebeurtenis rapporteert ook de tekenpositie in de invoertekst of SSML direct voordat het woord wordt gesproken. | Deze gebeurtenis wordt vaak gebruikt om relatieve posities van de tekst en bijbehorende audio te verkrijgen. Misschien wilt u meer weten over een nieuw woord en vervolgens actie ondernemen op basis van de timing. U kunt bijvoorbeeld informatie krijgen waarmee u kunt bepalen wanneer en hoe lang woorden moeten worden gemarkeerd terwijl ze worden gesproken. |
Notitie
Gebeurtenissen worden gegenereerd wanneer de uitvoeraudiogegevens beschikbaar komen, wat sneller is dan afspelen op een uitvoerapparaat. De beller moet streaming en realtime synchroniseren.
Hier volgt een voorbeeld waarin wordt getoond hoe u zich kunt abonneren op gebeurtenissen voor spraaksynthese.
Belangrijk
Als u een API-sleutel gebruikt, slaat u deze veilig op ergens anders op, zoals in Azure Key Vault. Neem de API-sleutel niet rechtstreeks in uw code op en plaats deze nooit openbaar.
Zie Aanvragen verifiëren bij Azure AI-services voor meer informatie over beveiliging van AI-services.
U kunt de instructies in de quickstart volgen, maar de inhoud van dat SpeechSynthesis.java bestand vervangen door de volgende Java-code:
import com.microsoft.cognitiveservices.speech.*;
import com.microsoft.cognitiveservices.speech.audio.*;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;
public class SpeechSynthesis {
// This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
private static String speechKey = System.getenv("SPEECH_KEY");
private static String speechRegion = System.getenv("SPEECH_REGION");
public static void main(String[] args) throws InterruptedException, ExecutionException {
SpeechConfig speechConfig = SpeechConfig.fromSubscription(speechKey, speechRegion);
// Required for WordBoundary event sentences.
speechConfig.setProperty(PropertyId.SpeechServiceResponse_RequestSentenceBoundary, "true");
String speechSynthesisVoiceName = "en-US-AvaMultilingualNeural";
String ssml = String.format("<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>"
.concat(String.format("<voice name='%s'>", speechSynthesisVoiceName))
.concat("<mstts:viseme type='redlips_front'/>")
.concat("The rainbow has seven colors: <bookmark mark='colors_list_begin'/>Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark='colors_list_end'/>.")
.concat("</voice>")
.concat("</speak>"));
SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig);
{
// Subscribe to events
speechSynthesizer.BookmarkReached.addEventListener((o, e) -> {
System.out.println("BookmarkReached event:");
System.out.println("\tAudioOffset: " + ((e.getAudioOffset() + 5000) / 10000) + "ms");
System.out.println("\tText: " + e.getText());
});
speechSynthesizer.SynthesisCanceled.addEventListener((o, e) -> {
System.out.println("SynthesisCanceled event");
});
speechSynthesizer.SynthesisCompleted.addEventListener((o, e) -> {
SpeechSynthesisResult result = e.getResult();
byte[] audioData = result.getAudioData();
System.out.println("SynthesisCompleted event:");
System.out.println("\tAudioData: " + audioData.length + " bytes");
System.out.println("\tAudioDuration: " + result.getAudioDuration());
result.close();
});
speechSynthesizer.SynthesisStarted.addEventListener((o, e) -> {
System.out.println("SynthesisStarted event");
});
speechSynthesizer.Synthesizing.addEventListener((o, e) -> {
SpeechSynthesisResult result = e.getResult();
byte[] audioData = result.getAudioData();
System.out.println("Synthesizing event:");
System.out.println("\tAudioData: " + audioData.length + " bytes");
result.close();
});
speechSynthesizer.VisemeReceived.addEventListener((o, e) -> {
System.out.println("VisemeReceived event:");
System.out.println("\tAudioOffset: " + ((e.getAudioOffset() + 5000) / 10000) + "ms");
System.out.println("\tVisemeId: " + e.getVisemeId());
});
speechSynthesizer.WordBoundary.addEventListener((o, e) -> {
System.out.println("WordBoundary event:");
System.out.println("\tBoundaryType: " + e.getBoundaryType());
System.out.println("\tAudioOffset: " + ((e.getAudioOffset() + 5000) / 10000) + "ms");
System.out.println("\tDuration: " + e.getDuration());
System.out.println("\tText: " + e.getText());
System.out.println("\tTextOffset: " + e.getTextOffset());
System.out.println("\tWordLength: " + e.getWordLength());
});
// Synthesize the SSML
System.out.println("SSML to synthesize:");
System.out.println(ssml);
SpeechSynthesisResult speechSynthesisResult = speechSynthesizer.SpeakSsmlAsync(ssml).get();
if (speechSynthesisResult.getReason() == ResultReason.SynthesizingAudioCompleted) {
System.out.println("SynthesizingAudioCompleted result");
}
else if (speechSynthesisResult.getReason() == ResultReason.Canceled) {
SpeechSynthesisCancellationDetails cancellation = SpeechSynthesisCancellationDetails.fromResult(speechSynthesisResult);
System.out.println("CANCELED: Reason=" + cancellation.getReason());
if (cancellation.getReason() == CancellationReason.Error) {
System.out.println("CANCELED: ErrorCode=" + cancellation.getErrorCode());
System.out.println("CANCELED: ErrorDetails=" + cancellation.getErrorDetails());
System.out.println("CANCELED: Did you set the speech resource key and region values?");
}
}
}
speechSynthesizer.close();
System.exit(0);
}
}
U vindt meer tekst naar spraakvoorbeelden op GitHub.
Een aangepast eindpunt gebruiken
Het aangepaste eindpunt is functioneel identiek aan het standaardeindpunt dat wordt gebruikt voor tekst-naar-spraakaanvragen.
Een verschil is dat het EndpointId
moet worden opgegeven om uw aangepaste stem te gebruiken via de Speech SDK. U kunt beginnen met de snelstartgids voor tekst naar spraak en vervolgens de code bijwerken met de EndpointId
en SpeechSynthesisVoiceName
.
SpeechConfig speechConfig = SpeechConfig.fromSubscription(speechKey, speechRegion);
speechConfig.setSpeechSynthesisVoiceName("YourCustomVoiceName");
speechConfig.setEndpointId("YourEndpointId");
Als u een aangepaste stem wilt gebruiken via Speech Synthesis Markup Language (SSML), geeft u de modelnaam op als de spraaknaam. In dit voorbeeld wordt de YourCustomVoiceName
stem gebruikt.
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
<voice name="YourCustomVoiceName">
This is the text that is spoken.
</voice>
</speak>
Een container uitvoeren en gebruiken
Spraakcontainers bieden websocket-api's voor query-eindpunten die toegankelijk zijn via de Speech SDK en Speech CLI. De Speech SDK en Speech CLI maken standaard gebruik van de openbare Speech-service. Als u de container wilt gebruiken, moet u de initialisatiemethode wijzigen. Gebruik een containerhost-URL in plaats van sleutel en regio.
Zie Speech-containers installeren en uitvoeren met Docker voor meer informatie over containers.
Referentiedocumentatiepakket (npm) | Aanvullende voorbeelden in broncode van GitHub Library | |
In deze handleiding leert u algemene ontwerppatronen voor het uitvoeren van tekst-naar-spraaksynthese.
Zie Wat is tekst naar spraak voor meer informatie over de volgende gebieden ?
- Antwoorden krijgen als in-memory streams.
- Voorbeeldsnelheid en bitsnelheid van uitvoer aanpassen.
- Syntheseaanvragen verzenden met behulp van Speech Synthesis Markup Language (SSML).
- Neurale stemmen gebruiken.
- Abonneren op gebeurtenissen en reageren op resultaten.
Synthesetaal en spraak selecteren
De functie tekst-naar-spraak in de Speech-service ondersteunt meer dan 400 stemmen en meer dan 140 talen en varianten. U kunt de volledige lijst ophalen of ze uitproberen in de spraakgalerie.
Geef de taal of stem op van SpeechConfig
uw invoertekst en gebruik de opgegeven stem:
function synthesizeSpeech() {
const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
// Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
speechConfig.speechSynthesisLanguage = "en-US";
speechConfig.speechSynthesisVoiceName = "en-US-AvaMultilingualNeural";
}
synthesizeSpeech();
Alle neurale stemmen zijn meertalige en vloeiende taal en Engels. Als de invoertekst in het Engels bijvoorbeeld 'Ik ben enthousiast om tekst naar spraak te proberen' is en u selecteert es-ES-ElviraNeural
, wordt de tekst in het Engels gesproken met een Spaans accent.
Als de stem de taal van de invoertekst niet spreekt, maakt de Speech-service geen gesynthetiseerde audio. Zie Taal- en spraakondersteuning voor de Speech-service voor een volledige lijst met ondersteunde neurale stemmen.
Notitie
De standaardstem is de eerste stem die per landinstelling wordt geretourneerd vanuit de Voice List-API.
De stem die spreekt, wordt als volgt bepaald in volgorde van prioriteit:
- Als u dit niet instelt
SpeechSynthesisVoiceName
ofSpeechSynthesisLanguage
, wordt de standaardstem vooren-US
gesproken tekst gebruikt. - Als u alleen instelt
SpeechSynthesisLanguage
, spreekt de standaardstem voor de opgegeven landinstelling. - Als beide
SpeechSynthesisVoiceName
zijnSpeechSynthesisLanguage
ingesteld, wordt deSpeechSynthesisLanguage
instelling genegeerd. De stem die u opgeeft met behulp vanSpeechSynthesisVoiceName
spreekt. - Als het spraakelement is ingesteld met behulp van Speech Synthesis Markup Language (SSML), worden de
SpeechSynthesisVoiceName
enSpeechSynthesisLanguage
instellingen genegeerd.
Samengevat kan de volgorde van prioriteit worden beschreven als:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Resultaat |
---|---|---|---|
✗ | ✗ | ✗ | Standaardstem voor en-US spreken |
✗ | ✔ | ✗ | Standaardstem voor de opgegeven landinstelling spreekt. |
✔ | ✔ | ✗ | De stem die u opgeeft met behulp van SpeechSynthesisVoiceName spreekt. |
✔ | ✔ | ✔ | De stem die u opgeeft met behulp van SSML spreekt. |
Tekst omzetten in spraak
Als u gesynthetiseerde spraak wilt uitvoeren naar het huidige actieve uitvoerapparaat zoals een luidspreker, instantiëren AudioConfig
met behulp van de fromDefaultSpeakerOutput()
statische functie. Hier volgt een voorbeeld:
function synthesizeSpeech() {
const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
const audioConfig = sdk.AudioConfig.fromDefaultSpeakerOutput();
const speechSynthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
speechSynthesizer.speakTextAsync(
"I'm excited to try text to speech",
result => {
if (result) {
speechSynthesizer.close();
return result.audioData;
}
},
error => {
console.log(error);
speechSynthesizer.close();
});
}
Wanneer u het programma uitvoert, wordt gesynthetiseerde audio afgespeeld vanuit de luidspreker. Dit resultaat is een goed voorbeeld van het meest eenvoudige gebruik. Vervolgens kunt u de uitvoer aanpassen en het uitvoerantwoord verwerken als een in-memory stream voor het werken met aangepaste scenario's.
Een resultaat ophalen als een stroom in het geheugen
U kunt de resulterende audiogegevens gebruiken als een in-memory stream in plaats van rechtstreeks naar een bestand te schrijven. Met een in-memory stream kunt u aangepast gedrag bouwen:
- Abstract de resulterende bytematrix als een zoekbare stroom voor aangepaste downstreamservices.
- Integreer het resultaat met andere API's of services.
- Wijzig de audiogegevens, schrijf aangepaste headers en voer gerelateerde
.wav
taken uit.
U kunt deze wijziging aanbrengen in het vorige voorbeeld. Verwijder het AudioConfig
blok, omdat u het uitvoergedrag vanaf dit punt handmatig beheert voor een betere controle. Geef null
vervolgens de AudioConfig
SpeechSynthesizer
constructor door.
Notitie
Het doorgeven null
van AudioConfig
, in plaats van het weglaten zoals u in het vorige voorbeeld van de luidsprekeruitvoer hebt gedaan, speelt de audio niet standaard af op het huidige actieve uitvoerapparaat.
Sla het resultaat op in een SpeechSynthesisResult-variabele . De SpeechSynthesisResult.audioData
eigenschap retourneert een ArrayBuffer
waarde van de uitvoergegevens, het standaardtype browserstream. Voor code aan de serverzijde converteert u ArrayBuffer
naar een bufferstroom.
De volgende code werkt voor de clientzijde:
function synthesizeSpeech() {
const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
const speechSynthesizer = new sdk.SpeechSynthesizer(speechConfig);
speechSynthesizer.speakTextAsync(
"I'm excited to try text to speech",
result => {
speechSynthesizer.close();
return result.audioData;
},
error => {
console.log(error);
speechSynthesizer.close();
});
}
U kunt elk aangepast gedrag implementeren met behulp van het resulterende ArrayBuffer
object. ArrayBuffer
is een veelvoorkomend type dat u in een browser kunt ontvangen en kunt afspelen vanuit deze indeling.
Als u met de gegevens als een stroom wilt werken, moet u het ArrayBuffer
object converteren naar een stream als u op een server gebaseerde code wilt gebruiken:
function synthesizeSpeech() {
const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
const speechSynthesizer = new sdk.SpeechSynthesizer(speechConfig);
speechSynthesizer.speakTextAsync(
"I'm excited to try text to speech",
result => {
const { audioData } = result;
speechSynthesizer.close();
// convert arrayBuffer to stream
// return stream
const bufferStream = new PassThrough();
bufferStream.end(Buffer.from(audioData));
return bufferStream;
},
error => {
console.log(error);
speechSynthesizer.close();
});
}
Audio-indeling aanpassen
U kunt kenmerken voor audio-uitvoer aanpassen, waaronder:
- Audiobestandstype
- Samplefrequentie
- Bitdiepte
Als u de audio-indeling wilt wijzigen, gebruikt u de speechSynthesisOutputFormat
eigenschap van het SpeechConfig
object. Deze eigenschap verwacht een enum
exemplaar van het type SpeechSynthesisOutputFormat. Gebruik de enum
optie om de uitvoerindeling te selecteren. Zie de lijst met audio-indelingen voor beschikbare indelingen.
Er zijn verschillende opties voor verschillende bestandstypen, afhankelijk van uw vereisten. Onbewerkte indelingen Raw24Khz16BitMonoPcm
bevatten standaard geen audioheaders. Gebruik onbewerkte indelingen alleen in een van deze situaties:
- U weet dat uw downstream-implementatie een onbewerkte bitstream kan decoderen.
- U bent van plan om handmatig headers te bouwen op basis van factoren zoals bitdiepte, samplefrequentie en aantal kanalen.
In dit voorbeeld wordt de RIFF-indeling Riff24Khz16BitMonoPcm
met hoge kwaliteit opgegeven door het object in te SpeechConfig
stellenspeechSynthesisOutputFormat
. Net als in het voorbeeld in de vorige sectie, kunt u de ArrayBuffer
-audiogegevens ophalen en ermee werken.
function synthesizeSpeech() {
const speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
// Set the output format
speechConfig.speechSynthesisOutputFormat = sdk.SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm;
const speechSynthesizer = new sdk.SpeechSynthesizer(speechConfig, null);
speechSynthesizer.speakTextAsync(
"I'm excited to try text to speech",
result => {
// Interact with the audio ArrayBuffer data
const audioData = result.audioData;
console.log(`Audio data byte size: ${audioData.byteLength}.`)
speechSynthesizer.close();
},
error => {
console.log(error);
speechSynthesizer.close();
});
}
SSML gebruiken om spraakkenmerken aan te passen
U kunt SSML gebruiken om de toonhoogte, uitspraak, spreeksnelheid, volume en andere aspecten in de tekst naar spraakuitvoer af te stemmen door uw aanvragen vanuit een XML-schema in te dienen. In deze sectie ziet u een voorbeeld van het wijzigen van de stem. Zie het overzicht van Speech Synthesis Markup Language voor meer informatie.
Als u SSML wilt gaan gebruiken voor aanpassing, moet u een kleine wijziging aanbrengen waarmee de stem wordt gewijzigd.
Maak een nieuw XML-bestand voor de SSML-configuratie in de hoofdprojectmap.
<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US"> <voice name="en-US-AvaMultilingualNeural"> When you're on the freeway, it's a good idea to use a GPS. </voice> </speak>
In dit voorbeeld is het ssml.xml. Het hoofdelement is altijd
<speak>
. Als u de tekst in een<voice>
element terugloopt, kunt u de stem wijzigen met behulp van dename
parameter. Zie Ondersteunde talen voor de volledige lijst met ondersteunde neurale stemmen.Wijzig de aanvraag voor spraaksynthese om te verwijzen naar uw XML-bestand. De aanvraag is doorgaans hetzelfde, maar in plaats van de functie
speakTextAsync()
gebruikt uspeakSsmlAsync()
. Deze functie verwacht een XML-tekenreeks. Maak een functie om een XML-bestand te laden en als een tekenreeks te retourneren:function xmlToString(filePath) { const xml = readFileSync(filePath, "utf8"); return xml; }
Zie Node.js-bestandssysteem voor meer informatie over
readFileSync
.Het resultaatobject is precies hetzelfde als de vorige voorbeelden:
function synthesizeSpeech() { const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion"); const speechSynthesizer = new sdk.SpeechSynthesizer(speechConfig, null); const ssml = xmlToString("ssml.xml"); speechSynthesizer.speakSsmlAsync( ssml, result => { if (result.errorDetails) { console.error(result.errorDetails); } else { console.log(JSON.stringify(result)); } speechSynthesizer.close(); }, error => { console.log(error); speechSynthesizer.close(); }); }
Notitie
Als u de stem wilt wijzigen zonder SSML te gebruiken, kunt u de eigenschap SpeechConfig
instellen met behulp van SpeechConfig.speechSynthesisVoiceName = "en-US-AvaMultilingualNeural";
.
Abonneren op synthesizer-evenementen
Mogelijk wilt u meer inzichten over de tekst naar spraakverwerking en resultaten. U wilt bijvoorbeeld weten wanneer de synthesizer start en stopt, of misschien wilt u weten over andere gebeurtenissen die tijdens de synthese zijn aangetroffen.
Tijdens het gebruik van speechSynthesizer voor tekst-naar-spraak kunt u zich abonneren op de gebeurtenissen in deze tabel:
Gebeurtenis | Beschrijving | Gebruiksscenario |
---|---|---|
BookmarkReached |
Signalen dat een bladwijzer is bereikt. Voor het activeren van een gebeurtenis die een bladwijzer heeft bereikt, is een bookmark element vereist in de SSML. Deze gebeurtenis rapporteert de verstreken tijd van de uitvoeraudio tussen het begin van de synthese en het bookmark element. De eigenschap van Text de gebeurtenis is de tekenreekswaarde die u hebt ingesteld in het kenmerk van mark de bladwijzer. De bookmark elementen worden niet gesproken. |
U kunt het bookmark element gebruiken om aangepaste markeringen in SSML in te voegen om de verschuiving van elke markering in de audiostream op te halen. Het bookmark element kan worden gebruikt om te verwijzen naar een specifieke locatie in de tekst- of tagvolgorde. |
SynthesisCanceled |
Signalen dat de spraaksynthese is geannuleerd. | U kunt bevestigen wanneer synthese wordt geannuleerd. |
SynthesisCompleted |
Signalen dat spraaksynthese is voltooid. | U kunt bevestigen wanneer de synthese is voltooid. |
SynthesisStarted |
Signalen dat spraaksynthese is gestart. | U kunt bevestigen wanneer de synthese is gestart. |
Synthesizing |
Signalen dat spraaksynthese gaande is. Deze gebeurtenis wordt geactiveerd telkens wanneer de SDK een audiosegment van de Speech-service ontvangt. | U kunt controleren wanneer de synthese wordt uitgevoerd. |
VisemeReceived |
Signalen dat er een visemegebeurtenis is ontvangen. | Visemes worden vaak gebruikt om de belangrijkste poses in geobserveerde spraak te vertegenwoordigen. Belangrijke poses zijn onder andere de positie van de lippen, de kaak en de tong bij het produceren van een bepaald telefoonme. U kunt visemes gebruiken om het gezicht van een teken te animeren terwijl spraakaudio wordt afgespeeld. |
WordBoundary |
Signalen dat een woordgrens is ontvangen. Deze gebeurtenis wordt aan het begin van elk nieuw gesproken woord, leesteken en zin gegenereerd. De gebeurtenis rapporteert de tijdsverschil van het huidige woord, in tikken, vanaf het begin van de uitvoeraudio. Deze gebeurtenis rapporteert ook de tekenpositie in de invoertekst of SSML direct voordat het woord wordt gesproken. | Deze gebeurtenis wordt vaak gebruikt om relatieve posities van de tekst en bijbehorende audio te verkrijgen. Misschien wilt u meer weten over een nieuw woord en vervolgens actie ondernemen op basis van de timing. U kunt bijvoorbeeld informatie krijgen waarmee u kunt bepalen wanneer en hoe lang woorden moeten worden gemarkeerd terwijl ze worden gesproken. |
Notitie
Gebeurtenissen worden gegenereerd wanneer de uitvoeraudiogegevens beschikbaar komen, wat sneller is dan afspelen op een uitvoerapparaat. De beller moet streaming en realtime synchroniseren.
Hier volgt een voorbeeld waarin wordt getoond hoe u zich kunt abonneren op gebeurtenissen voor spraaksynthese.
Belangrijk
Als u een API-sleutel gebruikt, slaat u deze veilig op ergens anders op, zoals in Azure Key Vault. Neem de API-sleutel niet rechtstreeks in uw code op en plaats deze nooit openbaar.
Zie Aanvragen verifiëren bij Azure AI-services voor meer informatie over beveiliging van AI-services.
U kunt de instructies in de quickstart volgen, maar de inhoud van dat SpeechSynthesis.js bestand vervangen door de volgende JavaScript-code.
(function() {
"use strict";
var sdk = require("microsoft-cognitiveservices-speech-sdk");
var audioFile = "YourAudioFile.wav";
// This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
const speechConfig = sdk.SpeechConfig.fromSubscription(process.env.SPEECH_KEY, process.env.SPEECH_REGION);
const audioConfig = sdk.AudioConfig.fromAudioFileOutput(audioFile);
var speechSynthesisVoiceName = "en-US-AvaMultilingualNeural";
var ssml = `<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'> \r\n \
<voice name='${speechSynthesisVoiceName}'> \r\n \
<mstts:viseme type='redlips_front'/> \r\n \
The rainbow has seven colors: <bookmark mark='colors_list_begin'/>Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark='colors_list_end'/>. \r\n \
</voice> \r\n \
</speak>`;
// Required for WordBoundary event sentences.
speechConfig.setProperty(sdk.PropertyId.SpeechServiceResponse_RequestSentenceBoundary, "true");
// Create the speech speechSynthesizer.
var speechSynthesizer = new sdk.SpeechSynthesizer(speechConfig, audioConfig);
speechSynthesizer.bookmarkReached = function (s, e) {
var str = `BookmarkReached event: \
\r\n\tAudioOffset: ${(e.audioOffset + 5000) / 10000}ms \
\r\n\tText: \"${e.text}\".`;
console.log(str);
};
speechSynthesizer.synthesisCanceled = function (s, e) {
console.log("SynthesisCanceled event");
};
speechSynthesizer.synthesisCompleted = function (s, e) {
var str = `SynthesisCompleted event: \
\r\n\tAudioData: ${e.result.audioData.byteLength} bytes \
\r\n\tAudioDuration: ${e.result.audioDuration}`;
console.log(str);
};
speechSynthesizer.synthesisStarted = function (s, e) {
console.log("SynthesisStarted event");
};
speechSynthesizer.synthesizing = function (s, e) {
var str = `Synthesizing event: \
\r\n\tAudioData: ${e.result.audioData.byteLength} bytes`;
console.log(str);
};
speechSynthesizer.visemeReceived = function(s, e) {
var str = `VisemeReceived event: \
\r\n\tAudioOffset: ${(e.audioOffset + 5000) / 10000}ms \
\r\n\tVisemeId: ${e.visemeId}`;
console.log(str);
};
speechSynthesizer.wordBoundary = function (s, e) {
// Word, Punctuation, or Sentence
var str = `WordBoundary event: \
\r\n\tBoundaryType: ${e.boundaryType} \
\r\n\tAudioOffset: ${(e.audioOffset + 5000) / 10000}ms \
\r\n\tDuration: ${e.duration} \
\r\n\tText: \"${e.text}\" \
\r\n\tTextOffset: ${e.textOffset} \
\r\n\tWordLength: ${e.wordLength}`;
console.log(str);
};
// Synthesize the SSML
console.log(`SSML to synthesize: \r\n ${ssml}`)
console.log(`Synthesize to: ${audioFile}`);
speechSynthesizer.speakSsmlAsync(ssml,
function (result) {
if (result.reason === sdk.ResultReason.SynthesizingAudioCompleted) {
console.log("SynthesizingAudioCompleted result");
} else {
console.error("Speech synthesis canceled, " + result.errorDetails +
"\nDid you set the speech resource key and region values?");
}
speechSynthesizer.close();
speechSynthesizer = null;
},
function (err) {
console.trace("err - " + err);
speechSynthesizer.close();
speechSynthesizer = null;
});
}());
U vindt meer tekst naar spraakvoorbeelden op GitHub.
Een container uitvoeren en gebruiken
Spraakcontainers bieden websocket-api's voor query-eindpunten die toegankelijk zijn via de Speech SDK en Speech CLI. De Speech SDK en Speech CLI maken standaard gebruik van de openbare Speech-service. Als u de container wilt gebruiken, moet u de initialisatiemethode wijzigen. Gebruik een containerhost-URL in plaats van sleutel en regio.
Zie Speech-containers installeren en uitvoeren met Docker voor meer informatie over containers.
Referentiedocumentatiepakket (download) | Aanvullende voorbeelden op GitHub |
In deze handleiding leert u algemene ontwerppatronen voor het uitvoeren van tekst-naar-spraaksynthese.
Zie Wat is tekst naar spraak voor meer informatie over de volgende gebieden ?
- Antwoorden krijgen als in-memory streams.
- Voorbeeldsnelheid en bitsnelheid van uitvoer aanpassen.
- Syntheseaanvragen verzenden met behulp van Speech Synthesis Markup Language (SSML).
- Neurale stemmen gebruiken.
- Abonneren op gebeurtenissen en reageren op resultaten.
Vereisten
- Een Azure-abonnement. U kunt er gratis een maken.
- Maak een spraakresource in Azure Portal.
- Haal de spraakresourcesleutel en -regio op. Nadat uw Spraak-resource is geïmplementeerd, selecteert u Ga naar de resource om sleutels weer te geven en te beheren.
De Speech SDK en voorbeelden installeren
De opslagplaats Azure-Samples/cognitive-services-speech-sdk bevat voorbeelden die zijn geschreven in Objective-C voor iOS en Mac. Selecteer een koppeling om de installatie-instructies voor elk voorbeeld te bekijken:
- Gesproken tekst omzetten in Objective-C in macOS
- Gesproken tekst omzetten in Objective-C in iOS
- Meer voorbeelden voor Objective-C in iOS
Een aangepast eindpunt gebruiken
Het aangepaste eindpunt is functioneel identiek aan het standaardeindpunt dat wordt gebruikt voor tekst-naar-spraakaanvragen.
Een verschil is dat het EndpointId
moet worden opgegeven om uw aangepaste stem te gebruiken via de Speech SDK. U kunt beginnen met de snelstartgids voor tekst naar spraak en vervolgens de code bijwerken met de EndpointId
en SpeechSynthesisVoiceName
.
SPXSpeechConfiguration *speechConfig = [[SPXSpeechConfiguration alloc] initWithSubscription:speechKey region:speechRegion];
speechConfig.speechSynthesisVoiceName = @"YourCustomVoiceName";
speechConfig.EndpointId = @"YourEndpointId";
Als u een aangepaste stem wilt gebruiken via Speech Synthesis Markup Language (SSML), geeft u de modelnaam op als de spraaknaam. In dit voorbeeld wordt de YourCustomVoiceName
stem gebruikt.
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
<voice name="YourCustomVoiceName">
This is the text that is spoken.
</voice>
</speak>
Een container uitvoeren en gebruiken
Spraakcontainers bieden websocket-api's voor query-eindpunten die toegankelijk zijn via de Speech SDK en Speech CLI. De Speech SDK en Speech CLI maken standaard gebruik van de openbare Speech-service. Als u de container wilt gebruiken, moet u de initialisatiemethode wijzigen. Gebruik een containerhost-URL in plaats van sleutel en regio.
Zie Speech-containers installeren en uitvoeren met Docker voor meer informatie over containers.
Referentiedocumentatiepakket (download) | Aanvullende voorbeelden op GitHub |
In deze handleiding leert u algemene ontwerppatronen voor het uitvoeren van tekst-naar-spraaksynthese.
Zie Wat is tekst naar spraak voor meer informatie over de volgende gebieden ?
- Antwoorden krijgen als in-memory streams.
- Voorbeeldsnelheid en bitsnelheid van uitvoer aanpassen.
- Syntheseaanvragen verzenden met behulp van Speech Synthesis Markup Language (SSML).
- Neurale stemmen gebruiken.
- Abonneren op gebeurtenissen en reageren op resultaten.
Vereisten
- Een Azure-abonnement. U kunt er gratis een maken.
- Maak een spraakresource in Azure Portal.
- Haal de spraakresourcesleutel en -regio op. Nadat uw Spraak-resource is geïmplementeerd, selecteert u Ga naar de resource om sleutels weer te geven en te beheren.
De Speech SDK en voorbeelden installeren
De opslagplaats Azure-Samples/cognitive-services-speech-sdk bevat voorbeelden die zijn geschreven in Swift voor iOS en Mac. Selecteer een koppeling om de installatie-instructies voor elk voorbeeld te bekijken:
Een container uitvoeren en gebruiken
Spraakcontainers bieden websocket-api's voor query-eindpunten die toegankelijk zijn via de Speech SDK en Speech CLI. De Speech SDK en Speech CLI maken standaard gebruik van de openbare Speech-service. Als u de container wilt gebruiken, moet u de initialisatiemethode wijzigen. Gebruik een containerhost-URL in plaats van sleutel en regio.
Zie Speech-containers installeren en uitvoeren met Docker voor meer informatie over containers.
Referentiedocumentatiepakket (PyPi) | Aanvullende voorbeelden op GitHub |
In deze handleiding leert u algemene ontwerppatronen voor het uitvoeren van tekst-naar-spraaksynthese.
Zie Wat is tekst naar spraak voor meer informatie over de volgende gebieden ?
- Antwoorden krijgen als in-memory streams.
- Voorbeeldsnelheid en bitsnelheid van uitvoer aanpassen.
- Syntheseaanvragen verzenden met behulp van Speech Synthesis Markup Language (SSML).
- Neurale stemmen gebruiken.
- Abonneren op gebeurtenissen en reageren op resultaten.
Synthesetaal en spraak selecteren
De functie tekst-naar-spraak in de Speech-service ondersteunt meer dan 400 stemmen en meer dan 140 talen en varianten. U kunt de volledige lijst ophalen of ze uitproberen in de spraakgalerie.
Geef de taal of stem op van SpeechConfig
uw invoertekst en gebruik de opgegeven stem:
# Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
speech_config.speech_synthesis_language = "en-US"
speech_config.speech_synthesis_voice_name ="en-US-AvaMultilingualNeural"
Alle neurale stemmen zijn meertalige en vloeiende taal en Engels. Als de invoertekst in het Engels bijvoorbeeld 'Ik ben enthousiast om tekst naar spraak te proberen' is en u selecteert es-ES-ElviraNeural
, wordt de tekst in het Engels gesproken met een Spaans accent.
Als de stem de taal van de invoertekst niet spreekt, maakt de Speech-service geen gesynthetiseerde audio. Zie Taal- en spraakondersteuning voor de Speech-service voor een volledige lijst met ondersteunde neurale stemmen.
Notitie
De standaardstem is de eerste stem die per landinstelling wordt geretourneerd vanuit de Voice List-API.
De stem die spreekt, wordt als volgt bepaald in volgorde van prioriteit:
- Als u dit niet instelt
SpeechSynthesisVoiceName
ofSpeechSynthesisLanguage
, wordt de standaardstem vooren-US
gesproken tekst gebruikt. - Als u alleen instelt
SpeechSynthesisLanguage
, spreekt de standaardstem voor de opgegeven landinstelling. - Als beide
SpeechSynthesisVoiceName
zijnSpeechSynthesisLanguage
ingesteld, wordt deSpeechSynthesisLanguage
instelling genegeerd. De stem die u opgeeft met behulp vanSpeechSynthesisVoiceName
spreekt. - Als het spraakelement is ingesteld met behulp van Speech Synthesis Markup Language (SSML), worden de
SpeechSynthesisVoiceName
enSpeechSynthesisLanguage
instellingen genegeerd.
Samengevat kan de volgorde van prioriteit worden beschreven als:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Resultaat |
---|---|---|---|
✗ | ✗ | ✗ | Standaardstem voor en-US spreken |
✗ | ✔ | ✗ | Standaardstem voor de opgegeven landinstelling spreekt. |
✔ | ✔ | ✗ | De stem die u opgeeft met behulp van SpeechSynthesisVoiceName spreekt. |
✔ | ✔ | ✔ | De stem die u opgeeft met behulp van SSML spreekt. |
Spraak synthetiseren naar een bestand
Maak een SpeechSynthesizer-object . Met dit object wordt tekst uitgevoerd naar spraakconversies en uitvoer naar luidsprekers, bestanden of andere uitvoerstromen. SpeechSynthesizer
accepteert als parameters:
- Het
SpeechConfig
object dat u in de vorige stap hebt gemaakt. - Een
AudioOutputConfig
object dat aangeeft hoe uitvoerresultaten moeten worden verwerkt.
Maak een
AudioOutputConfig
exemplaar om de uitvoer automatisch naar een .wav-bestand te schrijven met behulp van defilename
constructorparameter:audio_config = speechsdk.audio.AudioOutputConfig(filename="path/to/write/file.wav")
Instantieer
SpeechSynthesizer
door uwspeech_config
object en hetaudio_config
object als parameters door te geven. Als u spraak wilt omzetten en naar een bestand wilt schrijven, voert u deze uitspeak_text_async()
met een tekenreeks tekst.speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=audio_config) speech_synthesis_result = speech_synthesizer.speak_text_async("I'm excited to try text to speech").get()
Wanneer u het programma uitvoert, wordt er een gesynthetiseerd .wav-bestand gemaakt, dat wordt geschreven naar de locatie die u opgeeft. Dit resultaat is een goed voorbeeld van het meest eenvoudige gebruik. Vervolgens kunt u de uitvoer aanpassen en het uitvoerantwoord verwerken als een stroom in het geheugen voor het werken met aangepaste scenario's.
Synthetiseren naar de uitvoer van de luidspreker
Als u gesynthetiseerde spraak wilt uitvoeren naar het huidige actieve uitvoerapparaat zoals een luidspreker, stelt u de use_default_speaker
parameter in wanneer u het AudioOutputConfig
exemplaar maakt. Hier volgt een voorbeeld:
audio_config = speechsdk.audio.AudioOutputConfig(use_default_speaker=True)
Een resultaat ophalen als een stroom in het geheugen
U kunt de resulterende audiogegevens gebruiken als een in-memory stream in plaats van rechtstreeks naar een bestand te schrijven. Met een in-memory stream kunt u aangepast gedrag bouwen:
- Abstract de resulterende bytematrix als een zoekbare stroom voor aangepaste downstreamservices.
- Integreer het resultaat met andere API's of services.
- Wijzig de audiogegevens, schrijf aangepaste .wav headers en voer gerelateerde taken uit.
U kunt deze wijziging aanbrengen in het vorige voorbeeld. Verwijder AudioConfig
eerst, omdat u vanaf dit moment het uitvoergedrag handmatig beheert voor meer controle. Geef None
deze door AudioConfig
in de SpeechSynthesizer
constructor.
Notitie
Het doorgeven None
van AudioConfig
, in plaats van het weglaten zoals u in het vorige voorbeeld van de luidsprekeruitvoer hebt gedaan, speelt de audio niet standaard af op het huidige actieve uitvoerapparaat.
Sla het resultaat op in een SpeechSynthesisResult
variabele. De eigenschap audio_data
bevat een bytes
-object van de uitvoergegevens. U kunt handmatig met dit object werken, of u kunt de AudioDataStream
-klasse gebruiken om de stroom in het geheugen te beheren.
In dit voorbeeld gebruikt u de AudioDataStream
constructor om een stroom op te halen uit het resultaat:
speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=None)
speech_synthesis_result = speech_synthesizer.speak_text_async("I'm excited to try text to speech").get()
stream = speechsdk.AudioDataStream(speech_synthesis_result)
Op dit moment kunt u elk aangepast gedrag implementeren met behulp van het resulterende stream
object.
Audio-indeling aanpassen
U kunt kenmerken voor audio-uitvoer aanpassen, waaronder:
- Audiobestandstype
- Samplefrequentie
- Bitdiepte
Als u de audio-indeling wilt wijzigen, gebruikt u de set_speech_synthesis_output_format()
functie voor het SpeechConfig
object. Deze functie verwacht een exemplaar van het enum
type SpeechSynthesisOutputFormat. Gebruik de enum
optie om de uitvoerindeling te selecteren. Zie de lijst met audio-indelingen voor beschikbare indelingen.
Er zijn verschillende opties voor verschillende bestandstypen, afhankelijk van uw vereisten. Onbewerkte indelingen Raw24Khz16BitMonoPcm
bevatten standaard geen audioheaders. Gebruik onbewerkte indelingen alleen in een van deze situaties:
- U weet dat uw downstream-implementatie een onbewerkte bitstream kan decoderen.
- U bent van plan om handmatig headers te bouwen op basis van factoren zoals bitdiepte, samplefrequentie en aantal kanalen.
In dit voorbeeld wordt de RIFF-indeling Riff24Khz16BitMonoPcm
met hoge kwaliteit opgegeven door het object in te SpeechConfig
stellenSpeechSynthesisOutputFormat
. Net als in het voorbeeld in de vorige sectie, gebruikt u AudioDataStream
om een stroom in het geheugen van het resultaat te verkrijgen en vervolgens naar een bestand te schrijven.
speech_config.set_speech_synthesis_output_format(speechsdk.SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm)
speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=None)
speech_synthesis_result = speech_synthesizer.speak_text_async("I'm excited to try text to speech").get()
stream = speechsdk.AudioDataStream(speech_synthesis_result)
stream.save_to_wav_file("path/to/write/file.wav")
Wanneer u het programma uitvoert, wordt er een .wav-bestand naar het opgegeven pad geschreven.
SSML gebruiken om spraakkenmerken aan te passen
U kunt SSML gebruiken om de toonhoogte, uitspraak, spreeksnelheid, volume en andere aspecten in de tekst naar spraakuitvoer af te stemmen door uw aanvragen vanuit een XML-schema in te dienen. In deze sectie ziet u een voorbeeld van het wijzigen van de stem. Zie het overzicht van Speech Synthesis Markup Language voor meer informatie.
Als u SSML wilt gaan gebruiken voor aanpassing, moet u een kleine wijziging aanbrengen waarmee de stem wordt gewijzigd.
Maak een nieuw XML-bestand voor de SSML-configuratie in de hoofdprojectmap.
<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US"> <voice name="en-US-AvaMultilingualNeural"> When you're on the freeway, it's a good idea to use a GPS. </voice> </speak>
In dit voorbeeld wordt het bestand ssml.xml. Het hoofdelement is altijd
<speak>
. Als u de tekst in een<voice>
element terugloopt, kunt u de stem wijzigen met behulp van dename
parameter. Zie Ondersteunde talen voor de volledige lijst met ondersteunde neurale stemmen.Wijzig de aanvraag voor spraaksynthese om te verwijzen naar uw XML-bestand. De aanvraag is meestal hetzelfde. Gebruik in plaats van de
speak_text_async()
functiespeak_ssml_async()
. Deze functie verwacht een XML-tekenreeks. Lees eerst uw SSML-configuratie als een tekenreeks. Vanaf dit punt is het resultaatobject precies hetzelfde als eerdere voorbeelden.Notitie
Als uw
ssml_string
aan het begin van de tekenreeks
bevat, moet u de BOM-indeling verwijderen, anders wordt er een foutbericht weergegeven. U doet dit door de parameterencoding
als volgt in te stellen:open("ssml.xml", "r", encoding="utf-8-sig")
.speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=None) ssml_string = open("ssml.xml", "r").read() speech_synthesis_result = speech_synthesizer.speak_ssml_async(ssml_string).get() stream = speechsdk.AudioDataStream(speech_synthesis_result) stream.save_to_wav_file("path/to/write/file.wav")
Notitie
Als u de stem wilt wijzigen zonder SSML te gebruiken, kunt u de eigenschap SpeechConfig
instellen met behulp van speech_config.speech_synthesis_voice_name = "en-US-AvaMultilingualNeural"
.
Abonneren op synthesizer-evenementen
Mogelijk wilt u meer inzichten over de tekst naar spraakverwerking en resultaten. U wilt bijvoorbeeld weten wanneer de synthesizer start en stopt, of misschien wilt u weten over andere gebeurtenissen die tijdens de synthese zijn aangetroffen.
Tijdens het gebruik van speechSynthesizer voor tekst-naar-spraak kunt u zich abonneren op de gebeurtenissen in deze tabel:
Gebeurtenis | Beschrijving | Gebruiksscenario |
---|---|---|
BookmarkReached |
Signalen dat een bladwijzer is bereikt. Voor het activeren van een gebeurtenis die een bladwijzer heeft bereikt, is een bookmark element vereist in de SSML. Deze gebeurtenis rapporteert de verstreken tijd van de uitvoeraudio tussen het begin van de synthese en het bookmark element. De eigenschap van Text de gebeurtenis is de tekenreekswaarde die u hebt ingesteld in het kenmerk van mark de bladwijzer. De bookmark elementen worden niet gesproken. |
U kunt het bookmark element gebruiken om aangepaste markeringen in SSML in te voegen om de verschuiving van elke markering in de audiostream op te halen. Het bookmark element kan worden gebruikt om te verwijzen naar een specifieke locatie in de tekst- of tagvolgorde. |
SynthesisCanceled |
Signalen dat de spraaksynthese is geannuleerd. | U kunt bevestigen wanneer synthese wordt geannuleerd. |
SynthesisCompleted |
Signalen dat spraaksynthese is voltooid. | U kunt bevestigen wanneer de synthese is voltooid. |
SynthesisStarted |
Signalen dat spraaksynthese is gestart. | U kunt bevestigen wanneer de synthese is gestart. |
Synthesizing |
Signalen dat spraaksynthese gaande is. Deze gebeurtenis wordt geactiveerd telkens wanneer de SDK een audiosegment van de Speech-service ontvangt. | U kunt controleren wanneer de synthese wordt uitgevoerd. |
VisemeReceived |
Signalen dat er een visemegebeurtenis is ontvangen. | Visemes worden vaak gebruikt om de belangrijkste poses in geobserveerde spraak te vertegenwoordigen. Belangrijke poses zijn onder andere de positie van de lippen, de kaak en de tong bij het produceren van een bepaald telefoonme. U kunt visemes gebruiken om het gezicht van een teken te animeren terwijl spraakaudio wordt afgespeeld. |
WordBoundary |
Signalen dat een woordgrens is ontvangen. Deze gebeurtenis wordt aan het begin van elk nieuw gesproken woord, leesteken en zin gegenereerd. De gebeurtenis rapporteert de tijdsverschil van het huidige woord, in tikken, vanaf het begin van de uitvoeraudio. Deze gebeurtenis rapporteert ook de tekenpositie in de invoertekst of SSML direct voordat het woord wordt gesproken. | Deze gebeurtenis wordt vaak gebruikt om relatieve posities van de tekst en bijbehorende audio te verkrijgen. Misschien wilt u meer weten over een nieuw woord en vervolgens actie ondernemen op basis van de timing. U kunt bijvoorbeeld informatie krijgen waarmee u kunt bepalen wanneer en hoe lang woorden moeten worden gemarkeerd terwijl ze worden gesproken. |
Notitie
Gebeurtenissen worden gegenereerd wanneer de uitvoeraudiogegevens beschikbaar komen, wat sneller is dan afspelen op een uitvoerapparaat. De beller moet streaming en realtime synchroniseren.
Hier volgt een voorbeeld waarin wordt getoond hoe u zich kunt abonneren op gebeurtenissen voor spraaksynthese.
Belangrijk
Als u een API-sleutel gebruikt, slaat u deze veilig op ergens anders op, zoals in Azure Key Vault. Neem de API-sleutel niet rechtstreeks in uw code op en plaats deze nooit openbaar.
Zie Aanvragen verifiëren bij Azure AI-services voor meer informatie over beveiliging van AI-services.
U kunt de instructies in de quickstart volgen, maar de inhoud van dat speech-synthesis.py bestand vervangen door de volgende Python-code:
import os
import azure.cognitiveservices.speech as speechsdk
def speech_synthesizer_bookmark_reached_cb(evt: speechsdk.SessionEventArgs):
print('BookmarkReached event:')
print('\tAudioOffset: {}ms'.format((evt.audio_offset + 5000) / 10000))
print('\tText: {}'.format(evt.text))
def speech_synthesizer_synthesis_canceled_cb(evt: speechsdk.SessionEventArgs):
print('SynthesisCanceled event')
def speech_synthesizer_synthesis_completed_cb(evt: speechsdk.SessionEventArgs):
print('SynthesisCompleted event:')
print('\tAudioData: {} bytes'.format(len(evt.result.audio_data)))
print('\tAudioDuration: {}'.format(evt.result.audio_duration))
def speech_synthesizer_synthesis_started_cb(evt: speechsdk.SessionEventArgs):
print('SynthesisStarted event')
def speech_synthesizer_synthesizing_cb(evt: speechsdk.SessionEventArgs):
print('Synthesizing event:')
print('\tAudioData: {} bytes'.format(len(evt.result.audio_data)))
def speech_synthesizer_viseme_received_cb(evt: speechsdk.SessionEventArgs):
print('VisemeReceived event:')
print('\tAudioOffset: {}ms'.format((evt.audio_offset + 5000) / 10000))
print('\tVisemeId: {}'.format(evt.viseme_id))
def speech_synthesizer_word_boundary_cb(evt: speechsdk.SessionEventArgs):
print('WordBoundary event:')
print('\tBoundaryType: {}'.format(evt.boundary_type))
print('\tAudioOffset: {}ms'.format((evt.audio_offset + 5000) / 10000))
print('\tDuration: {}'.format(evt.duration))
print('\tText: {}'.format(evt.text))
print('\tTextOffset: {}'.format(evt.text_offset))
print('\tWordLength: {}'.format(evt.word_length))
# This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
speech_config = speechsdk.SpeechConfig(subscription=os.environ.get('SPEECH_KEY'), region=os.environ.get('SPEECH_REGION'))
# Required for WordBoundary event sentences.
speech_config.set_property(property_id=speechsdk.PropertyId.SpeechServiceResponse_RequestSentenceBoundary, value='true')
audio_config = speechsdk.audio.AudioOutputConfig(use_default_speaker=True)
speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=audio_config)
# Subscribe to events
speech_synthesizer.bookmark_reached.connect(speech_synthesizer_bookmark_reached_cb)
speech_synthesizer.synthesis_canceled.connect(speech_synthesizer_synthesis_canceled_cb)
speech_synthesizer.synthesis_completed.connect(speech_synthesizer_synthesis_completed_cb)
speech_synthesizer.synthesis_started.connect(speech_synthesizer_synthesis_started_cb)
speech_synthesizer.synthesizing.connect(speech_synthesizer_synthesizing_cb)
speech_synthesizer.viseme_received.connect(speech_synthesizer_viseme_received_cb)
speech_synthesizer.synthesis_word_boundary.connect(speech_synthesizer_word_boundary_cb)
# The language of the voice that speaks.
speech_synthesis_voice_name='en-US-AvaMultilingualNeural'
ssml = """<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>
<voice name='{}'>
<mstts:viseme type='redlips_front'/>
The rainbow has seven colors: <bookmark mark='colors_list_begin'/>Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark='colors_list_end'/>.
</voice>
</speak>""".format(speech_synthesis_voice_name)
# Synthesize the SSML
print("SSML to synthesize: \r\n{}".format(ssml))
speech_synthesis_result = speech_synthesizer.speak_ssml_async(ssml).get()
if speech_synthesis_result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
print("SynthesizingAudioCompleted result")
elif speech_synthesis_result.reason == speechsdk.ResultReason.Canceled:
cancellation_details = speech_synthesis_result.cancellation_details
print("Speech synthesis canceled: {}".format(cancellation_details.reason))
if cancellation_details.reason == speechsdk.CancellationReason.Error:
if cancellation_details.error_details:
print("Error details: {}".format(cancellation_details.error_details))
print("Did you set the speech resource key and region values?")
U vindt meer tekst naar spraakvoorbeelden op GitHub.
Een aangepast eindpunt gebruiken
Het aangepaste eindpunt is functioneel identiek aan het standaardeindpunt dat wordt gebruikt voor tekst-naar-spraakaanvragen.
Een verschil is dat het endpoint_id
moet worden opgegeven om uw aangepaste stem te gebruiken via de Speech SDK. U kunt beginnen met de snelstartgids voor tekst naar spraak en vervolgens de code bijwerken met de endpoint_id
en speech_synthesis_voice_name
.
speech_config = speechsdk.SpeechConfig(subscription=os.environ.get('SPEECH_KEY'), region=os.environ.get('SPEECH_REGION'))
speech_config.endpoint_id = "YourEndpointId"
speech_config.speech_synthesis_voice_name = "YourCustomVoiceName"
Als u een aangepaste stem wilt gebruiken via Speech Synthesis Markup Language (SSML), geeft u de modelnaam op als de spraaknaam. In dit voorbeeld wordt de YourCustomVoiceName
stem gebruikt.
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
<voice name="YourCustomVoiceName">
This is the text that is spoken.
</voice>
</speak>
Een container uitvoeren en gebruiken
Spraakcontainers bieden websocket-api's voor query-eindpunten die toegankelijk zijn via de Speech SDK en Speech CLI. De Speech SDK en Speech CLI maken standaard gebruik van de openbare Speech-service. Als u de container wilt gebruiken, moet u de initialisatiemethode wijzigen. Gebruik een containerhost-URL in plaats van sleutel en regio.
Zie Speech-containers installeren en uitvoeren met Docker voor meer informatie over containers.
Spraak-naar-tekst-REST API-verwijzing Speech to text REST API voor korte audioverwijzing | Aanvullende voorbeelden op GitHub |
In deze handleiding leert u algemene ontwerppatronen voor het uitvoeren van tekst-naar-spraaksynthese.
Zie Wat is tekst naar spraak voor meer informatie over de volgende gebieden ?
- Antwoorden krijgen als in-memory streams.
- Voorbeeldsnelheid en bitsnelheid van uitvoer aanpassen.
- Syntheseaanvragen verzenden met behulp van Speech Synthesis Markup Language (SSML).
- Neurale stemmen gebruiken.
- Abonneren op gebeurtenissen en reageren op resultaten.
Vereisten
- Een Azure-abonnement. U kunt er gratis een maken.
- Maak een spraakresource in Azure Portal.
- Haal de spraakresourcesleutel en -regio op. Nadat uw Spraak-resource is geïmplementeerd, selecteert u Ga naar de resource om sleutels weer te geven en te beheren.
Tekst naar spraak converteren
Voer de volgende opdracht uit bij een opdrachtprompt: Voeg deze waarden in de opdracht in:
- Uw spraakresourcesleutel
- Uw spraakresourceregio
U kunt ook de volgende waarden wijzigen:
- De waarde van de
X-Microsoft-OutputFormat
-header, waarmee de indeling van de audio-uitvoer wordt bepaald. U vindt een lijst met ondersteunde audio-uitvoerindelingen in de tekst-naar-spraak-REST API-verwijzing. - De stem voor de uitvoer. Zie de Spraaklijst-API voor een lijst met stemmen die beschikbaar zijn voor uw Speech-service-eindpunt.
- Het uitvoerbestand. In dit voorbeeld wordt het antwoord van de server naar het bestand
output.mp3
gestuurd.
curl --location --request POST 'https://YOUR_RESOURCE_REGION.tts.speech.microsoft.com/cognitiveservices/v1' \
--header 'Ocp-Apim-Subscription-Key: YOUR_RESOURCE_KEY' \
--header 'Content-Type: application/ssml+xml' \
--header 'X-Microsoft-OutputFormat: audio-16khz-128kbitrate-mono-mp3' \
--header 'User-Agent: curl' \
--data-raw '<speak version='\''1.0'\'' xml:lang='\''en-US'\''>
<voice name='\''en-US-AvaMultilingualNeural'\''>
I am excited to try text to speech
</voice>
</speak>' > output.mp3
In deze handleiding leert u algemene ontwerppatronen voor het uitvoeren van tekst-naar-spraaksynthese.
Zie Wat is tekst naar spraak voor meer informatie over de volgende gebieden ?
- Antwoorden krijgen als in-memory streams.
- Voorbeeldsnelheid en bitsnelheid van uitvoer aanpassen.
- Syntheseaanvragen verzenden met behulp van Speech Synthesis Markup Language (SSML).
- Neurale stemmen gebruiken.
- Abonneren op gebeurtenissen en reageren op resultaten.
Vereisten
- Een Azure-abonnement. U kunt er gratis een maken.
- Maak een spraakresource in Azure Portal.
- Haal de spraakresourcesleutel en -regio op. Nadat uw Spraak-resource is geïmplementeerd, selecteert u Ga naar de resource om sleutels weer te geven en te beheren.
Downloaden en installeren van
Volg deze stappen en bekijk de quickstart voor Speech CLI voor andere vereisten voor uw platform.
Voer de volgende .NET CLI-opdracht uit om de Speech CLI te installeren:
dotnet tool install --global Microsoft.CognitiveServices.Speech.CLI
Voer de volgende opdrachten uit om uw Spraak-resourcesleutel en -regio te configureren. Vervang door
SUBSCRIPTION-KEY
uw Spraak-resourcesleutel en vervang deze doorREGION
de spraakresourceregio.spx config @key --set SUBSCRIPTION-KEY spx config @region --set REGION
Spraaksynthese naar een luidspreker
Nu bent u klaar om de Speech CLI uit te voeren om tekst om te zetten in spraak.
Ga in een consolevenster naar de map met het binaire Speech CLI-bestand. Voer vervolgens de volgende opdracht uit:
spx synthesize --text "I'm excited to try text to speech"
De Speech CLI produceert natuurlijke taal in het Engels via de computer spreker.
Spraak synthetiseren naar een bestand
Voer de volgende opdracht uit om de uitvoer van uw luidspreker te wijzigen in een .wav-bestand :
spx synthesize --text "I'm excited to try text to speech" --audio output greetings.wav
De Speech CLI produceert natuurlijke taal in het Engels naar het greetings.wav audiobestand.
Een container uitvoeren en gebruiken
Spraakcontainers bieden websocket-api's voor query-eindpunten die toegankelijk zijn via de Speech SDK en Speech CLI. De Speech SDK en Speech CLI maken standaard gebruik van de openbare Speech-service. Als u de container wilt gebruiken, moet u de initialisatiemethode wijzigen. Gebruik een containerhost-URL in plaats van sleutel en regio.
Zie Speech-containers installeren en uitvoeren met Docker voor meer informatie over containers.