Synthetisieren von Sprache aus Text
Referenzdokumentation | Paket (NuGet) | Zusätzliche Beispiele auf GitHub
In dieser Schrittanleitung werden gängige Entwurfsmuster für die Sprachsynthese vorgestellt.
Weitere Informationen zu den folgenden Bereichen finden Sie unter Was ist Sprachsynthese?.
- Abrufen von Antworten als In-Memory-Datenströme
- Anpassen der Abtast- und Bitrate der Ausgabe
- Übermitteln von Syntheseanforderungen mithilfe der Markupsprache für Sprachsynthese (Speech Synthesis Markup Language, SSML)
- Verwenden neuronaler Stimmen
- Abonnieren von Ereignissen und ergebnisbezogenes Handeln
Auswählen von Synthesesprache und Stimme
Das Feature für die Sprachsynthese im Speech-Dienst unterstützt mehr als 400 Stimmen und über 140 Sprachen und Varianten. Sie können die vollständige Liste abrufen oder sie im Stimmkatalog ausprobieren.
Geben Sie die Sprache oder Stimme von SpeechConfig
entsprechend Ihres Eingabetexts an, und verwenden Sie die festgelegte Stimme. Der folgende Codeschnipsel zeigt, wie dieses Verfahren funktioniert:
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 neuronalen Stimmen sind mehrsprachig und können in ihrer eigenen Sprache und in englischer Sprache sprechen. Wenn der Eingabetext auf Englisch beispielsweise „I'm excited to try text to speech“ lautet und Sie es-ES-ElviraNeural
auswählen, wird der Text in englischer Sprache mit einem spanischen Akzent gesprochen.
Wenn die Stimme nicht die Sprache des Eingabetexts spricht, wird keine synthetisierte Audioausgabe vom Speech-Dienst erstellt. Eine vollständige Liste der unterstützten neuronalen Stimmen finden Sie unter Sprach- und Stimmunterstützung für den Speech-Dienst.
Hinweis
Die Standardstimme ist die erste Stimme, die pro Gebietsschema von der Stimmlisten-API zurückgegeben wird.
Die Stimme, die spricht, wird wie folgt nach ihrer Priorität bestimmt:
- Wenn Sie weder
SpeechSynthesisVoiceName
nochSpeechSynthesisLanguage
festlegen, spricht die Standardstimme füren-US
. - Wenn Sie nur
SpeechSynthesisLanguage
festlegen, spricht die Standardstimme für das angegebene Gebietsschema. - Wenn sowohl
SpeechSynthesisVoiceName
als auchSpeechSynthesisLanguage
festgelegt sind, wird die EinstellungSpeechSynthesisLanguage
ignoriert. Die Stimme, die Sie mithilfe vonSpeechSynthesisVoiceName
angeben, spricht. - Wenn das Stimmelement über Speech Synthesis Markup Language (SSML) festgelegt wird, werden die Einstellungen
SpeechSynthesisVoiceName
undSpeechSynthesisLanguage
ignoriert.
Zusammenfassend kann die Reihenfolge der Priorität wie folgt beschrieben werden:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Ergebnis |
---|---|---|---|
✗ | ✗ | ✗ | Die Standardstimme für en-US spricht. |
✗ | ✔ | ✗ | Die Standardstimme für das angegebene Gebietsschema spricht. |
✔ | ✔ | ✗ | Die Stimme, die Sie mithilfe von SpeechSynthesisVoiceName angeben, spricht. |
✔ | ✔ | ✔ | Die Stimme, die Sie mithilfe von SSML angeben, spricht. |
Synthetisieren von Sprache in eine Datei
Erstellen Sie ein SpeechSynthesizer-Objekt. Das in den folgenden Codeschnipseln gezeigte Objekt führt die Konvertierungen von Text in Sprache und Ausgaben an Lautsprecher, in Dateien oder andere Ausgabestreams aus. SpeechSynthesizer
akzeptiert folgende Parameter:
- Das SpeechConfig-Objekt, das Sie im vorherigen Schritt erstellt haben
- Ein AudioConfig-Objekt, das angibt, wie Ausgabeergebnisse verarbeitet werden sollen
Erstellen Sie eine
AudioConfig
-Instanz, um die Ausgabe mithilfe der FunktionFromWavFileOutput()
automatisch in eine WAV-Datei zu schreiben. Instanziieren Sie sie mit einerusing
-Anweisung.static async Task SynthesizeAudioAsync() { var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion"); using var audioConfig = AudioConfig.FromWavFileOutput("path/to/write/file.wav"); }
Eine
using
-Anweisung in diesem Kontext gibt automatisch nicht verwaltete Ressourcen frei und führt dazu, dass das Objekt nach der Freigabe nicht mehr zum Geltungsbereich gehört.Instanziieren Sie mit einer weiteren
using
-Anweisung eineSpeechSynthesizer
-Instanz. Übergeben Sie diespeechConfig
- undaudioConfig
-Objekte als Parameter. Um Sprache zu synthetisieren und in eine Datei zu schreiben, führen SieSpeakTextAsync()
mit einer Textzeichenfolge aus.
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");
}
Wenn Sie das Programm ausführen, wird eine synthetisierte WAV-Datei erstellt, die an den von Ihnen angegebenen Speicherort geschrieben wird. Dieses Ergebnis ist ein gutes Beispiel für die einfachste Verwendungsmöglichkeit. Als Nächstes können Sie die Ausgabe anpassen und die Ausgabeantwort als In-Memory-Datenstrom für benutzerdefinierte Szenarios verarbeiten.
Synthetisieren der Lautsprecherausgabe
Zum Ausgeben von synthetisierter Sprache auf dem aktuell aktiven Ausgabegerät wie einem Lautsprecher lassen Sie den Parameter AudioConfig
weg, wenn Sie die SpeechSynthesizer
-Instanz erstellen. Hier sehen Sie ein Beispiel:
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");
}
Abrufen eines Ergebnisses als In-Memory-Datenstrom
Sie können die resultierenden Audiodaten als einen In-Memory-Datenstrom verwenden, statt sie direkt in eine Datei zu schreiben. Mit einem In-Memory-Datenstrom können Sie benutzerdefiniertes Verhalten erstellen:
- Abstrahieren des resultierenden Bytearrays als durchsuchbaren Datenstrom für benutzerdefinierte Downstreamdienste
- Integrieren des Ergebnisses in andere APIs oder Dienste
- Ändern Sie die Audiodaten, schreiben Sie benutzerdefinierte WAV-Header, und erledigen Sie zugehörige Aufgaben.
Sie können diese Änderung am vorherigen Beispiel vornehmen. Entfernen Sie zunächst den AudioConfig
-Block, da Sie das Ausgabeverhalten ab jetzt manuell verwalten, um eine bessere Kontrolle zu erzielen. Übergeben Sie im SpeechSynthesizer
-Konstruktor null
für AudioConfig
.
Hinweis
Wenn Sie null
für AudioConfig
übergeben, anstatt den Parameter wie im obigen Beispiel für die Lautsprecherausgabe wegzulassen, werden die Audiodaten nicht standardmäßig auf dem derzeit aktiven Ausgabegerät wiedergegeben.
Speichern Sie das Ergebnis in einer SpeechSynthesisResult-Variablen. Die AudioData
-Eigenschaft enthält eine byte []
-Instanz für die Ausgabedaten. Sie können diese byte []
-Instanz manuell nutzen oder die AudioDataStream-Klasse verwenden, um den In-Memory-Datenstrom zu verwalten.
In diesem Beispiel verwenden Sie die statische Funktion AudioDataStream.FromResult()
, um einen Datenstrom aus dem Ergebnis abzurufen:
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);
}
Nun können Sie mit dem resultierenden stream
-Objekt ein beliebiges benutzerdefiniertes Verhalten implementieren.
Anpassen des Audioformats
Sie können die Attribute der Audioausgabe anpassen, z. B.:
- Audiodateityp
- Samplingrate
- Bittiefe
Zum Ändern des Audioformats wenden Sie die Funktion SetSpeechSynthesisOutputFormat()
auf das Objekt SpeechConfig
an. Diese Funktion erwartet eine enum
-Instanz vom Typ SpeechSynthesisOutputFormat. Verwenden Sie enum
, um das Ausgabeformat auszuwählen. Informationen zu den verfügbaren Formaten finden Sie in der Liste der Audioformate.
Abhängig von Ihren Anforderungen stehen Ihnen verschiedene Optionen für unterschiedliche Dateitypen zur Verfügung. Rohformate wie Raw24Khz16BitMonoPcm
enthalten gemäß Definition keine Audioheader. Verwenden Sie Rohformate nur in den folgenden Situationen:
- Sie wissen, dass Ihre Downstreamimplementierung einen unformatierten Bitstream decodieren kann.
- Sie planen, Header basierend auf Faktoren wie Bittiefe, Abtastrate und Anzahl von Kanälen manuell zu erstellen.
In diesem Beispiel wird das High-Fidelity-RIFF-Format Riff24Khz16BitMonoPcm
angegeben, indem SpeechSynthesisOutputFormat
für das SpeechConfig
-Objekt festgelegt wird. Ähnlich wie im Beispiel im vorherigen Abschnitt nutzen Sie AudioDataStream, um einen In-Memory-Datenstrom des Ergebnisses abzurufen, den Sie anschließend in eine Datei schreiben.
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");
}
Wenn Sie das Programm ausführen, schreibt es eine WAV-Datei in den angegebenen Pfad.
Verwenden von SSML zum Anpassen von Sprachmerkmalen
Mit SSML können Sie die Tonhöhe, Aussprache, Sprechgeschwindigkeit, Lautstärke und andere Aspekte der Ausgabe der Sprachsynthese optimieren, indem Sie Ihre Anforderungen per XML-Schema übermitteln. Dieser Abschnitt enthält ein Beispiel für das Ändern der Stimme. Weitere Informationen finden Sie unter Übersicht über Speech Synthesis Markup Language.
Wenn Sie SSML für die Anpassung nutzen möchten, nehmen Sie eine geringfügige Änderung vor, um die Stimme zu wechseln.
Erstellen Sie im Stammverzeichnis des Projekts eine neue XML-Datei für die SSML-Konfiguration.
<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 diesem Beispiel ist die Datei ssml.xml. Das Stammelement ist immer
<speak>
. Indem Sie den Text in einem<voice>
-Element umschließen, können Sie die Stimme mit demname
-Parameter ändern. Eine vollständige Liste der unterstützten neuronalen Stimmen finden Sie unter Unterstützte Sprachen.Ändern Sie die Anforderung der Sprachsynthese so, dass darin auf Ihre XML-Datei verwiesen wird. Die Anforderung bleibt größtenteils unverändert, aber Sie verwenden nun
SpeakSsmlAsync()
anstelle vonSpeakTextAsync()
. Diese Funktion erwartet eine XML-Zeichenfolge. Laden Sie zunächst mithilfe vonFile.ReadAllText()
Ihre SSML-Konfiguration als Zeichenfolge. Ab diesem Punkt stimmt das resultierende Objekt genau mit den Objekten in den vorherigen Beispielen überein.Hinweis
Wenn Sie Visual Studio verwenden, findet Ihre Buildkonfiguration die XML-Datei wahrscheinlich nicht standardmäßig. Klicken Sie mit der rechten Maustaste auf die XML-Datei, und wählen Sie Eigenschaften aus. Ändern Sie Buildaktion in Inhalt. Ändern Sie die Einstellung In Ausgabeverzeichnis kopieren in Immer kopieren.
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"); }
Hinweis
Wenn Sie die Stimme ohne SSML ändern möchten, können Sie die Eigenschaft für SpeechConfig
mithilfe von SpeechConfig.SpeechSynthesisVoiceName = "en-US-AvaMultilingualNeural";
festlegen.
Abonnieren von Synthesizerereignissen
Sie sollten mehr über die Sprachsyntheseverarbeitung und die Ergebnisse erfahren. Beispielsweise möchten Sie vielleicht wissen, wann der Synthesizer beginnt und anhält, oder Sie möchten wissen, welche anderen Ereignisse während der Synthese auftreten.
Wenn Sie den SpeechSynthesizer für die Sprachsynthese verwenden, können Sie die Ereignisse in dieser Tabelle abonnieren:
Ereignis | BESCHREIBUNG | Anwendungsfall |
---|---|---|
BookmarkReached |
Signalisiert, dass eine Textmarke erreicht wurde. Zum Auslösen eines Textmarke-erreicht-Ereignisses ist im SSML ein bookmark -Element erforderlich. Dieses Ereignis meldet die verstrichene Audioausgabezeit zwischen dem Beginn der Synthese und dem bookmark -Element. Die Eigenschaft Text des Ereignisses ist der Zeichenfolgenwert, den Sie im Attribut mark der Textmarke festlegen. Die bookmark -Elemente werden nicht ausgesprochen. |
Sie können das bookmark -Element verwenden, um benutzerdefinierte Marker in SSML einzufügen, um den Offset der einzelnen Marker im Audiostream abzurufen. Das bookmark -Element kann verwendet werden, um auf eine bestimmte Position in der Text- oder Tagsequenz zu verweisen. |
SynthesisCanceled |
Zeigt an, dass die Sprachsynthese abgebrochen wurde. | Sie können bestätigen, wann die Synthese abgebrochen wird. |
SynthesisCompleted |
Zeigt an, dass die Sprachsynthese vollständig ist. | Sie können bestätigen, wenn die Synthese abgeschlossen wurde. |
SynthesisStarted |
Zeigt an, dass die Sprachsynthese begonnen hat. | Sie können bestätigen, wenn die Synthese begonnen hat. |
Synthesizing |
Zeigt an, dass die Sprachsynthese fortgesetzt wird. Dieses Ereignis wird jedes Mal ausgelöst, wenn das SDK einen Audioabschnitt vom Speech-Dienst empfängt. | Sie können bestätigen, wenn die Synthese aktuell ausgeführt wird. |
VisemeReceived |
Zeigt an, dass ein Visemereignis empfangen wurde. | Viseme (Mundbilder) werden häufig verwendet, um die wichtigsten Gesichtsausdrücke beim Sprechen darzustellen. Sie umfassen u. a. die Position der Lippen, des Kiefers und der Zunge beim Erzeugen eines bestimmten Phonems. Sie können Viseme (Mundbilder) anwenden, um das Gesicht einer Figur zu animieren, wenn die Audiodatei abgespielt wird. |
WordBoundary |
Zeigt an, dass eine Wortgrenze empfangen wurde. Dieses Ereignis wird am Anfang jedes neuen gesprochenen Worts, beim Erreichen von Satzzeichen und am Satzanfang ausgelöst. Das Ereignis meldet den Zeitoffset des aktuellen Worts (in Ticks) vom Anfang der Audioausgabe. Dieses Ereignis meldet außerdem die Zeichenposition im Eingabetext (oder SSML) unmittelbar vor dem Wort, das als Nächstes gesprochen wird. | Dieses Ereignis wird häufig verwendet, um die relativen Positionen von Text und den entsprechenden Audiodaten abzurufen. Es kann sinnvoll sein, Informationen zu einem neuen Wort zu empfangen und dann auf der Grundlage des Timings Aktionen auszuführen. Sie können z. B. Informationen abrufen, die Sie bei der Entscheidung unterstützen, wann und wie lange Wörter beim Sprechen hervorgehoben werden sollen. |
Hinweis
Ereignisse werden ausgelöst, wenn die ausgegebenen Audiodaten verfügbar werden, was schneller passiert als die Wiedergabe über ein Ausgabegerät. Der Aufrufer muss das Streaming ordnungsgemäß und in Echtzeit synchronisieren.
Dieses Beispiel zeigt, wie Ereignisse für die Sprachsynthese abonniert werden.
Wichtig
Wenn Sie einen API-Schlüssel verwenden, speichern Sie ihn an einer anderen Stelle sicher, z. B. in Azure Key Vault. Fügen Sie den API-Schlüssel nicht direkt in Ihren Code ein, und machen Sie ihn nicht öffentlich zugänglich.
Weitere Informationen zur Sicherheit von KI Services finden Sie unter Authentifizieren von Anforderungen an Azure KI Services.
Sie können die Anweisungen im Schnellstart befolgen, aber den Inhalt dieser Program.cs-Datei durch den folgenden C#-Code ersetzen:
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();
}
}
Weitere Beispiele zur Sprachsynthese finden Sie auf GitHub.
Verwenden Sie einen benutzerdefinierten Endpunkt
Der benutzerdefinierte Endpunkt verfügt über dieselben Funktionen wie der Standardendpunkt für Sprachsynthese-API-Anforderungen.
Ein Unterschied besteht darin, dass die EndpointId
angegeben werden muss, wenn Ihre benutzerdefinierte Stimme über das Speech SDK verwendet werden soll. Sie können mit dem Sprachsynthese-Schnellstart beginnen und dann den Code mit EndpointId
und SpeechSynthesisVoiceName
aktualisieren.
var speechConfig = SpeechConfig.FromSubscription(speechKey, speechRegion);
speechConfig.SpeechSynthesisVoiceName = "YourCustomVoiceName";
speechConfig.EndpointId = "YourEndpointId";
Zum Verwenden einer benutzerdefinierten Stimme mithilfe von Speech Synthesis Markup Language (SSML) geben Sie den Modellnamen als Stimmnamen an. In diesem Beispiel wird die Stimme YourCustomVoiceName
verwendet.
<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>
Ausführen und Verwenden eines Containers
Speech-Container bieten websocketbasierte Abfrageendpunkt-APIs, auf die über das Speech SDK und die Speech-CLI zugegriffen wird. Standardmäßig verwenden das Speech SDK und die Speech-CLI den öffentlichen Speech-Dienst. Um den Container verwenden zu können, müssen Sie die Initialisierungsmethode ändern. Verwenden Sie eine Containerhost-URL anstelle von Schlüssel und Region.
Weitere Informationen zu Containern finden Sie unter Installieren und Ausführen von Speech-Containern mit Docker.
Referenzdokumentation | Paket (NuGet) | Zusätzliche Beispiele auf GitHub
In dieser Schrittanleitung werden gängige Entwurfsmuster für die Sprachsynthese vorgestellt.
Weitere Informationen zu den folgenden Bereichen finden Sie unter Was ist Sprachsynthese?.
- Abrufen von Antworten als In-Memory-Datenströme
- Anpassen der Abtast- und Bitrate der Ausgabe
- Übermitteln von Syntheseanforderungen mithilfe der Markupsprache für Sprachsynthese (Speech Synthesis Markup Language, SSML)
- Verwenden neuronaler Stimmen
- Abonnieren von Ereignissen und ergebnisbezogenes Handeln
Auswählen von Synthesesprache und Stimme
Das Feature für die Sprachsynthese im Speech-Dienst unterstützt mehr als 400 Stimmen und über 140 Sprachen und Varianten. Weitere Informationen finden Sie in der vollständigen Liste der unterstützten regionalen Sprachen für die Sprachsynthese. Sie können sie auch im Stimmkatalog ausprobieren.
Geben Sie die Sprache oder Stimme der SpeechConfig-Klasse entsprechend Ihres Eingabetexts an, und verwenden Sie die festgelegte Stimme. Der folgende Codeschnipsel zeigt, wie dieses Verfahren funktioniert:
void synthesizeSpeech()
{
auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
// Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
speechConfig->SetSpeechSynthesisLanguage("en-US");
speechConfig->SetSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural");
}
Alle neuronalen Stimmen sind mehrsprachig und können in ihrer eigenen Sprache und in englischer Sprache sprechen. Wenn der Eingabetext auf Englisch beispielsweise „I'm excited to try text to speech“ lautet und Sie es-ES-ElviraNeural
auswählen, wird der Text in englischer Sprache mit einem spanischen Akzent gesprochen.
Wenn die Stimme nicht die Sprache des Eingabetexts spricht, wird keine synthetisierte Audioausgabe vom Speech-Dienst erstellt. Eine vollständige Liste der unterstützten neuronalen Stimmen finden Sie unter Sprach- und Stimmunterstützung für den Speech-Dienst.
Hinweis
Die Standardstimme ist die erste Stimme, die pro Gebietsschema von der Stimmlisten-API zurückgegeben wird.
Die Stimme, die spricht, wird wie folgt nach ihrer Priorität bestimmt:
- Wenn Sie weder
SpeechSynthesisVoiceName
nochSpeechSynthesisLanguage
festlegen, spricht die Standardstimme füren-US
. - Wenn Sie nur
SpeechSynthesisLanguage
festlegen, spricht die Standardstimme für das angegebene Gebietsschema. - Wenn sowohl
SpeechSynthesisVoiceName
als auchSpeechSynthesisLanguage
festgelegt sind, wird die EinstellungSpeechSynthesisLanguage
ignoriert. Die Stimme, die Sie mithilfe vonSpeechSynthesisVoiceName
angeben, spricht. - Wenn das Stimmelement über Speech Synthesis Markup Language (SSML) festgelegt wird, werden die Einstellungen
SpeechSynthesisVoiceName
undSpeechSynthesisLanguage
ignoriert.
Zusammenfassend kann die Reihenfolge der Priorität wie folgt beschrieben werden:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Ergebnis |
---|---|---|---|
✗ | ✗ | ✗ | Die Standardstimme für en-US spricht. |
✗ | ✔ | ✗ | Die Standardstimme für das angegebene Gebietsschema spricht. |
✔ | ✔ | ✗ | Die Stimme, die Sie mithilfe von SpeechSynthesisVoiceName angeben, spricht. |
✔ | ✔ | ✔ | Die Stimme, die Sie mithilfe von SSML angeben, spricht. |
Synthetisieren von Sprache in eine Datei
Erstellen Sie ein SpeechSynthesizer-Objekt. Das in den folgenden Codeschnipseln gezeigte Objekt führt die Konvertierungen von Text in Sprache und Ausgaben an Lautsprecher, in Dateien oder andere Ausgabestreams aus. SpeechSynthesizer
akzeptiert folgende Parameter:
- Das SpeechConfig-Objekt, das Sie im vorherigen Schritt erstellt haben
- Ein AudioConfig-Objekt, das angibt, wie Ausgabeergebnisse verarbeitet werden sollen
Erstellen Sie eine
AudioConfig
-Instanz, um die Ausgabe mithilfe der FunktionFromWavFileOutput()
automatisch in eine WAV-Datei zu schreiben:void synthesizeSpeech() { auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion"); auto audioConfig = AudioConfig::FromWavFileOutput("path/to/write/file.wav"); }
Instanziieren Sie eine
SpeechSynthesizer
-Instanz. Übergeben Sie diespeechConfig
- undaudioConfig
-Objekte als Parameter. Um Sprache zu synthetisieren und in eine Datei zu schreiben, führen SieSpeakTextAsync()
mit einer Textzeichenfolge aus.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(); }
Wenn Sie das Programm ausführen, wird eine synthetisierte WAV-Datei erstellt, die an den von Ihnen angegebenen Speicherort geschrieben wird. Dieses Ergebnis ist ein gutes Beispiel für die einfachste Verwendungsmöglichkeit. Als Nächstes können Sie die Ausgabe anpassen und die Ausgabeantwort als In-Memory-Datenstrom für benutzerdefinierte Szenarios verarbeiten.
Synthetisieren der Lautsprecherausgabe
Zum Ausgeben von synthetisierter Sprache auf dem aktuell aktiven Ausgabegerät wie einem Lautsprecher lassen Sie den Parameter AudioConfig
weg, wenn Sie die SpeechSynthesizer
-Instanz erstellen. Ein Beispiel:
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();
}
Abrufen eines Ergebnisses als In-Memory-Datenstrom
Sie können die resultierenden Audiodaten als einen In-Memory-Datenstrom verwenden, statt sie direkt in eine Datei zu schreiben. Mit einem In-Memory-Datenstrom können Sie benutzerdefiniertes Verhalten erstellen:
- Abstrahieren des resultierenden Bytearrays als durchsuchbaren Datenstrom für benutzerdefinierte Downstreamdienste
- Integrieren des Ergebnisses in andere APIs oder Dienste
- Ändern Sie die Audiodaten, schreiben Sie benutzerdefinierte WAV-Header, und erledigen Sie zugehörige Aufgaben.
Sie können diese Änderung am vorherigen Beispiel vornehmen. Entfernen Sie zunächst den AudioConfig
-Block, da Sie das Ausgabeverhalten ab jetzt manuell verwalten, um eine bessere Kontrolle zu erzielen. Übergeben Sie im SpeechSynthesizer
-Konstruktor NULL
für AudioConfig
.
Hinweis
Wenn Sie NULL
für AudioConfig
übergeben, anstatt den Parameter wie im obigen Beispiel für die Lautsprecherausgabe wegzulassen, werden die Audiodaten nicht standardmäßig auf dem derzeit aktiven Ausgabegerät wiedergegeben.
Speichern Sie das Ergebnis in einer SpeechSynthesisResult-Variablen. Der GetAudioData
-Getter gibt eine byte []
-Instanz für die Ausgabedaten zurück. Sie können diese byte []
-Instanz manuell nutzen oder die AudioDataStream-Klasse verwenden, um den In-Memory-Datenstrom zu verwalten.
In diesem Beispiel verwenden Sie die statische Funktion AudioDataStream.FromResult()
, um einen Datenstrom aus dem Ergebnis abzurufen:
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);
}
Nun können Sie mit dem resultierenden stream
-Objekt ein beliebiges benutzerdefiniertes Verhalten implementieren.
Anpassen des Audioformats
Sie können die Attribute der Audioausgabe anpassen, z. B.:
- Audiodateityp
- Samplingrate
- Bittiefe
Zum Ändern des Audioformats wenden Sie die Funktion SetSpeechSynthesisOutputFormat()
auf das Objekt SpeechConfig
an. Diese Funktion erwartet eine enum
-Instanz vom Typ SpeechSynthesisOutputFormat. Verwenden Sie enum
, um das Ausgabeformat auszuwählen. Informationen zu den verfügbaren Formaten finden Sie in der Liste der Audioformate.
Abhängig von Ihren Anforderungen stehen Ihnen verschiedene Optionen für unterschiedliche Dateitypen zur Verfügung. Rohformate wie Raw24Khz16BitMonoPcm
enthalten gemäß Definition keine Audioheader. Verwenden Sie Rohformate nur in den folgenden Situationen:
- Sie wissen, dass Ihre Downstreamimplementierung einen unformatierten Bitstream decodieren kann.
- Sie planen, Header basierend auf Faktoren wie Bittiefe, Abtastrate und Anzahl von Kanälen manuell zu erstellen.
In diesem Beispiel wird das High-Fidelity-RIFF-Format Riff24Khz16BitMonoPcm
angegeben, indem SpeechSynthesisOutputFormat
für das SpeechConfig
-Objekt festgelegt wird. Ähnlich wie im Beispiel im vorherigen Abschnitt nutzen Sie AudioDataStream
, um einen InMemory-Datenstrom des Ergebnisses zu erhalten, das Sie anschließend in eine Datei schreiben.
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();
}
Wenn Sie das Programm ausführen, schreibt es eine WAV-Datei in den angegebenen Pfad.
Verwenden von SSML zum Anpassen von Sprachmerkmalen
Mit SSML können Sie die Tonhöhe, Aussprache, Sprechgeschwindigkeit, Lautstärke und andere Aspekte der Ausgabe der Sprachsynthese optimieren, indem Sie Ihre Anforderungen per XML-Schema übermitteln. Dieser Abschnitt enthält ein Beispiel für das Ändern der Stimme. Weitere Informationen finden Sie unter Übersicht über Speech Synthesis Markup Language.
Wenn Sie SSML für die Anpassung nutzen möchten, nehmen Sie eine geringfügige Änderung vor, um die Stimme zu wechseln.
Erstellen Sie im Stammverzeichnis des Projekts eine neue XML-Datei für die SSML-Konfiguration.
<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 diesem Beispiel ist die Datei ssml.xml. Das Stammelement ist immer
<speak>
. Indem Sie den Text in einem<voice>
-Element umschließen, können Sie die Stimme mit demname
-Parameter ändern. Eine vollständige Liste der unterstützten neuronalen Stimmen finden Sie unter Unterstützte Sprachen.Ändern Sie die Anforderung der Sprachsynthese so, dass darin auf Ihre XML-Datei verwiesen wird. Die Anforderung ist größtenteils identisch. Anstatt die
SpeakTextAsync()
-Funktion zu verwenden, verwenden SieSpeakSsmlAsync()
. Diese Funktion erwartet eine XML-Zeichenfolge. Laden Sie zunächst Ihre SSML-Konfiguration als Zeichenfolge. Ab diesem Punkt stimmt das resultierende Objekt genau mit den Objekten in den vorherigen Beispielen überein.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(); }
Hinweis
Wenn Sie die Stimme ohne SSML ändern möchten, können Sie die Eigenschaft für SpeechConfig
mithilfe von SpeechConfig.SetSpeechSynthesisVoiceName("en-US-AndrewMultilingualNeural")
festlegen.
Abonnieren von Synthesizerereignissen
Sie sollten mehr über die Sprachsyntheseverarbeitung und die Ergebnisse erfahren. Beispielsweise möchten Sie vielleicht wissen, wann der Synthesizer beginnt und anhält, oder Sie möchten wissen, welche anderen Ereignisse während der Synthese auftreten.
Wenn Sie den SpeechSynthesizer für die Sprachsynthese verwenden, können Sie die Ereignisse in dieser Tabelle abonnieren:
Ereignis | BESCHREIBUNG | Anwendungsfall |
---|---|---|
BookmarkReached |
Signalisiert, dass eine Textmarke erreicht wurde. Zum Auslösen eines Textmarke-erreicht-Ereignisses ist im SSML ein bookmark -Element erforderlich. Dieses Ereignis meldet die verstrichene Audioausgabezeit zwischen dem Beginn der Synthese und dem bookmark -Element. Die Eigenschaft Text des Ereignisses ist der Zeichenfolgenwert, den Sie im Attribut mark der Textmarke festlegen. Die bookmark -Elemente werden nicht ausgesprochen. |
Sie können das bookmark -Element verwenden, um benutzerdefinierte Marker in SSML einzufügen, um den Offset der einzelnen Marker im Audiostream abzurufen. Das bookmark -Element kann verwendet werden, um auf eine bestimmte Position in der Text- oder Tagsequenz zu verweisen. |
SynthesisCanceled |
Zeigt an, dass die Sprachsynthese abgebrochen wurde. | Sie können bestätigen, wann die Synthese abgebrochen wird. |
SynthesisCompleted |
Zeigt an, dass die Sprachsynthese vollständig ist. | Sie können bestätigen, wenn die Synthese abgeschlossen wurde. |
SynthesisStarted |
Zeigt an, dass die Sprachsynthese begonnen hat. | Sie können bestätigen, wenn die Synthese begonnen hat. |
Synthesizing |
Zeigt an, dass die Sprachsynthese fortgesetzt wird. Dieses Ereignis wird jedes Mal ausgelöst, wenn das SDK einen Audioabschnitt vom Speech-Dienst empfängt. | Sie können bestätigen, wenn die Synthese aktuell ausgeführt wird. |
VisemeReceived |
Zeigt an, dass ein Visemereignis empfangen wurde. | Viseme (Mundbilder) werden häufig verwendet, um die wichtigsten Gesichtsausdrücke beim Sprechen darzustellen. Sie umfassen u. a. die Position der Lippen, des Kiefers und der Zunge beim Erzeugen eines bestimmten Phonems. Sie können Viseme (Mundbilder) anwenden, um das Gesicht einer Figur zu animieren, wenn die Audiodatei abgespielt wird. |
WordBoundary |
Zeigt an, dass eine Wortgrenze empfangen wurde. Dieses Ereignis wird am Anfang jedes neuen gesprochenen Worts, beim Erreichen von Satzzeichen und am Satzanfang ausgelöst. Das Ereignis meldet den Zeitoffset des aktuellen Worts (in Ticks) vom Anfang der Audioausgabe. Dieses Ereignis meldet außerdem die Zeichenposition im Eingabetext (oder SSML) unmittelbar vor dem Wort, das als Nächstes gesprochen wird. | Dieses Ereignis wird häufig verwendet, um die relativen Positionen von Text und den entsprechenden Audiodaten abzurufen. Es kann sinnvoll sein, Informationen zu einem neuen Wort zu empfangen und dann auf der Grundlage des Timings Aktionen auszuführen. Sie können z. B. Informationen abrufen, die Sie bei der Entscheidung unterstützen, wann und wie lange Wörter beim Sprechen hervorgehoben werden sollen. |
Hinweis
Ereignisse werden ausgelöst, wenn die ausgegebenen Audiodaten verfügbar werden, was schneller passiert als die Wiedergabe über ein Ausgabegerät. Der Aufrufer muss das Streaming ordnungsgemäß und in Echtzeit synchronisieren.
Dieses Beispiel zeigt, wie Ereignisse für die Sprachsynthese abonniert werden.
Wichtig
Wenn Sie einen API-Schlüssel verwenden, speichern Sie ihn an einer anderen Stelle sicher, z. B. in Azure Key Vault. Fügen Sie den API-Schlüssel nicht direkt in Ihren Code ein, und machen Sie ihn nicht öffentlich zugänglich.
Weitere Informationen zur Sicherheit von KI Services finden Sie unter Authentifizieren von Anforderungen an Azure KI Services.
Sie können die Anweisungen im Schnellstart befolgen, aber den Inhalt dieser main.cpp-Datei durch den folgenden Code ersetzen:
#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
}
Weitere Beispiele zur Sprachsynthese finden Sie auf GitHub.
Verwenden Sie einen benutzerdefinierten Endpunkt
Der benutzerdefinierte Endpunkt verfügt über dieselben Funktionen wie der Standardendpunkt für Sprachsynthese-Anforderungen.
Ein Unterschied besteht darin, dass die EndpointId
angegeben werden muss, wenn Ihre benutzerdefinierte Stimme über das Speech SDK verwendet werden soll. Sie können mit dem Sprachsynthese-Schnellstart beginnen und dann den Code mit EndpointId
und SpeechSynthesisVoiceName
aktualisieren.
auto speechConfig = SpeechConfig::FromSubscription(speechKey, speechRegion);
speechConfig->SetSpeechSynthesisVoiceName("YourCustomVoiceName");
speechConfig->SetEndpointId("YourEndpointId");
Zum Verwenden einer benutzerdefinierten Stimme mithilfe von Speech Synthesis Markup Language (SSML) geben Sie den Modellnamen als Stimmnamen an. In diesem Beispiel wird die Stimme YourCustomVoiceName
verwendet.
<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>
Ausführen und Verwenden eines Containers
Speech-Container bieten websocketbasierte Abfrageendpunkt-APIs, auf die über das Speech SDK und die Speech-CLI zugegriffen wird. Standardmäßig verwenden das Speech SDK und die Speech-CLI den öffentlichen Speech-Dienst. Um den Container verwenden zu können, müssen Sie die Initialisierungsmethode ändern. Verwenden Sie eine Containerhost-URL anstelle von Schlüssel und Region.
Weitere Informationen zu Containern finden Sie unter Installieren und Ausführen von Speech-Containern mit Docker.
Referenzdokumentation | Paket (Go) | Zusätzliche Beispiele auf GitHub
In dieser Schrittanleitung werden gängige Entwurfsmuster für die Sprachsynthese vorgestellt.
Weitere Informationen zu den folgenden Bereichen finden Sie unter Was ist Sprachsynthese?.
- Abrufen von Antworten als In-Memory-Datenströme
- Anpassen der Abtast- und Bitrate der Ausgabe
- Übermitteln von Syntheseanforderungen mithilfe der Markupsprache für Sprachsynthese (Speech Synthesis Markup Language, SSML)
- Verwenden neuronaler Stimmen
- Abonnieren von Ereignissen und ergebnisbezogenes Handeln
Voraussetzungen
- Ein Azure-Abonnement. Sie können ein kostenloses Konto erstellen.
- Erstellen Sie eine Speech-Ressource im Azure-Portal.
- Abrufen des Speech-Ressourcenschlüssel und des Endpunkts. Wählen Sie nach der Bereitstellung Ihrer Speech-Ressource Zu Ressource wechseln aus, um Schlüssel anzuzeigen und zu verwalten.
Installieren des Speech SDK
Zuallererst müssen Sie das Speech SDK für Go installieren.
Sprachsynthese über Lautsprecher
Verwenden Sie das folgende Codebeispiel, um die Sprachsynthese über Ihr standardmäßiges Audioausgabegerät durchzuführen. Ersetzen Sie die Variablen subscription
und region
durch Ihren Schlüssel für die Spracheingabe und durch Ihren Standort/Ihre Region. Wenn Sie das Skript ausführen, wird Ihr Eingabetext über den Standardlautsprecher gesprochen.
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)
}
}
}
}
Führen Sie die folgenden Befehle aus, um eine Datei namens go.mod zu erstellen, die mit auf GitHub gehosteten Komponenten verknüpft ist:
go mod init quickstart
go get github.com/Microsoft/cognitive-services-speech-sdk-go
Erstellen Sie nun den Code, und führen Sie ihn aus:
go build
go run quickstart
Ausführliche Informationen zu den Klassen finden Sie in der Referenzdokumentation zu SpeechConfig
und SpeechSynthesizer
.
Sprachsynthese über In-Memory-Datenstrom
Sie können die resultierenden Audiodaten als einen In-Memory-Datenstrom verwenden, statt sie direkt in eine Datei zu schreiben. Mit einem In-Memory-Datenstrom können Sie benutzerdefiniertes Verhalten erstellen:
- Abstrahieren des resultierenden Bytearrays als durchsuchbaren Datenstrom für benutzerdefinierte Downstreamdienste
- Integrieren des Ergebnisses in andere APIs oder Dienste
- Ändern Sie die Audiodaten, schreiben Sie benutzerdefinierte WAV-Header, und erledigen Sie zugehörige Aufgaben.
Sie können diese Änderung am vorherigen Beispiel vornehmen. Entfernen Sie den AudioConfig
-Block, da Sie das Ausgabeverhalten ab jetzt manuell verwalten, um eine bessere Kontrolle zu erzielen. Übergeben Sie anschließend im SpeechSynthesizer
-Konstruktor nil
für AudioConfig
.
Hinweis
Wenn Sie nil
für AudioConfig
übergeben, anstatt den Parameter wie im obigen Beispiel für die Lautsprecherausgabe wegzulassen, werden die Audiodaten nicht standardmäßig auf dem derzeit aktiven Ausgabegerät wiedergegeben.
Speichern Sie das Ergebnis in einer SpeechSynthesisResult
-Variablen. Die AudioData
-Eigenschaft gibt eine []byte
-Instanz für die Ausgabedaten zurück. Sie können diese []byte
-Instanz manuell nutzen oder die AudioDataStream
-Klasse verwenden, um den In-Memory-Datenstrom zu verwalten.
In diesem Beispiel verwenden Sie die statische Funktion NewAudioDataStreamFromSpeechSynthesisResult()
, um einen Datenstrom aus dem Ergebnis abzurufen.
Ersetzen Sie die Variablen subscription
und region
durch Ihren Schlüssel für die Spracheingabe und durch Ihren Standort bzw. Ihre Region:
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))
}
}
Führen Sie die folgenden Befehle aus, um eine Datei namens go.mod zu erstellen, die mit auf GitHub gehosteten Komponenten verknüpft ist:
go mod init quickstart
go get github.com/Microsoft/cognitive-services-speech-sdk-go
Erstellen Sie nun den Code, und führen Sie ihn aus:
go build
go run quickstart
Ausführliche Informationen zu den Klassen finden Sie in der Referenzdokumentation zu SpeechConfig
und SpeechSynthesizer
.
Auswählen von Synthesesprache und Stimme
Das Feature für die Sprachsynthese im Speech-Dienst unterstützt mehr als 400 Stimmen und über 140 Sprachen und Varianten. Sie können die vollständige Liste abrufen oder sie im Stimmkatalog ausprobieren.
Geben Sie die Sprache oder Stimme von SpeechConfig
entsprechend Ihres Eingabetexts an, und verwenden Sie die festgelegte Stimme:
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 neuronalen Stimmen sind mehrsprachig und können in ihrer eigenen Sprache und in englischer Sprache sprechen. Wenn der Eingabetext auf Englisch beispielsweise „I'm excited to try text to speech“ lautet und Sie es-ES-ElviraNeural
auswählen, wird der Text in englischer Sprache mit einem spanischen Akzent gesprochen.
Wenn die Stimme nicht die Sprache des Eingabetexts spricht, wird keine synthetisierte Audioausgabe vom Speech-Dienst erstellt. Eine vollständige Liste der unterstützten neuronalen Stimmen finden Sie unter Sprach- und Stimmunterstützung für den Speech-Dienst.
Hinweis
Die Standardstimme ist die erste Stimme, die pro Gebietsschema von der Stimmlisten-API zurückgegeben wird.
Die Stimme, die spricht, wird wie folgt nach ihrer Priorität bestimmt:
- Wenn Sie weder
SpeechSynthesisVoiceName
nochSpeechSynthesisLanguage
festlegen, spricht die Standardstimme füren-US
. - Wenn Sie nur
SpeechSynthesisLanguage
festlegen, spricht die Standardstimme für das angegebene Gebietsschema. - Wenn sowohl
SpeechSynthesisVoiceName
als auchSpeechSynthesisLanguage
festgelegt sind, wird die EinstellungSpeechSynthesisLanguage
ignoriert. Die Stimme, die Sie mithilfe vonSpeechSynthesisVoiceName
angeben, spricht. - Wenn das Stimmelement über Speech Synthesis Markup Language (SSML) festgelegt wird, werden die Einstellungen
SpeechSynthesisVoiceName
undSpeechSynthesisLanguage
ignoriert.
Zusammenfassend kann die Reihenfolge der Priorität wie folgt beschrieben werden:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Ergebnis |
---|---|---|---|
✗ | ✗ | ✗ | Die Standardstimme für en-US spricht. |
✗ | ✔ | ✗ | Die Standardstimme für das angegebene Gebietsschema spricht. |
✔ | ✔ | ✗ | Die Stimme, die Sie mithilfe von SpeechSynthesisVoiceName angeben, spricht. |
✔ | ✔ | ✔ | Die Stimme, die Sie mithilfe von SSML angeben, spricht. |
Verwenden von SSML zum Anpassen von Sprachmerkmalen
Mit der Markupsprache für Sprachsynthese (Speech Synthesis Markup Language, SSML) können Sie die Tonhöhe, Aussprache, Sprechgeschwindigkeit, Lautstärke und weitere Aspekte der Ausgabe der Sprachsynthese optimieren, indem Sie Ihre Anforderungen per XML-Schema übermitteln. Dieser Abschnitt enthält ein Beispiel für das Ändern der Stimme. Weitere Informationen finden Sie unter Übersicht über Speech Synthesis Markup Language.
Wenn Sie SSML für die Anpassung nutzen möchten, nehmen Sie eine geringfügige Änderung vor, um die Stimme zu wechseln.
Erstellen Sie zuerst im Stammverzeichnis des Projekts eine neue XML-Datei für die SSML-Konfiguration. In diesem Beispiel lautet er ssml.xml
. Das Stammelement ist immer <speak>
. Indem Sie den Text in einem <voice>
-Element umschließen, können Sie die Stimme mit dem name
-Parameter ändern. Eine vollständige Liste der unterstützten neuronalen Stimmen finden Sie unter Unterstützte Sprachen.
<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>
Als Nächstes müssen Sie die Anforderung der Sprachsynthese so ändern, dass darin auf Ihre XML-Datei verwiesen wird. Die Anforderung bleibt größtenteils unverändert, aber Sie verwenden nun SpeakSsmlAsync()
anstelle von SpeakTextAsync()
. Diese Funktion erwartet eine XML-Zeichenfolge. Daher laden Sie zunächst Ihre SSML-Konfiguration als Zeichenfolge. Ab diesem Punkt stimmt das resultierende Objekt genau mit den Objekten in den vorherigen Beispielen überein.
Hinweis
Wenn Sie die Stimme ohne SSML festlegen möchten, können Sie die Eigenschaft für SpeechConfig
mithilfe von speechConfig.SetSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural")
festlegen.
Abonnieren von Synthesizerereignissen
Sie sollten mehr über die Sprachsyntheseverarbeitung und die Ergebnisse erfahren. Beispielsweise möchten Sie vielleicht wissen, wann der Synthesizer beginnt und anhält, oder Sie möchten wissen, welche anderen Ereignisse während der Synthese auftreten.
Wenn Sie den SpeechSynthesizer für die Sprachsynthese verwenden, können Sie die Ereignisse in dieser Tabelle abonnieren:
Ereignis | BESCHREIBUNG | Anwendungsfall |
---|---|---|
BookmarkReached |
Signalisiert, dass eine Textmarke erreicht wurde. Zum Auslösen eines Textmarke-erreicht-Ereignisses ist im SSML ein bookmark -Element erforderlich. Dieses Ereignis meldet die verstrichene Audioausgabezeit zwischen dem Beginn der Synthese und dem bookmark -Element. Die Eigenschaft Text des Ereignisses ist der Zeichenfolgenwert, den Sie im Attribut mark der Textmarke festlegen. Die bookmark -Elemente werden nicht ausgesprochen. |
Sie können das bookmark -Element verwenden, um benutzerdefinierte Marker in SSML einzufügen, um den Offset der einzelnen Marker im Audiostream abzurufen. Das bookmark -Element kann verwendet werden, um auf eine bestimmte Position in der Text- oder Tagsequenz zu verweisen. |
SynthesisCanceled |
Zeigt an, dass die Sprachsynthese abgebrochen wurde. | Sie können bestätigen, wann die Synthese abgebrochen wird. |
SynthesisCompleted |
Zeigt an, dass die Sprachsynthese vollständig ist. | Sie können bestätigen, wenn die Synthese abgeschlossen wurde. |
SynthesisStarted |
Zeigt an, dass die Sprachsynthese begonnen hat. | Sie können bestätigen, wenn die Synthese begonnen hat. |
Synthesizing |
Zeigt an, dass die Sprachsynthese fortgesetzt wird. Dieses Ereignis wird jedes Mal ausgelöst, wenn das SDK einen Audioabschnitt vom Speech-Dienst empfängt. | Sie können bestätigen, wenn die Synthese aktuell ausgeführt wird. |
VisemeReceived |
Zeigt an, dass ein Visemereignis empfangen wurde. | Viseme (Mundbilder) werden häufig verwendet, um die wichtigsten Gesichtsausdrücke beim Sprechen darzustellen. Sie umfassen u. a. die Position der Lippen, des Kiefers und der Zunge beim Erzeugen eines bestimmten Phonems. Sie können Viseme (Mundbilder) anwenden, um das Gesicht einer Figur zu animieren, wenn die Audiodatei abgespielt wird. |
WordBoundary |
Zeigt an, dass eine Wortgrenze empfangen wurde. Dieses Ereignis wird am Anfang jedes neuen gesprochenen Worts, beim Erreichen von Satzzeichen und am Satzanfang ausgelöst. Das Ereignis meldet den Zeitoffset des aktuellen Worts (in Ticks) vom Anfang der Audioausgabe. Dieses Ereignis meldet außerdem die Zeichenposition im Eingabetext (oder SSML) unmittelbar vor dem Wort, das als Nächstes gesprochen wird. | Dieses Ereignis wird häufig verwendet, um die relativen Positionen von Text und den entsprechenden Audiodaten abzurufen. Es kann sinnvoll sein, Informationen zu einem neuen Wort zu empfangen und dann auf der Grundlage des Timings Aktionen auszuführen. Sie können z. B. Informationen abrufen, die Sie bei der Entscheidung unterstützen, wann und wie lange Wörter beim Sprechen hervorgehoben werden sollen. |
Hinweis
Ereignisse werden ausgelöst, wenn die ausgegebenen Audiodaten verfügbar werden, was schneller passiert als die Wiedergabe über ein Ausgabegerät. Der Aufrufer muss das Streaming ordnungsgemäß und in Echtzeit synchronisieren.
Dieses Beispiel zeigt, wie Ereignisse für die Sprachsynthese abonniert werden.
Wichtig
Wenn Sie einen API-Schlüssel verwenden, speichern Sie ihn an einer anderen Stelle sicher, z. B. in Azure Key Vault. Fügen Sie den API-Schlüssel nicht direkt in Ihren Code ein, und machen Sie ihn nicht öffentlich zugänglich.
Weitere Informationen zur Sicherheit von KI Services finden Sie unter Authentifizieren von Anforderungen an Azure KI Services.
Sie können die Anweisungen im Schnellstart befolgen, aber den Inhalt dieser speech-synthesis.go
-Datei durch den folgenden Go-Code ersetzen:
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)
}
}
}
Weitere Beispiele zur Sprachsynthese finden Sie auf GitHub.
Ausführen und Verwenden eines Containers
Speech-Container bieten websocketbasierte Abfrageendpunkt-APIs, auf die über das Speech SDK und die Speech-CLI zugegriffen wird. Standardmäßig verwenden das Speech SDK und die Speech-CLI den öffentlichen Speech-Dienst. Um den Container verwenden zu können, müssen Sie die Initialisierungsmethode ändern. Verwenden Sie eine Containerhost-URL anstelle von Schlüssel und Region.
Weitere Informationen zu Containern finden Sie unter Installieren und Ausführen von Speech-Containern mit Docker.
Referenzdokumentation | Zusätzliche Beispiele auf GitHub
In dieser Schrittanleitung werden gängige Entwurfsmuster für die Sprachsynthese vorgestellt.
Weitere Informationen zu den folgenden Bereichen finden Sie unter Was ist Sprachsynthese?.
- Abrufen von Antworten als In-Memory-Datenströme
- Anpassen der Abtast- und Bitrate der Ausgabe
- Übermitteln von Syntheseanforderungen mithilfe der Markupsprache für Sprachsynthese (Speech Synthesis Markup Language, SSML)
- Verwenden neuronaler Stimmen
- Abonnieren von Ereignissen und ergebnisbezogenes Handeln
Auswählen von Synthesesprache und Stimme
Das Feature für die Sprachsynthese im Speech-Dienst unterstützt mehr als 400 Stimmen und über 140 Sprachen und Varianten. Sie können die vollständige Liste abrufen oder sie im Stimmkatalog ausprobieren.
Geben Sie die Sprache oder Stimme von SpeechConfig entsprechend Ihres Eingabetexts an, und verwenden Sie die festgelegte Stimme. Der folgende Codeschnipsel zeigt, wie dieses Verfahren funktioniert:
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 neuronalen Stimmen sind mehrsprachig und können in ihrer eigenen Sprache und in englischer Sprache sprechen. Wenn der Eingabetext auf Englisch beispielsweise „I'm excited to try text to speech“ lautet und Sie es-ES-ElviraNeural
auswählen, wird der Text in englischer Sprache mit einem spanischen Akzent gesprochen.
Wenn die Stimme nicht die Sprache des Eingabetexts spricht, wird keine synthetisierte Audioausgabe vom Speech-Dienst erstellt. Eine vollständige Liste der unterstützten neuronalen Stimmen finden Sie unter Sprach- und Stimmunterstützung für den Speech-Dienst.
Hinweis
Die Standardstimme ist die erste Stimme, die pro Gebietsschema von der Stimmlisten-API zurückgegeben wird.
Die Stimme, die spricht, wird wie folgt nach ihrer Priorität bestimmt:
- Wenn Sie weder
SpeechSynthesisVoiceName
nochSpeechSynthesisLanguage
festlegen, spricht die Standardstimme füren-US
. - Wenn Sie nur
SpeechSynthesisLanguage
festlegen, spricht die Standardstimme für das angegebene Gebietsschema. - Wenn sowohl
SpeechSynthesisVoiceName
als auchSpeechSynthesisLanguage
festgelegt sind, wird die EinstellungSpeechSynthesisLanguage
ignoriert. Die Stimme, die Sie mithilfe vonSpeechSynthesisVoiceName
angegeben haben, spricht. - Wenn das Stimmelement über Speech Synthesis Markup Language (SSML) festgelegt wird, werden die Einstellungen
SpeechSynthesisVoiceName
undSpeechSynthesisLanguage
ignoriert.
Zusammenfassend kann die Reihenfolge der Priorität wie folgt beschrieben werden:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Ergebnis |
---|---|---|---|
✗ | ✗ | ✗ | Die Standardstimme für en-US spricht. |
✗ | ✔ | ✗ | Die Standardstimme für das angegebene Gebietsschema spricht. |
✔ | ✔ | ✗ | Die Stimme, die Sie mithilfe von SpeechSynthesisVoiceName angeben, spricht. |
✔ | ✔ | ✔ | Die Stimme, die Sie mithilfe von SSML angeben, spricht. |
Synthetisieren von Sprache in eine Datei
Erstellen eines SpeechSynthesizer
-Objekts Dieses Objekt führt die Konvertierungen von Text in Sprache und Ausgaben an Lautsprecher, in Dateien oder andere Ausgabestreams aus. SpeechSynthesizer
akzeptiert folgende Parameter:
- Das
SpeechConfig
-Objekt, das Sie im vorherigen Schritt erstellt haben - Ein
AudioConfig
-Objekt, das angibt, wie Ausgabeergebnisse verarbeitet werden sollen
Erstellen Sie eine
AudioConfig
-Instanz, um die Ausgabe mithilfe der statischen FunktionfromWavFileOutput()
automatisch in eine WAV-Datei zu schreiben:public static void main(String[] args) { SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion"); AudioConfig audioConfig = AudioConfig.fromWavFileOutput("path/to/write/file.wav"); }
Instanziieren Sie eine
SpeechSynthesizer
-Instanz. Übergeben Sie diespeechConfig
- undaudioConfig
-Objekte als Parameter. Um Sprache zu synthetisieren und in eine Datei zu schreiben, führen SieSpeakText()
mit einer Textzeichenfolge aus.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"); }
Wenn Sie das Programm ausführen, wird eine synthetisierte WAV-Datei erstellt, die an den von Ihnen angegebenen Speicherort geschrieben wird. Dieses Ergebnis ist ein gutes Beispiel für die einfachste Verwendungsmöglichkeit. Als Nächstes können Sie die Ausgabe anpassen und die Ausgabeantwort als In-Memory-Datenstrom für benutzerdefinierte Szenarios verarbeiten.
Synthetisieren der Lautsprecherausgabe
Sie sollten mehr über die Sprachsyntheseverarbeitung und die Ergebnisse erfahren. Beispielsweise möchten Sie vielleicht wissen, wann der Synthesizer beginnt und anhält, oder Sie möchten wissen, welche anderen Ereignisse während der Synthese auftreten.
Zum Ausgeben von synthetisierter Sprache an das aktuell aktive Ausgabegerät wie etwa einen Lautsprecher instanziieren Sie AudioConfig
mithilfe der statischen Funktion fromDefaultSpeakerOutput()
. Hier sehen Sie ein Beispiel:
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");
}
Abrufen eines Ergebnisses als In-Memory-Datenstrom
Sie können die resultierenden Audiodaten als einen In-Memory-Datenstrom verwenden, statt sie direkt in eine Datei zu schreiben. Mit einem In-Memory-Datenstrom können Sie benutzerdefiniertes Verhalten erstellen:
- Abstrahieren des resultierenden Bytearrays als durchsuchbaren Datenstrom für benutzerdefinierte Downstreamdienste
- Integrieren des Ergebnisses in andere APIs oder Dienste
- Ändern Sie die Audiodaten, schreiben Sie benutzerdefinierte WAV-Header, und erledigen Sie zugehörige Aufgaben.
Sie können diese Änderung am vorherigen Beispiel vornehmen. Entfernen Sie zunächst den AudioConfig
-Block, da Sie das Ausgabeverhalten ab jetzt manuell verwalten, um eine bessere Kontrolle zu erzielen. Übergeben Sie anschließend im SpeechSynthesizer
-Konstruktor null
für AudioConfig
.
Hinweis
Wenn Sie null
für AudioConfig
übergeben, anstatt den Parameter wie im obigen Beispiel für die Lautsprecherausgabe wegzulassen, werden die Audiodaten nicht standardmäßig auf dem derzeit aktiven Ausgabegerät wiedergegeben.
Speichern Sie das Ergebnis in einer SpeechSynthesisResult
-Variablen. Die Funktion SpeechSynthesisResult.getAudioData()
gibt eine byte []
-Instanz der Ausgabedaten zurück. Sie können diese byte []
-Instanz manuell nutzen oder die AudioDataStream
-Klasse verwenden, um den In-Memory-Datenstrom zu verwalten.
In diesem Beispiel verwenden Sie die statische Funktion AudioDataStream.fromResult()
, um einen Datenstrom aus dem Ergebnis abzurufen:
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());
}
Nun können Sie mit dem resultierenden stream
-Objekt ein beliebiges benutzerdefiniertes Verhalten implementieren.
Anpassen des Audioformats
Sie können die Attribute der Audioausgabe anpassen, z. B.:
- Audiodateityp
- Samplingrate
- Bittiefe
Zum Ändern des Audioformats wenden Sie die Funktion setSpeechSynthesisOutputFormat()
auf das Objekt SpeechConfig
an. Diese Funktion erwartet eine enum
-Instanz vom Typ SpeechSynthesisOutputFormat. Verwenden Sie enum
, um das Ausgabeformat auszuwählen. Informationen zu den verfügbaren Formaten finden Sie in der Liste der Audioformate.
Abhängig von Ihren Anforderungen stehen Ihnen verschiedene Optionen für unterschiedliche Dateitypen zur Verfügung. Rohformate wie Raw24Khz16BitMonoPcm
enthalten gemäß Definition keine Audioheader. Verwenden Sie Rohformate nur in den folgenden Situationen:
- Sie wissen, dass Ihre Downstreamimplementierung einen unformatierten Bitstream decodieren kann.
- Sie planen, Header basierend auf Faktoren wie Bittiefe, Abtastrate und Anzahl von Kanälen manuell zu erstellen.
In diesem Beispiel wird das High-Fidelity-RIFF-Format Riff24Khz16BitMonoPcm
angegeben, indem SpeechSynthesisOutputFormat
für das SpeechConfig
-Objekt festgelegt wird. Ähnlich wie im Beispiel im vorherigen Abschnitt nutzen Sie AudioDataStream
, um einen InMemory-Datenstrom des Ergebnisses zu erhalten, das Sie anschließend in eine Datei schreiben.
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");
}
Wenn Sie das Programm ausführen, schreibt es eine WAV-Datei in den angegebenen Pfad.
Verwenden von SSML zum Anpassen von Sprachmerkmalen
Mit SSML können Sie die Tonhöhe, Aussprache, Sprechgeschwindigkeit, Lautstärke und andere Aspekte der Ausgabe der Sprachsynthese optimieren, indem Sie Ihre Anforderungen per XML-Schema übermitteln. Dieser Abschnitt enthält ein Beispiel für das Ändern der Stimme. Weitere Informationen finden Sie im Artikel zur Verwendung von SSML.
Wenn Sie SSML für die Anpassung nutzen möchten, nehmen Sie eine geringfügige Änderung vor, um die Stimme zu wechseln.
Erstellen Sie im Stammverzeichnis des Projekts eine neue XML-Datei für die SSML-Konfiguration.
<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 diesem Beispiel ist die Datei ssml.xml. Das Stammelement ist immer
<speak>
. Indem Sie den Text in einem<voice>
-Element umschließen, können Sie die Stimme mit demname
-Parameter ändern. Eine vollständige Liste der unterstützten neuronalen Stimmen finden Sie unter Unterstützte Sprachen.Ändern Sie die Anforderung der Sprachsynthese so, dass darin auf Ihre XML-Datei verwiesen wird. Die Anforderung ist größtenteils identisch. Anstatt die
SpeakText()
-Funktion zu verwenden, verwenden SieSpeakSsml()
. Diese Funktion erwartet eine XML-Zeichenfolge. Daher erstellen Sie zunächst eine Funktion, um eine XML-Datei zu laden und als Zeichenfolge zurückzugeben: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."; } }
An diesem Punkt stimmt das resultierende Objekt genau mit den Objekten in den vorherigen Beispielen überein:
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"); }
Hinweis
Wenn Sie die Stimme ohne SSML ändern möchten, können Sie die Eigenschaft für SpeechConfig
mithilfe von SpeechConfig.setSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural");
festlegen.
Abonnieren von Synthesizerereignissen
Sie sollten mehr über die Sprachsyntheseverarbeitung und die Ergebnisse erfahren. Beispielsweise möchten Sie vielleicht wissen, wann der Synthesizer beginnt und anhält, oder Sie möchten wissen, welche anderen Ereignisse während der Synthese auftreten.
Wenn Sie den SpeechSynthesizer für die Sprachsynthese verwenden, können Sie die Ereignisse in dieser Tabelle abonnieren:
Ereignis | BESCHREIBUNG | Anwendungsfall |
---|---|---|
BookmarkReached |
Signalisiert, dass eine Textmarke erreicht wurde. Zum Auslösen eines Textmarke-erreicht-Ereignisses ist im SSML ein bookmark -Element erforderlich. Dieses Ereignis meldet die verstrichene Audioausgabezeit zwischen dem Beginn der Synthese und dem bookmark -Element. Die Eigenschaft Text des Ereignisses ist der Zeichenfolgenwert, den Sie im Attribut mark der Textmarke festlegen. Die bookmark -Elemente werden nicht ausgesprochen. |
Sie können das bookmark -Element verwenden, um benutzerdefinierte Marker in SSML einzufügen, um den Offset der einzelnen Marker im Audiostream abzurufen. Das bookmark -Element kann verwendet werden, um auf eine bestimmte Position in der Text- oder Tagsequenz zu verweisen. |
SynthesisCanceled |
Zeigt an, dass die Sprachsynthese abgebrochen wurde. | Sie können bestätigen, wann die Synthese abgebrochen wird. |
SynthesisCompleted |
Zeigt an, dass die Sprachsynthese vollständig ist. | Sie können bestätigen, wenn die Synthese abgeschlossen wurde. |
SynthesisStarted |
Zeigt an, dass die Sprachsynthese begonnen hat. | Sie können bestätigen, wenn die Synthese begonnen hat. |
Synthesizing |
Zeigt an, dass die Sprachsynthese fortgesetzt wird. Dieses Ereignis wird jedes Mal ausgelöst, wenn das SDK einen Audioabschnitt vom Speech-Dienst empfängt. | Sie können bestätigen, wenn die Synthese aktuell ausgeführt wird. |
VisemeReceived |
Zeigt an, dass ein Visemereignis empfangen wurde. | Viseme (Mundbilder) werden häufig verwendet, um die wichtigsten Gesichtsausdrücke beim Sprechen darzustellen. Sie umfassen u. a. die Position der Lippen, des Kiefers und der Zunge beim Erzeugen eines bestimmten Phonems. Sie können Viseme (Mundbilder) anwenden, um das Gesicht einer Figur zu animieren, wenn die Audiodatei abgespielt wird. |
WordBoundary |
Zeigt an, dass eine Wortgrenze empfangen wurde. Dieses Ereignis wird am Anfang jedes neuen gesprochenen Worts, beim Erreichen von Satzzeichen und am Satzanfang ausgelöst. Das Ereignis meldet den Zeitoffset des aktuellen Worts (in Ticks) vom Anfang der Audioausgabe. Dieses Ereignis meldet außerdem die Zeichenposition im Eingabetext (oder SSML) unmittelbar vor dem Wort, das als Nächstes gesprochen wird. | Dieses Ereignis wird häufig verwendet, um die relativen Positionen von Text und den entsprechenden Audiodaten abzurufen. Es kann sinnvoll sein, Informationen zu einem neuen Wort zu empfangen und dann auf der Grundlage des Timings Aktionen auszuführen. Sie können z. B. Informationen abrufen, die Sie bei der Entscheidung unterstützen, wann und wie lange Wörter beim Sprechen hervorgehoben werden sollen. |
Hinweis
Ereignisse werden ausgelöst, wenn die ausgegebenen Audiodaten verfügbar werden, was schneller passiert als die Wiedergabe über ein Ausgabegerät. Der Aufrufer muss das Streaming ordnungsgemäß und in Echtzeit synchronisieren.
Dieses Beispiel zeigt, wie Ereignisse für die Sprachsynthese abonniert werden.
Wichtig
Wenn Sie einen API-Schlüssel verwenden, speichern Sie ihn an einer anderen Stelle sicher, z. B. in Azure Key Vault. Fügen Sie den API-Schlüssel nicht direkt in Ihren Code ein, und machen Sie ihn nicht öffentlich zugänglich.
Weitere Informationen zur Sicherheit von KI Services finden Sie unter Authentifizieren von Anforderungen an Azure KI Services.
Sie können die Anweisungen im Schnellstart befolgen, aber den Inhalt dieser SpeechSynthesis.java-Datei durch den folgenden Java-Code ersetzen:
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);
}
}
Weitere Beispiele zur Sprachsynthese finden Sie auf GitHub.
Verwenden Sie einen benutzerdefinierten Endpunkt
Der benutzerdefinierte Endpunkt verfügt über dieselben Funktionen wie der Standardendpunkt für Sprachsynthese-Anforderungen.
Ein Unterschied besteht darin, dass die EndpointId
angegeben werden muss, wenn Ihre benutzerdefinierte Stimme über das Speech SDK verwendet werden soll. Sie können mit dem Sprachsynthese-Schnellstart beginnen und dann den Code mit EndpointId
und SpeechSynthesisVoiceName
aktualisieren.
SpeechConfig speechConfig = SpeechConfig.fromSubscription(speechKey, speechRegion);
speechConfig.setSpeechSynthesisVoiceName("YourCustomVoiceName");
speechConfig.setEndpointId("YourEndpointId");
Zum Verwenden einer benutzerdefinierten Stimme mithilfe von Speech Synthesis Markup Language (SSML) geben Sie den Modellnamen als Stimmnamen an. In diesem Beispiel wird die Stimme YourCustomVoiceName
verwendet.
<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>
Ausführen und Verwenden eines Containers
Speech-Container bieten websocketbasierte Abfrageendpunkt-APIs, auf die über das Speech SDK und die Speech-CLI zugegriffen wird. Standardmäßig verwenden das Speech SDK und die Speech-CLI den öffentlichen Speech-Dienst. Um den Container verwenden zu können, müssen Sie die Initialisierungsmethode ändern. Verwenden Sie eine Containerhost-URL anstelle von Schlüssel und Region.
Weitere Informationen zu Containern finden Sie unter Installieren und Ausführen von Speech-Containern mit Docker.
Referenzdokumentation | Paket (npm) | Zusätzliche Beispiele auf GitHub | Quellcode der Bibliothek
In dieser Schrittanleitung werden gängige Entwurfsmuster für die Sprachsynthese vorgestellt.
Weitere Informationen zu den folgenden Bereichen finden Sie unter Was ist Sprachsynthese?.
- Abrufen von Antworten als In-Memory-Datenströme
- Anpassen der Abtast- und Bitrate der Ausgabe
- Übermitteln von Syntheseanforderungen mithilfe der Markupsprache für Sprachsynthese (Speech Synthesis Markup Language, SSML)
- Verwenden neuronaler Stimmen
- Abonnieren von Ereignissen und ergebnisbezogenes Handeln
Auswählen von Synthesesprache und Stimme
Das Feature für die Sprachsynthese im Speech-Dienst unterstützt mehr als 400 Stimmen und über 140 Sprachen und Varianten. Sie können die vollständige Liste abrufen oder sie im Stimmkatalog ausprobieren.
Geben Sie die Sprache oder Stimme von SpeechConfig
entsprechend Ihres Eingabetexts an, und verwenden Sie die festgelegte Stimme:
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 neuronalen Stimmen sind mehrsprachig und können in ihrer eigenen Sprache und in englischer Sprache sprechen. Wenn der Eingabetext auf Englisch beispielsweise „I'm excited to try text to speech“ lautet und Sie es-ES-ElviraNeural
auswählen, wird der Text in englischer Sprache mit einem spanischen Akzent gesprochen.
Wenn die Stimme nicht die Sprache des Eingabetexts spricht, wird keine synthetisierte Audioausgabe vom Speech-Dienst erstellt. Eine vollständige Liste der unterstützten neuronalen Stimmen finden Sie unter Sprach- und Stimmunterstützung für den Speech-Dienst.
Hinweis
Die Standardstimme ist die erste Stimme, die pro Gebietsschema von der Stimmlisten-API zurückgegeben wird.
Die Stimme, die spricht, wird wie folgt nach ihrer Priorität bestimmt:
- Wenn Sie weder
SpeechSynthesisVoiceName
nochSpeechSynthesisLanguage
festlegen, spricht die Standardstimme füren-US
. - Wenn Sie nur
SpeechSynthesisLanguage
festlegen, spricht die Standardstimme für das angegebene Gebietsschema. - Wenn sowohl
SpeechSynthesisVoiceName
als auchSpeechSynthesisLanguage
festgelegt sind, wird die EinstellungSpeechSynthesisLanguage
ignoriert. Die Stimme, die Sie mithilfe vonSpeechSynthesisVoiceName
angeben, spricht. - Wenn das Stimmelement über Speech Synthesis Markup Language (SSML) festgelegt wird, werden die Einstellungen
SpeechSynthesisVoiceName
undSpeechSynthesisLanguage
ignoriert.
Zusammenfassend kann die Reihenfolge der Priorität wie folgt beschrieben werden:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Ergebnis |
---|---|---|---|
✗ | ✗ | ✗ | Die Standardstimme für en-US spricht. |
✗ | ✔ | ✗ | Die Standardstimme für das angegebene Gebietsschema spricht. |
✔ | ✔ | ✗ | Die Stimme, die Sie mithilfe von SpeechSynthesisVoiceName angeben, spricht. |
✔ | ✔ | ✔ | Die Stimme, die Sie mithilfe von SSML angeben, spricht. |
Synthetisieren von Text in Sprache
Zum Ausgeben von synthetisierter Sprache an das aktuell aktive Ausgabegerät wie etwa einen Lautsprecher instanziieren Sie AudioConfig
mithilfe der statischen Funktion fromDefaultSpeakerOutput()
. Ein Beispiel:
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();
});
}
Wenn Sie das Programm ausführen, werden synthetisierte Audiodaten über den Lautsprecher wiedergegeben. Dieses Ergebnis ist ein gutes Beispiel für die einfachste Verwendungsmöglichkeit. Als Nächstes können Sie die Ausgabe anpassen und die Ausgabeantwort als In-Memory-Datenstrom für benutzerdefinierte Szenarios verarbeiten.
Abrufen eines Ergebnisses als In-Memory-Datenstrom
Sie können die resultierenden Audiodaten als einen In-Memory-Datenstrom verwenden, statt sie direkt in eine Datei zu schreiben. Mit einem In-Memory-Datenstrom können Sie benutzerdefiniertes Verhalten erstellen:
- Abstrahieren des resultierenden Bytearrays als durchsuchbaren Datenstrom für benutzerdefinierte Downstreamdienste
- Integrieren des Ergebnisses in andere APIs oder Dienste
- Ändern der Audiodaten, Schreiben benutzerdefinierter
.wav
-Header und Ausführen zugehöriger Aufgaben
Sie können diese Änderung am vorherigen Beispiel vornehmen. Entfernen Sie den AudioConfig
-Block, da Sie das Ausgabeverhalten ab jetzt manuell verwalten, um eine bessere Kontrolle zu erzielen. Übergeben Sie anschließend im SpeechSynthesizer
-Konstruktor null
für AudioConfig
.
Hinweis
Wenn Sie null
für AudioConfig
übergeben, anstatt den Parameter wie im obigen Beispiel für die Lautsprecherausgabe wegzulassen, werden die Audiodaten nicht standardmäßig auf dem derzeit aktiven Ausgabegerät wiedergegeben.
Speichern Sie das Ergebnis in einer SpeechSynthesisResult-Variablen. Die SpeechSynthesisResult.audioData
-Eigenschaft gibt einen ArrayBuffer
-Wert der Ausgabedaten zurück, den Standard-Browserstreamtyp. Konvertieren Sie ArrayBuffer
für serverseitigen Code in einen Pufferstream.
Der folgende Code funktioniert für die Clientseite:
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();
});
}
Sie können mit dem resultierenden ArrayBuffer
-Objekt ein beliebiges benutzerdefiniertes Verhalten implementieren. ArrayBuffer
ist ein gängiger Typ, der in einem Browser empfangen und in diesem Format wiedergegeben wird.
Wenn Sie in serverbasiertem Code mit den Daten als Stream arbeiten müssen, müssen Sie das ArrayBuffer
-Objekt in einen Stream konvertieren:
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();
});
}
Anpassen des Audioformats
Sie können die Attribute der Audioausgabe anpassen, z. B.:
- Audiodateityp
- Samplingrate
- Bittiefe
Zum Ändern des Audioformats wenden Sie die Eigenschaft speechSynthesisOutputFormat
auf das Objekt SpeechConfig
an. Diese Eigenschaft erwartet eine enum
-Instanz vom Typ SpeechSynthesisOutputFormat. Verwenden Sie enum
, um das Ausgabeformat auszuwählen. Informationen zu den verfügbaren Formaten finden Sie in der Liste der Audioformate.
Abhängig von Ihren Anforderungen stehen Ihnen verschiedene Optionen für unterschiedliche Dateitypen zur Verfügung. Rohformate wie Raw24Khz16BitMonoPcm
enthalten gemäß Definition keine Audioheader. Verwenden Sie Rohformate nur in den folgenden Situationen:
- Sie wissen, dass Ihre Downstreamimplementierung einen unformatierten Bitstream decodieren kann.
- Sie planen, Header basierend auf Faktoren wie Bittiefe, Abtastrate und Anzahl von Kanälen manuell zu erstellen.
In diesem Beispiel wird das High-Fidelity-RIFF-Format Riff24Khz16BitMonoPcm
angegeben, indem speechSynthesisOutputFormat
für das SpeechConfig
-Objekt festgelegt wird. Rufen Sie die ArrayBuffer
-Audiodaten ähnlich wie im Beispiel im vorherigen Abschnitt ab, und interagieren Sie damit.
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();
});
}
Verwenden von SSML zum Anpassen von Sprachmerkmalen
Mit SSML können Sie die Tonhöhe, Aussprache, Sprechgeschwindigkeit, Lautstärke und andere Aspekte der Ausgabe der Sprachsynthese optimieren, indem Sie Ihre Anforderungen per XML-Schema übermitteln. Dieser Abschnitt enthält ein Beispiel für das Ändern der Stimme. Weitere Informationen finden Sie unter Übersicht über Speech Synthesis Markup Language.
Wenn Sie SSML für die Anpassung nutzen möchten, nehmen Sie eine geringfügige Änderung vor, um die Stimme zu wechseln.
Erstellen Sie im Stammverzeichnis des Projekts eine neue XML-Datei für die SSML-Konfiguration.
<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 diesem Beispiel wird ssml.xml verwendet. Das Stammelement ist immer
<speak>
. Indem Sie den Text in einem<voice>
-Element umschließen, können Sie die Stimme mit demname
-Parameter ändern. Eine vollständige Liste der unterstützten neuronalen Stimmen finden Sie unter Unterstützte Sprachen.Ändern Sie die Anforderung der Sprachsynthese so, dass darin auf Ihre XML-Datei verwiesen wird. Die Anforderung bleibt größtenteils unverändert, aber Sie verwenden nun
speakSsmlAsync()
anstelle vonspeakTextAsync()
. Diese Funktion erwartet eine XML-Zeichenfolge. Erstellen Sie eine Funktion, um eine XML-Datei zu laden und als Zeichenfolge zurückzugeben:function xmlToString(filePath) { const xml = readFileSync(filePath, "utf8"); return xml; }
Weitere Informationen zu
readFileSync
finden Sie unter Node.js-Dateisystem.Das resultierende Objekt stimmt genau mit den Objekten in den vorherigen Beispielen überein:
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(); }); }
Hinweis
Wenn Sie die Stimme ohne SSML ändern möchten, können Sie die Eigenschaft für SpeechConfig
mithilfe von SpeechConfig.speechSynthesisVoiceName = "en-US-AvaMultilingualNeural";
festlegen.
Abonnieren von Synthesizerereignissen
Sie sollten mehr über die Sprachsyntheseverarbeitung und die Ergebnisse erfahren. Beispielsweise möchten Sie vielleicht wissen, wann der Synthesizer beginnt und anhält, oder Sie möchten wissen, welche anderen Ereignisse während der Synthese auftreten.
Wenn Sie den SpeechSynthesizer für die Sprachsynthese verwenden, können Sie die Ereignisse in dieser Tabelle abonnieren:
Ereignis | BESCHREIBUNG | Anwendungsfall |
---|---|---|
BookmarkReached |
Signalisiert, dass eine Textmarke erreicht wurde. Zum Auslösen eines Textmarke-erreicht-Ereignisses ist im SSML ein bookmark -Element erforderlich. Dieses Ereignis meldet die verstrichene Audioausgabezeit zwischen dem Beginn der Synthese und dem bookmark -Element. Die Eigenschaft Text des Ereignisses ist der Zeichenfolgenwert, den Sie im Attribut mark der Textmarke festlegen. Die bookmark -Elemente werden nicht ausgesprochen. |
Sie können das bookmark -Element verwenden, um benutzerdefinierte Marker in SSML einzufügen, um den Offset der einzelnen Marker im Audiostream abzurufen. Das bookmark -Element kann verwendet werden, um auf eine bestimmte Position in der Text- oder Tagsequenz zu verweisen. |
SynthesisCanceled |
Zeigt an, dass die Sprachsynthese abgebrochen wurde. | Sie können bestätigen, wann die Synthese abgebrochen wird. |
SynthesisCompleted |
Zeigt an, dass die Sprachsynthese vollständig ist. | Sie können bestätigen, wenn die Synthese abgeschlossen wurde. |
SynthesisStarted |
Zeigt an, dass die Sprachsynthese begonnen hat. | Sie können bestätigen, wenn die Synthese begonnen hat. |
Synthesizing |
Zeigt an, dass die Sprachsynthese fortgesetzt wird. Dieses Ereignis wird jedes Mal ausgelöst, wenn das SDK einen Audioabschnitt vom Speech-Dienst empfängt. | Sie können bestätigen, wenn die Synthese aktuell ausgeführt wird. |
VisemeReceived |
Zeigt an, dass ein Visemereignis empfangen wurde. | Viseme (Mundbilder) werden häufig verwendet, um die wichtigsten Gesichtsausdrücke beim Sprechen darzustellen. Sie umfassen u. a. die Position der Lippen, des Kiefers und der Zunge beim Erzeugen eines bestimmten Phonems. Sie können Viseme (Mundbilder) anwenden, um das Gesicht einer Figur zu animieren, wenn die Audiodatei abgespielt wird. |
WordBoundary |
Zeigt an, dass eine Wortgrenze empfangen wurde. Dieses Ereignis wird am Anfang jedes neuen gesprochenen Worts, beim Erreichen von Satzzeichen und am Satzanfang ausgelöst. Das Ereignis meldet den Zeitoffset des aktuellen Worts (in Ticks) vom Anfang der Audioausgabe. Dieses Ereignis meldet außerdem die Zeichenposition im Eingabetext (oder SSML) unmittelbar vor dem Wort, das als Nächstes gesprochen wird. | Dieses Ereignis wird häufig verwendet, um die relativen Positionen von Text und den entsprechenden Audiodaten abzurufen. Es kann sinnvoll sein, Informationen zu einem neuen Wort zu empfangen und dann auf der Grundlage des Timings Aktionen auszuführen. Sie können z. B. Informationen abrufen, die Sie bei der Entscheidung unterstützen, wann und wie lange Wörter beim Sprechen hervorgehoben werden sollen. |
Hinweis
Ereignisse werden ausgelöst, wenn die ausgegebenen Audiodaten verfügbar werden, was schneller passiert als die Wiedergabe über ein Ausgabegerät. Der Aufrufer muss das Streaming ordnungsgemäß und in Echtzeit synchronisieren.
Dieses Beispiel zeigt, wie Ereignisse für die Sprachsynthese abonniert werden.
Wichtig
Wenn Sie einen API-Schlüssel verwenden, speichern Sie ihn an einer anderen Stelle sicher, z. B. in Azure Key Vault. Fügen Sie den API-Schlüssel nicht direkt in Ihren Code ein, und machen Sie ihn nicht öffentlich zugänglich.
Weitere Informationen zur Sicherheit von KI Services finden Sie unter Authentifizieren von Anforderungen an Azure KI Services.
Sie können die Anweisungen im Schnellstart befolgen, aber den Inhalt dieser SpeechSynthesis.js-Datei durch den folgenden JavaScript-Code ersetzen.
(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;
});
}());
Weitere Beispiele zur Sprachsynthese finden Sie auf GitHub.
Ausführen und Verwenden eines Containers
Speech-Container bieten websocketbasierte Abfrageendpunkt-APIs, auf die über das Speech SDK und die Speech-CLI zugegriffen wird. Standardmäßig verwenden das Speech SDK und die Speech-CLI den öffentlichen Speech-Dienst. Um den Container verwenden zu können, müssen Sie die Initialisierungsmethode ändern. Verwenden Sie eine Containerhost-URL anstelle von Schlüssel und Region.
Weitere Informationen zu Containern finden Sie unter Installieren und Ausführen von Speech-Containern mit Docker.
Referenzdokumentation | Paket (Download) | Zusätzliche Beispiele auf GitHub
In dieser Schrittanleitung werden gängige Entwurfsmuster für die Sprachsynthese vorgestellt.
Weitere Informationen zu den folgenden Bereichen finden Sie unter Was ist Sprachsynthese?.
- Abrufen von Antworten als In-Memory-Datenströme
- Anpassen der Abtast- und Bitrate der Ausgabe
- Übermitteln von Syntheseanforderungen mithilfe der Markupsprache für Sprachsynthese (Speech Synthesis Markup Language, SSML)
- Verwenden neuronaler Stimmen
- Abonnieren von Ereignissen und ergebnisbezogenes Handeln
Voraussetzungen
- Ein Azure-Abonnement. Sie können ein kostenloses Konto erstellen.
- Erstellen Sie eine Speech-Ressource im Azure-Portal.
- Abrufen des Speech-Ressourcenschlüssel und des Endpunkts. Wählen Sie nach der Bereitstellung Ihrer Speech-Ressource Zu Ressource wechseln aus, um Schlüssel anzuzeigen und zu verwalten.
Installieren des Speech SDK und der Beispiele
Das Repository Azure-Samples/cognitive-services-speech-sdk enthält Beispiele in Objective-C für iOS und Mac. Wählen Sie einen Link aus, um Installationsanweisungen für die einzelnen Beispiele anzuzeigen:
- Sprachsynthese in Objective-C unter macOS
- Sprachsynthese in Objective-C unter iOS
- Weitere Beispiele für Objective-C auf iOS
Verwenden Sie einen benutzerdefinierten Endpunkt
Der benutzerdefinierte Endpunkt verfügt über dieselben Funktionen wie der Standardendpunkt für Sprachsynthese-Anforderungen.
Ein Unterschied besteht darin, dass die EndpointId
angegeben werden muss, wenn Ihre benutzerdefinierte Stimme über das Speech SDK verwendet werden soll. Sie können mit dem Sprachsynthese-Schnellstart beginnen und dann den Code mit EndpointId
und SpeechSynthesisVoiceName
aktualisieren.
SPXSpeechConfiguration *speechConfig = [[SPXSpeechConfiguration alloc] initWithSubscription:speechKey region:speechRegion];
speechConfig.speechSynthesisVoiceName = @"YourCustomVoiceName";
speechConfig.EndpointId = @"YourEndpointId";
Zum Verwenden einer benutzerdefinierten Stimme mithilfe von Speech Synthesis Markup Language (SSML) geben Sie den Modellnamen als Stimmnamen an. In diesem Beispiel wird die Stimme YourCustomVoiceName
verwendet.
<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>
Ausführen und Verwenden eines Containers
Speech-Container bieten websocketbasierte Abfrageendpunkt-APIs, auf die über das Speech SDK und die Speech-CLI zugegriffen wird. Standardmäßig verwenden das Speech SDK und die Speech-CLI den öffentlichen Speech-Dienst. Um den Container verwenden zu können, müssen Sie die Initialisierungsmethode ändern. Verwenden Sie eine Containerhost-URL anstelle von Schlüssel und Region.
Weitere Informationen zu Containern finden Sie unter Installieren und Ausführen von Speech-Containern mit Docker.
Referenzdokumentation | Paket (Download) | Zusätzliche Beispiele auf GitHub
In dieser Schrittanleitung werden gängige Entwurfsmuster für die Sprachsynthese vorgestellt.
Weitere Informationen zu den folgenden Bereichen finden Sie unter Was ist Sprachsynthese?.
- Abrufen von Antworten als In-Memory-Datenströme
- Anpassen der Abtast- und Bitrate der Ausgabe
- Übermitteln von Syntheseanforderungen mithilfe der Markupsprache für Sprachsynthese (Speech Synthesis Markup Language, SSML)
- Verwenden neuronaler Stimmen
- Abonnieren von Ereignissen und ergebnisbezogenes Handeln
Voraussetzungen
- Ein Azure-Abonnement. Sie können ein kostenloses Konto erstellen.
- Erstellen Sie eine Speech-Ressource im Azure-Portal.
- Abrufen des Speech-Ressourcenschlüssel und des Endpunkts. Wählen Sie nach der Bereitstellung Ihrer Speech-Ressource Zu Ressource wechseln aus, um Schlüssel anzuzeigen und zu verwalten.
Installieren des Speech SDK und der Beispiele
Das Repository Azure-Samples/cognitive-services-speech-sdk enthält Beispiele in Swift für iOS und Mac. Wählen Sie einen Link aus, um Installationsanweisungen für die einzelnen Beispiele anzuzeigen:
Ausführen und Verwenden eines Containers
Speech-Container bieten websocketbasierte Abfrageendpunkt-APIs, auf die über das Speech SDK und die Speech-CLI zugegriffen wird. Standardmäßig verwenden das Speech SDK und die Speech-CLI den öffentlichen Speech-Dienst. Um den Container verwenden zu können, müssen Sie die Initialisierungsmethode ändern. Verwenden Sie eine Containerhost-URL anstelle von Schlüssel und Region.
Weitere Informationen zu Containern finden Sie unter Installieren und Ausführen von Speech-Containern mit Docker.
Referenzdokumentation | Paket (PyPi) | Zusätzliche Beispiele auf GitHub
In dieser Schrittanleitung werden gängige Entwurfsmuster für die Sprachsynthese vorgestellt.
Weitere Informationen zu den folgenden Bereichen finden Sie unter Was ist Sprachsynthese?.
- Abrufen von Antworten als In-Memory-Datenströme
- Anpassen der Abtast- und Bitrate der Ausgabe
- Übermitteln von Syntheseanforderungen mithilfe der Markupsprache für Sprachsynthese (Speech Synthesis Markup Language, SSML)
- Verwenden neuronaler Stimmen
- Abonnieren von Ereignissen und ergebnisbezogenes Handeln
Auswählen von Synthesesprache und Stimme
Das Feature für die Sprachsynthese im Speech-Dienst unterstützt mehr als 400 Stimmen und über 140 Sprachen und Varianten. Sie können die vollständige Liste abrufen oder sie im Stimmkatalog ausprobieren.
Geben Sie die Sprache oder Stimme von SpeechConfig
entsprechend Ihres Eingabetexts an, und verwenden Sie die festgelegte Stimme:
# Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
speech_config.speech_synthesis_language = "en-US"
speech_config.speech_synthesis_voice_name ="en-US-AvaMultilingualNeural"
Alle neuronalen Stimmen sind mehrsprachig und können in ihrer eigenen Sprache und in englischer Sprache sprechen. Wenn der Eingabetext auf Englisch beispielsweise „I'm excited to try text to speech“ lautet und Sie es-ES-ElviraNeural
auswählen, wird der Text in englischer Sprache mit einem spanischen Akzent gesprochen.
Wenn die Stimme nicht die Sprache des Eingabetexts spricht, wird keine synthetisierte Audioausgabe vom Speech-Dienst erstellt. Eine vollständige Liste der unterstützten neuronalen Stimmen finden Sie unter Sprach- und Stimmunterstützung für den Speech-Dienst.
Hinweis
Die Standardstimme ist die erste Stimme, die pro Gebietsschema von der Stimmlisten-API zurückgegeben wird.
Die Stimme, die spricht, wird wie folgt nach ihrer Priorität bestimmt:
- Wenn Sie weder
SpeechSynthesisVoiceName
nochSpeechSynthesisLanguage
festlegen, spricht die Standardstimme füren-US
. - Wenn Sie nur
SpeechSynthesisLanguage
festlegen, spricht die Standardstimme für das angegebene Gebietsschema. - Wenn sowohl
SpeechSynthesisVoiceName
als auchSpeechSynthesisLanguage
festgelegt sind, wird die EinstellungSpeechSynthesisLanguage
ignoriert. Die Stimme, die Sie mithilfe vonSpeechSynthesisVoiceName
angeben, spricht. - Wenn das Stimmelement über Speech Synthesis Markup Language (SSML) festgelegt wird, werden die Einstellungen
SpeechSynthesisVoiceName
undSpeechSynthesisLanguage
ignoriert.
Zusammenfassend kann die Reihenfolge der Priorität wie folgt beschrieben werden:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Ergebnis |
---|---|---|---|
✗ | ✗ | ✗ | Die Standardstimme für en-US spricht. |
✗ | ✔ | ✗ | Die Standardstimme für das angegebene Gebietsschema spricht. |
✔ | ✔ | ✗ | Die Stimme, die Sie mithilfe von SpeechSynthesisVoiceName angeben, spricht. |
✔ | ✔ | ✔ | Die Stimme, die Sie mithilfe von SSML angeben, spricht. |
Synthetisieren von Sprache in eine Datei
Erstellen Sie ein SpeechSynthesizer-Objekt. Dieses Objekt führt die Konvertierungen von Text in Sprache und Ausgaben an Lautsprecher, in Dateien oder andere Ausgabestreams aus. SpeechSynthesizer
akzeptiert folgende Parameter:
- Das
SpeechConfig
-Objekt, das Sie im vorherigen Schritt erstellt haben - Ein
AudioOutputConfig
-Objekt, das angibt, wie Ausgabeergebnisse verarbeitet werden sollen
Erstellen Sie eine
AudioOutputConfig
-Instanz, um die Ausgabe mithilfe des Konstruktorparametersfilename
automatisch in eine WAV-Datei zu schreiben:audio_config = speechsdk.audio.AudioOutputConfig(filename="path/to/write/file.wav")
Instanziieren Sie
SpeechSynthesizer
, indem Sie diespeech_config
- undaudio_config
-Objekte als Parameter übergeben. Um Sprache zu synthetisieren und in eine Datei zu schreiben, führen Siespeak_text_async()
mit einer Textzeichenfolge aus.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()
Wenn Sie das Programm ausführen, wird eine synthetisierte WAV-Datei erstellt, die an den von Ihnen angegebenen Speicherort geschrieben wird. Dieses Ergebnis ist ein gutes Beispiel für die einfachste Verwendungsmöglichkeit. Als Nächstes können Sie die Ausgabe anpassen und die Ausgabeantwort als In-Memory-Datenstrom für benutzerdefinierte Szenarios verarbeiten.
Synthetisieren der Lautsprecherausgabe
Zum Ausgeben von synthetisierter Sprache auf dem aktuell aktiven Ausgabegerät wie einem Lautsprecher legen Sie den Parameter use_default_speaker
fest, wenn Sie die AudioOutputConfig
-Instanz erstellen. Ein Beispiel:
audio_config = speechsdk.audio.AudioOutputConfig(use_default_speaker=True)
Abrufen eines Ergebnisses als In-Memory-Datenstrom
Sie können die resultierenden Audiodaten als einen In-Memory-Datenstrom verwenden, statt sie direkt in eine Datei zu schreiben. Mit einem In-Memory-Datenstrom können Sie benutzerdefiniertes Verhalten erstellen:
- Abstrahieren des resultierenden Bytearrays als durchsuchbaren Datenstrom für benutzerdefinierte Downstreamdienste
- Integrieren des Ergebnisses in andere APIs oder Dienste
- Ändern Sie die Audiodaten, schreiben Sie benutzerdefinierte WAV-Header, und erledigen Sie zugehörige Aufgaben.
Sie können diese Änderung am vorherigen Beispiel vornehmen. Entfernen Sie zunächst AudioConfig
, da Sie das Ausgabeverhalten ab jetzt manuell verwalten, um eine bessere Kontrolle zu erzielen. Übergeben Sie im SpeechSynthesizer
-Konstruktor None
für AudioConfig
.
Hinweis
Wenn Sie None
für AudioConfig
übergeben, anstatt den Parameter wie im obigen Beispiel für die Lautsprecherausgabe wegzulassen, werden die Audiodaten nicht standardmäßig auf dem derzeit aktiven Ausgabegerät wiedergegeben.
Speichern Sie das Ergebnis in einer SpeechSynthesisResult
-Variablen. Die audio_data
-Eigenschaft enthält ein bytes
-Objekt der Ausgabedaten. Sie können dieses Objekt manuell nutzen oder die AudioDataStream
-Klasse verwenden, um den InMemory-Datenstrom zu verwalten.
In diesem Beispiel verwenden Sie den Konstruktor AudioDataStream
, um einen Datenstrom aus dem Ergebnis abzurufen:
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)
Nun können Sie mit dem resultierenden stream
-Objekt ein beliebiges benutzerdefiniertes Verhalten implementieren.
Anpassen des Audioformats
Sie können die Attribute der Audioausgabe anpassen, z. B.:
- Audiodateityp
- Samplingrate
- Bittiefe
Zum Ändern des Audioformats wenden Sie die Funktion set_speech_synthesis_output_format()
auf das Objekt SpeechConfig
an. Diese Funktion erwartet eine enum
-Instanz vom Typ SpeechSynthesisOutputFormat. Verwenden Sie enum
, um das Ausgabeformat auszuwählen. Informationen zu den verfügbaren Formaten finden Sie in der Liste der Audioformate.
Abhängig von Ihren Anforderungen stehen Ihnen verschiedene Optionen für unterschiedliche Dateitypen zur Verfügung. Rohformate wie Raw24Khz16BitMonoPcm
enthalten gemäß Definition keine Audioheader. Verwenden Sie Rohformate nur in den folgenden Situationen:
- Sie wissen, dass Ihre Downstreamimplementierung einen unformatierten Bitstream decodieren kann.
- Sie planen, Header basierend auf Faktoren wie Bittiefe, Abtastrate und Anzahl von Kanälen manuell zu erstellen.
In diesem Beispiel wird das High-Fidelity-RIFF-Format Riff24Khz16BitMonoPcm
angegeben, indem SpeechSynthesisOutputFormat
für das SpeechConfig
-Objekt festgelegt wird. Ähnlich wie im Beispiel im vorherigen Abschnitt nutzen Sie AudioDataStream
, um einen InMemory-Datenstrom des Ergebnisses zu erhalten, das Sie anschließend in eine Datei schreiben.
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")
Wenn Sie das Programm ausführen, schreibt es eine WAV-Datei in den angegebenen Pfad.
Verwenden von SSML zum Anpassen von Sprachmerkmalen
Mit SSML können Sie die Tonhöhe, Aussprache, Sprechgeschwindigkeit, Lautstärke und andere Aspekte der Ausgabe der Sprachsynthese optimieren, indem Sie Ihre Anforderungen per XML-Schema übermitteln. Dieser Abschnitt enthält ein Beispiel für das Ändern der Stimme. Weitere Informationen finden Sie unter Übersicht über Speech Synthesis Markup Language.
Wenn Sie SSML für die Anpassung nutzen möchten, nehmen Sie eine geringfügige Änderung vor, um die Stimme zu wechseln.
Erstellen Sie im Stammverzeichnis des Projekts eine neue XML-Datei für die SSML-Konfiguration.
<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 diesem Beispiel ist die Datei ssml.xml. Das Stammelement ist immer
<speak>
. Indem Sie den Text in einem<voice>
-Element umschließen, können Sie die Stimme mit demname
-Parameter ändern. Eine vollständige Liste der unterstützten neuronalen Stimmen finden Sie unter Unterstützte Sprachen.Ändern Sie die Anforderung der Sprachsynthese so, dass darin auf Ihre XML-Datei verwiesen wird. Die Anforderung ist größtenteils identisch. Anstatt die
speak_text_async()
-Funktion zu verwenden, verwenden Siespeak_ssml_async()
. Diese Funktion erwartet eine XML-Zeichenfolge. Lesen Sie zunächst Ihre SSML-Konfiguration als Zeichenfolge. Ab diesem Punkt stimmt das resultierende Objekt genau mit den Objekten in den vorherigen Beispielen überein.Hinweis
Wenn
ssml_string
am Anfang der Zeichenfolge
enthält, müssen Sie das BOM-Format entfernen, andernfalls gibt der Dienst einen Fehler zurück. Hierzu müssen Sie den Parameterencoding
wie folgt festlegen: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")
Hinweis
Wenn Sie die Stimme ohne SSML ändern möchten, können Sie die Eigenschaft für SpeechConfig
mithilfe von speech_config.speech_synthesis_voice_name = "en-US-AvaMultilingualNeural"
festlegen.
Abonnieren von Synthesizerereignissen
Sie sollten mehr über die Sprachsyntheseverarbeitung und die Ergebnisse erfahren. Beispielsweise möchten Sie vielleicht wissen, wann der Synthesizer beginnt und anhält, oder Sie möchten wissen, welche anderen Ereignisse während der Synthese auftreten.
Wenn Sie den SpeechSynthesizer für die Sprachsynthese verwenden, können Sie die Ereignisse in dieser Tabelle abonnieren:
Ereignis | BESCHREIBUNG | Anwendungsfall |
---|---|---|
BookmarkReached |
Signalisiert, dass eine Textmarke erreicht wurde. Zum Auslösen eines Textmarke-erreicht-Ereignisses ist im SSML ein bookmark -Element erforderlich. Dieses Ereignis meldet die verstrichene Audioausgabezeit zwischen dem Beginn der Synthese und dem bookmark -Element. Die Eigenschaft Text des Ereignisses ist der Zeichenfolgenwert, den Sie im Attribut mark der Textmarke festlegen. Die bookmark -Elemente werden nicht ausgesprochen. |
Sie können das bookmark -Element verwenden, um benutzerdefinierte Marker in SSML einzufügen, um den Offset der einzelnen Marker im Audiostream abzurufen. Das bookmark -Element kann verwendet werden, um auf eine bestimmte Position in der Text- oder Tagsequenz zu verweisen. |
SynthesisCanceled |
Zeigt an, dass die Sprachsynthese abgebrochen wurde. | Sie können bestätigen, wann die Synthese abgebrochen wird. |
SynthesisCompleted |
Zeigt an, dass die Sprachsynthese vollständig ist. | Sie können bestätigen, wenn die Synthese abgeschlossen wurde. |
SynthesisStarted |
Zeigt an, dass die Sprachsynthese begonnen hat. | Sie können bestätigen, wenn die Synthese begonnen hat. |
Synthesizing |
Zeigt an, dass die Sprachsynthese fortgesetzt wird. Dieses Ereignis wird jedes Mal ausgelöst, wenn das SDK einen Audioabschnitt vom Speech-Dienst empfängt. | Sie können bestätigen, wenn die Synthese aktuell ausgeführt wird. |
VisemeReceived |
Zeigt an, dass ein Visemereignis empfangen wurde. | Viseme (Mundbilder) werden häufig verwendet, um die wichtigsten Gesichtsausdrücke beim Sprechen darzustellen. Sie umfassen u. a. die Position der Lippen, des Kiefers und der Zunge beim Erzeugen eines bestimmten Phonems. Sie können Viseme (Mundbilder) anwenden, um das Gesicht einer Figur zu animieren, wenn die Audiodatei abgespielt wird. |
WordBoundary |
Zeigt an, dass eine Wortgrenze empfangen wurde. Dieses Ereignis wird am Anfang jedes neuen gesprochenen Worts, beim Erreichen von Satzzeichen und am Satzanfang ausgelöst. Das Ereignis meldet den Zeitoffset des aktuellen Worts (in Ticks) vom Anfang der Audioausgabe. Dieses Ereignis meldet außerdem die Zeichenposition im Eingabetext (oder SSML) unmittelbar vor dem Wort, das als Nächstes gesprochen wird. | Dieses Ereignis wird häufig verwendet, um die relativen Positionen von Text und den entsprechenden Audiodaten abzurufen. Es kann sinnvoll sein, Informationen zu einem neuen Wort zu empfangen und dann auf der Grundlage des Timings Aktionen auszuführen. Sie können z. B. Informationen abrufen, die Sie bei der Entscheidung unterstützen, wann und wie lange Wörter beim Sprechen hervorgehoben werden sollen. |
Hinweis
Ereignisse werden ausgelöst, wenn die ausgegebenen Audiodaten verfügbar werden, was schneller passiert als die Wiedergabe über ein Ausgabegerät. Der Aufrufer muss das Streaming ordnungsgemäß und in Echtzeit synchronisieren.
Dieses Beispiel zeigt, wie Ereignisse für die Sprachsynthese abonniert werden.
Wichtig
Wenn Sie einen API-Schlüssel verwenden, speichern Sie ihn an einer anderen Stelle sicher, z. B. in Azure Key Vault. Fügen Sie den API-Schlüssel nicht direkt in Ihren Code ein, und machen Sie ihn nicht öffentlich zugänglich.
Weitere Informationen zur Sicherheit von KI Services finden Sie unter Authentifizieren von Anforderungen an Azure KI Services.
Sie können die Anweisungen im Schnellstart befolgen, aber den Inhalt dieser speech-synthesis.py-Datei durch den folgenden Python-Code ersetzen:
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?")
Weitere Beispiele zur Sprachsynthese finden Sie auf GitHub.
Verwenden Sie einen benutzerdefinierten Endpunkt
Der benutzerdefinierte Endpunkt verfügt über dieselben Funktionen wie der Standardendpunkt für Sprachsynthese-Anforderungen.
Ein Unterschied besteht darin, dass die endpoint_id
angegeben werden muss, wenn Ihre benutzerdefinierte Stimme über das Speech SDK verwendet werden soll. Sie können mit dem Sprachsynthese-Schnellstart beginnen und dann den Code mit endpoint_id
und speech_synthesis_voice_name
aktualisieren.
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"
Zum Verwenden einer benutzerdefinierten Stimme mithilfe von Speech Synthesis Markup Language (SSML) geben Sie den Modellnamen als Stimmnamen an. In diesem Beispiel wird die Stimme YourCustomVoiceName
verwendet.
<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>
Ausführen und Verwenden eines Containers
Speech-Container bieten websocketbasierte Abfrageendpunkt-APIs, auf die über das Speech SDK und die Speech-CLI zugegriffen wird. Standardmäßig verwenden das Speech SDK und die Speech-CLI den öffentlichen Speech-Dienst. Um den Container verwenden zu können, müssen Sie die Initialisierungsmethode ändern. Verwenden Sie eine Containerhost-URL anstelle von Schlüssel und Region.
Weitere Informationen zu Containern finden Sie unter Installieren und Ausführen von Speech-Containern mit Docker.
REST-API-Referenz zur Spracherkennung | REST-API-Referenz zur Spracherkennung für kurze Audiodaten | Zusätzliche Beispiele auf GitHub
In dieser Schrittanleitung werden gängige Entwurfsmuster für die Sprachsynthese vorgestellt.
Weitere Informationen zu den folgenden Bereichen finden Sie unter Was ist Sprachsynthese?.
- Abrufen von Antworten als In-Memory-Datenströme
- Anpassen der Abtast- und Bitrate der Ausgabe
- Übermitteln von Syntheseanforderungen mithilfe der Markupsprache für Sprachsynthese (Speech Synthesis Markup Language, SSML)
- Verwenden neuronaler Stimmen
- Abonnieren von Ereignissen und ergebnisbezogenes Handeln
Voraussetzungen
- Ein Azure-Abonnement. Sie können ein kostenloses Konto erstellen.
- Erstellen Sie eine Speech-Ressource im Azure-Portal.
- Abrufen des Speech-Ressourcenschlüssel und des Endpunkts. Wählen Sie nach der Bereitstellung Ihrer Speech-Ressource Zu Ressource wechseln aus, um Schlüssel anzuzeigen und zu verwalten.
Konvertieren von Text in Sprache
Führen Sie an der Eingabeaufforderung den folgenden Befehl aus. Fügen Sie diese Werte in den Befehl ein:
- Ihr Speech-Ressourcenschlüssel
- Ihre Speech-Ressourcenregion
Sie können ggf. auch die folgenden Werte ändern:
- Headerwert
X-Microsoft-OutputFormat
, mit dem das Format der Audioausgabe gesteuert wird. Eine Liste mit den unterstützten Formaten für die Audioausgabe finden Sie in der Referenz zur Sprachsynthese-REST-API. - Die Stimme für die Ausgabe. Informationen zum Abrufen einer Liste der für Ihren Speech-Dienstendpunkt verfügbaren Stimmen finden Sie bei der Voice List-API.
- Die Ausgabedatei. In diesem Beispiel leiten wir die Antwort des Servers an eine Datei mit dem Namen
output.mp3
weiter.
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 dieser Schrittanleitung werden gängige Entwurfsmuster für die Sprachsynthese vorgestellt.
Weitere Informationen zu den folgenden Bereichen finden Sie unter Was ist Sprachsynthese?.
- Abrufen von Antworten als In-Memory-Datenströme
- Anpassen der Abtast- und Bitrate der Ausgabe
- Übermitteln von Syntheseanforderungen mithilfe der Markupsprache für Sprachsynthese (Speech Synthesis Markup Language, SSML)
- Verwenden neuronaler Stimmen
- Abonnieren von Ereignissen und ergebnisbezogenes Handeln
Voraussetzungen
- Ein Azure-Abonnement. Sie können ein kostenloses Konto erstellen.
- Erstellen Sie eine Speech-Ressource im Azure-Portal.
- Abrufen des Speech-Ressourcenschlüssel und des Endpunkts. Wählen Sie nach der Bereitstellung Ihrer Speech-Ressource Zu Ressource wechseln aus, um Schlüssel anzuzeigen und zu verwalten.
Herunterladen und installieren
Befolgen Sie diese Schritte und lesen Sie die Schnellstartanleitung für Speech CLI, um weitere Anforderungen für Ihre Plattform zu erfahren.
Führen Sie den folgenden .NET CLI-Befehl aus, um die Speech CLI zu installieren:
dotnet tool install --global Microsoft.CognitiveServices.Speech.CLI
Führen Sie die folgenden Befehle aus, um Ihren Speech-Ressourcenschlüssel und Ihre Region zu konfigurieren. Ersetzen Sie
SUBSCRIPTION-KEY
durch den Schlüssel Ihrer Speech-Ressource undREGION
durch die Region Ihrer Speech-Ressource.spx config @key --set SUBSCRIPTION-KEY spx config @region --set REGION
Synthetisieren von Sprache über einen Lautsprecher
Sie sind jetzt bereit, die Speech-Befehlszeilenschnittstelle auszuführen, um aus Text Sprache zu synthetisieren.
Navigieren Sie in einem Konsolenfenster zu dem Verzeichnis, das die Binärdatei der Speech-CLI enthält. Führen Sie dann den folgenden Befehl aus:
spx synthesize --text "I'm excited to try text to speech"
Die Speech-CLI gibt natürlichsprachliches Englisch über den Lautsprecher des Computers aus.
Synthetisieren von Sprache in eine Datei
Führen Sie den folgenden Befehl aus, um die Ausgabe über den Lautsprecher in eine WAV-Datei zu ändern:
spx synthesize --text "I'm excited to try text to speech" --audio output greetings.wav
Die Speech-CLI gibt natürlichsprachliches Englisch in die Audiodatei greetings.wav aus.
Ausführen und Verwenden eines Containers
Speech-Container bieten websocketbasierte Abfrageendpunkt-APIs, auf die über das Speech SDK und die Speech-CLI zugegriffen wird. Standardmäßig verwenden das Speech SDK und die Speech-CLI den öffentlichen Speech-Dienst. Um den Container verwenden zu können, müssen Sie die Initialisierungsmethode ändern. Verwenden Sie eine Containerhost-URL anstelle von Schlüssel und Region.
Weitere Informationen zu Containern finden Sie unter Installieren und Ausführen von Speech-Containern mit Docker.