Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Interfejs API REST zamiany mowy na tekst — dokumentacja | Interfejs API REST zamiany mowy na tekst dla krótkiego audio | Dodatkowe przykłady na GitHubie
W tym przewodniku z instrukcjami poznasz typowe wzorce projektowe służące do wykonywania syntezy mowy w tekście.
Aby uzyskać więcej informacji na temat następujących obszarów, zobacz Co to jest zamiana tekstu na mowę?
- Uzyskiwanie odpowiedzi jako strumieni w pamięci.
- Dostosowywanie szybkości próbkowania danych wyjściowych i szybkości bitów.
- Przesyłanie żądań syntezy przy użyciu języka znaczników syntezy mowy (SSML).
- Korzystanie z głosów neuronowych.
- Subskrybowanie eventów i reagowanie na wyniki.
Wymagania wstępne
- Subskrypcja platformy Azure. Możesz utworzyć go bezpłatnie.
- Utwórz zasób Foundry dla usługi Speech w portalu Azure.
- Pobierz klucz zasobu Mowy oraz region. Po wdrożeniu zasobu usługi Mowa wybierz pozycję Przejdź do zasobu , aby wyświetlić klucze i zarządzać nimi.
Konwertowanie tekstu na mowę
W wierszu polecenia uruchom następujące polecenie. Wstaw następujące wartości do polecenia:
- Klucz zasobu usługi Mowa
- Region zasobów Twojej usługi mowy
Możesz również zmienić następujące wartości:
- Wartość nagłówka
X-Microsoft-OutputFormat, która kontroluje format wyjściowy audio. Listę obsługiwanych formatów wyjściowych audio można znaleźć w dokumentacji interfejsu API REST zamiany tekstu na mowę. - Głos wyjściowy. Aby uzyskać listę głosów dostępnych dla punktu końcowego usługi przetwarzania mowy, zobacz API listy głosów.
- Plik wyjściowy. W tym przykładzie kierujemy odpowiedź z serwera do pliku o nazwie
output.mp3.
curl --location --request POST 'https://YourResourceName.cognitiveservices.azure.com/tts/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-Ava:DragonHDLatestNeural'\''>
I am excited to try text to speech
</voice>
</speak>' > output.mp3
Dokumentacja referencyjna | Package (PyPi) | Dodatkowe przykłady w witrynie GitHub
W tym przewodniku z instrukcjami poznasz typowe wzorce projektowe służące do wykonywania syntezy mowy w tekście.
Aby uzyskać więcej informacji na temat następujących obszarów, zobacz Co to jest zamiana tekstu na mowę?
- Uzyskiwanie odpowiedzi jako strumieni w pamięci.
- Dostosowywanie szybkości próbkowania danych wyjściowych i szybkości bitów.
- Przesyłanie żądań syntezy przy użyciu języka znaczników syntezy mowy (SSML).
- Korzystanie z głosów neuronowych.
- Subskrybowanie eventów i reagowanie na wyniki.
Wybieranie języka syntezy i głosu
Funkcja zamiany tekstu na mowę w usłudze Mowa obsługuje ponad 400 głosów i ponad 140 języków i wariantów. Pełną listę możesz uzyskać lub wypróbować w galerii głosów.
Określ język lub głos SpeechConfig, aby dopasować do tekstu wejściowego i użyć określonego głosu:
# Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
speech_config.speech_synthesis_language = "en-US"
speech_config.speech_synthesis_voice_name ="en-US-Ava:DragonHDLatestNeural"
Wszystkie neuronowe głosy są wielojęzyczne i płynne we własnym języku i języku angielskim. Jeśli na przykład tekst wejściowy w języku angielskim to "Cieszę się na możliwość wypróbowania funkcji zamiany tekstu na mowę", a następnie wybierzesz es-ES-Ximena:DragonHDLatestNeural, to tekst jest mówiony po angielsku z hiszpańskim akcentem.
Jeśli głos nie mówi w języku tekstu wejściowego, usługa rozpoznawania mowy nie tworzy syntetyzowanego dźwięku. Aby uzyskać pełną listę obsługiwanych głosów neuronowych, zobacz Obsługa języka i głosu dla usługi mowy.
Uwaga
Domyślny głos to pierwszy głos zwracany dla lokalizacji z interfejsu API Listy Głosów.
Głos, który mówi, jest określany w kolejności priorytetu w następujący sposób:
- Jeśli nie ustawisz
SpeechSynthesisVoiceNamelubSpeechSynthesisLanguage, domyślny głos dlaen-USbędzie użyty. - Jeśli tylko ustawisz
SpeechSynthesisLanguage, mówi domyślny głos dla określonego ustawienia regionalnego. - Jeśli zarówno
SpeechSynthesisVoiceName, jak iSpeechSynthesisLanguagesą ustawione, ustawienieSpeechSynthesisLanguagejest ignorowane. Głos, który określisz przy użyciuSpeechSynthesisVoiceName, mówi. - Jeśli element głosowy jest ustawiony przy użyciu języka znaczników syntezy mowy (SSML), ustawienia
SpeechSynthesisVoiceNameiSpeechSynthesisLanguagesą ignorowane.
Podsumowując, kolejność priorytetu można opisać jako:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Wynik |
|---|---|---|---|
| ✗ | ✗ | ✗ | Domyślny głos dla en-US wypowiedzi |
| ✗ | ✔ | ✗ | Domyślny głos dla określonych ustawień regionalnych mówi. |
| ✔ | ✔ | ✗ | Głos, który określisz przy użyciu SpeechSynthesisVoiceName, mówi. |
| ✔ | ✔ | ✔ | Głos, który określisz za pomocą języka znaczników SSML, przemawia. |
Syntetyzowanie mowy do pliku
Utwórz obiekt SpeechSynthesizer. Obiekt ten uruchamia konwersje tekstu na mowę i dane wyjściowe do głośników, plików lub innych strumieni wyjściowych.
SpeechSynthesizer akceptuje jako parametry:
-
SpeechConfigObiekt utworzony w poprzednim kroku. -
AudioOutputConfigObiekt określający sposób obsługi wyników wyjściowych.
AudioOutputConfigUtwórz wystąpienie, aby automatycznie zapisywać dane wyjściowe w pliku .wav przy użyciu parametru konstruktorafilename:audio_config = speechsdk.audio.AudioOutputConfig(filename="path/to/write/file.wav")Utwórz wystąpienie
SpeechSynthesizer, przekazując obiektspeech_configi obiektaudio_configjako parametry. Aby syntetyzować mowę i zapisywać w pliku, uruchom poleceniespeak_text_async()z ciągiem tekstu.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()
Po uruchomieniu programu program tworzy syntetyzowany plik .wav , który jest zapisywany w określonej lokalizacji. Ten wynik jest dobrym przykładem najbardziej podstawowego użycia. Następnie możesz dostosować dane wyjściowe i obsłużyć odpowiedź wyjściową jako strumień w pamięci na potrzeby pracy ze scenariuszami niestandardowymi.
Syntezowanie do wyjścia głośnikowego
Aby wysłać syntetyzowaną mowę do aktualnie aktywnego urządzenia wyjściowego, na przykład głośnika, ustaw parametr use_default_speaker podczas tworzenia wystąpienia AudioOutputConfig. Oto przykład:
audio_config = speechsdk.audio.AudioOutputConfig(use_default_speaker=True)
Uzyskaj wynik w postaci strumienia w pamięci
Możesz użyć wynikowych danych dźwiękowych jako strumienia w pamięci, zamiast bezpośredniego zapisywania do pliku. Za pomocą strumienia w pamięci można tworzyć niestandardowe zachowanie:
- Zabstrakcjonuj wynikową tablicę bajtów jako strumień z możliwością wyszukiwania dla usług podrzędnych niestandardowych.
- Zintegruj wynik z innymi interfejsami API lub usługami.
- Zmodyfikuj dane audio, zapisz niestandardowe nagłówki .wav i wykonaj powiązane zadania.
Tę zmianę można wprowadzić w poprzednim przykładzie. Najpierw usuń AudioConfig, ponieważ ręcznie zarządzasz zachowaniem danych wyjściowych od tego momentu, aby zwiększyć kontrolę. Przekaż None dla AudioConfig w konstruktorze SpeechSynthesizer.
Uwaga
Przekazywanie None dla AudioConfig, zamiast pomijania go jak w poprzednim przykładzie wyjściowym, nie odtwarza domyślnie dźwięku na bieżącym aktywnym urządzeniu wyjściowym.
Zapisz wynik w zmiennej SpeechSynthesisResult . Właściwość audio_data zawiera obiekt bytes danych wyjściowych. Możesz pracować z tym obiektem ręcznie lub użyć AudioDataStream klasy do zarządzania strumieniem w pamięci.
W tym przykładzie użyj konstruktora AudioDataStream , aby pobrać strumień z wyniku:
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)
W tym momencie można zaimplementować dowolne zachowanie niestandardowe przy użyciu wynikowego stream obiektu.
Dostosowywanie formatu audio
Możesz dostosować atrybuty danych wyjściowych dźwięku, w tym:
- Typ pliku audio
- Częstotliwość próbkowania
- Głębokość bitu
Aby zmienić format dźwięku, użyj set_speech_synthesis_output_format() funkcji w SpeechConfig obiekcie . Ta funkcja oczekuje enum wystąpienia typu SpeechSynthesisOutputFormat. Użyj polecenia , enum aby wybrać format danych wyjściowych. Aby uzyskać dostępne formaty, zobacz listę formatów audio.
Istnieją różne opcje dla różnych typów plików, w zależności od wymagań. Z definicji nieprzetworzone formaty, takie jak Raw24Khz16BitMonoPcm nie zawierają nagłówków dźwięku. Używaj formatów pierwotnych tylko w jednej z następujących sytuacji:
- Wiesz, że implementacja podrzędna może dekodować nieprzetworzone strumienie bitowe.
- Planujesz ręcznie tworzyć nagłówki na podstawie czynników, takich jak głębokość bitów, częstotliwość próbkowania i liczba kanałów.
W tym przykładzie określono format Riff24Khz16BitMonoPcm RIFF o wysokiej wierności, ustawiając SpeechSynthesisOutputFormat dla SpeechConfig obiektu. Podobnie jak w przykładzie w poprzedniej sekcji, użyj AudioDataStream, aby uzyskać strumień w pamięci wyniku, a następnie zapisać go w pliku.
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")
Po uruchomieniu programu zapisuje plik .wav do określonej ścieżki.
Dostosowywanie cech mowy przy użyciu języka SSML
Za pomocą języka SSML można dostroić intonację, wymowę, szybkość mówienia, głośność i inne aspekty w wyniku zamiany tekstu na mowę, przesyłając żądania przy użyciu schematu XML. W tej sekcji przedstawiono przykład zmiany głosu. Aby uzyskać więcej informacji, zobacz Omówienie języka znaczników syntezy mowy.
Aby rozpocząć korzystanie z języka SSML do dostosowywania, wprowadź niewielką zmianę, która przełącza głos.
Utwórz nowy plik XML dla konfiguracji SSML w katalogu głównym projektu.
<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US"> <voice name="en-US-Ava:DragonHDLatestNeural"> When you're on the freeway, it's a good idea to use a GPS. </voice> </speak>W tym przykładzie plik jest ssml.xml. Element główny to zawsze
<speak>. Zawijanie tekstu w elemecie<voice>umożliwia zmianę głosu przy użyciu parametruname. Aby uzyskać pełną listę obsługiwanych głosów neuronowych, zobacz Obsługiwane języki.Zmień żądanie syntezy mowy, aby odwołać się do pliku XML. Żądanie jest w większości takie samo. Zamiast używać
speak_text_async()funkcji, użyj poleceniaspeak_ssml_async(). Ta funkcja oczekuje ciągu XML. Najpierw odczytaj konfigurację SSML jako ciąg. Od tego momentu obiekt wynikowy jest dokładnie taki sam jak w poprzednich przykładach.Uwaga
Jeśli element
ssml_stringzawierana początku ciągu, musisz usunąć format BOM lub usługa zwróci błąd. W tym celu należy ustawićencodingparametr w następujący sposób: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")
Uwaga
Aby zmienić głos bez użycia języka SSML, możesz ustawić właściwość przy SpeechConfig użyciu polecenia speech_config.speech_synthesis_voice_name = "en-US-Ava:DragonHDLatestNeural".
Subskrypcja zdarzeń syntezatora
Możesz chcieć uzyskać więcej szczegółowych informacji na temat przetwarzania i wyników zamiany tekstu na mowę. Na przykład możesz chcieć wiedzieć, kiedy syntetyzator uruchamia się i zatrzymuje, lub możesz chcieć wiedzieć o innych zdarzeniach napotkanych podczas syntezy.
Używając narzędzia SpeechSynthesizer do zamiany tekstu na mowę, możesz subskrybować zdarzenia w tej tabeli:
| Wydarzenie | opis | Przypadek użycia |
|---|---|---|
BookmarkReached |
Sygnał, że osiągnięto zakładkę. Aby wyzwolić zdarzenie osiągnięcia zakładki, w bookmark wymagany jest element . To zdarzenie zgłasza czas, jaki upłynął w danych wyjściowych audio między rozpoczęciem syntezy a elementem bookmark . Właściwość zdarzenia Text to wartość typu string, którą ustawiłeś w atrybucie mark zakładki. Elementy bookmark nie są wypowiadane. |
Możesz użyć elementu bookmark, aby wstawić niestandardowe znaczniki w SSML w celu uzyskania przesunięcia każdego znacznika w strumieniu audio. Element bookmark może służyć do odwoływania się do określonej lokalizacji w sekwencji tekstu lub tagu. |
SynthesisCanceled |
Sygnały, że synteza mowy została anulowana. | Możesz potwierdzić, kiedy synteza zostanie anulowana. |
SynthesisCompleted |
Sygnały, że synteza mowy jest kompletna. | Można potwierdzić, kiedy synteza jest zakończona. |
SynthesisStarted |
Sygnały, że rozpoczęła się synteza mowy. | Możesz potwierdzić, kiedy rozpoczęto syntezę. |
Synthesizing |
Sygnały, że synteza mowy jest w toku. To zdarzenie jest uruchamiane za każdym razem, gdy zestaw SDK otrzymuje fragment dźwięku z usługi Mowa. | Możesz potwierdzić, kiedy synteza jest w toku. |
VisemeReceived |
Sygnały, że odebrano zdarzenie viseme. | Visemes są często używane do reprezentowania kluczowych pozycji w obserwowanej wypowiedzi. Kluczowe pozy obejmują położenie ust, szczęki i języka w produkcji konkretnej fonemy. Możesz użyć visemów, aby animować twarz postaci w trakcie odtwarzania dźwięku mowy. |
WordBoundary |
Sygnalizuje, że została odebrana granica słowa. To zdarzenie jest wywoływane na początku każdego nowego słowa mówionego, znaku interpunkcyjnego i zdania. Zdarzenie zgłasza przesunięcie czasowe bieżącego słowa w znacznikach od początku sygnału dźwięku wyjściowego. To zdarzenie zgłasza również położenie znaku w tekście wejściowym lub SSML bezpośrednio przed wyrazem, który ma być wypowiadany. | To zdarzenie jest często używane do pobierania względnych pozycji tekstu i odpowiadającego mu dźwięku. Możesz chcieć wiedzieć o nowym słowie, a następnie podjąć działania na podstawie czasu. Możesz na przykład uzyskać informacje, które mogą pomóc w podjęciu decyzji o tym, kiedy i na jak długo akcentować wyrazy podczas ich wypowiadania. |
Uwaga
Zdarzenia są zgłaszane, gdy dane wyjściowe audio stają się dostępne, co następuje szybciej niż odtwarzanie na urządzeniu wyjściowym. Obiekt wywołujący musi odpowiednio synchronizować procesy przesyłania strumieniowego i w czasie rzeczywistym.
Oto przykład pokazujący sposób subskrybowania zdarzeń na potrzeby syntezy mowy.
Ważne
Używaj kluczy interfejsu API z ostrożnością. Nie dołączaj klucza interfejsu API bezpośrednio do kodu i nigdy nie publikuj go publicznie. Jeśli używasz klucza interfejsu API, zapisz go bezpiecznie w usłudze Azure Key Vault. Aby uzyskać więcej informacji na temat bezpiecznego używania kluczy interfejsu API w aplikacjach, zobacz Klucze interfejsu API w usłudze Azure Key Vault.
Aby uzyskać więcej informacji na temat zabezpieczeń usług sztucznej inteligencji, zobacz Uwierzytelnianie żądań w usługach Azure AI.
Postępuj zgodnie z instrukcjami w przewodniku Szybki start, ale zastąp zawartość tego pliku speech-synthesis.py następującym kodem w języku Python:
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?")
Więcej przykładów zamiany tekstu na mowę można znaleźć w witrynie GitHub.
Używanie niestandardowego punktu końcowego
Niestandardowy punkt końcowy jest funkcjonalnie identyczny ze standardowym punktem końcowym używanym do obsługi żądań zamiany tekstu na mowę.
Jedną z różnic jest to, że endpoint_id należy określić, aby używać niestandardowego głosu za pośrednictwem zestawu Speech SDK. Możesz rozpocząć od szybkiego startu z tekstem na mowę, a następnie zaktualizować kod zawierając endpoint_id i speech_synthesis_voice_name.
speech_config = speechsdk.SpeechConfig(subscription=os.environ.get('SPEECH_KEY'), region=os.environ.get('SPEECH_REGION'))
speech_config.endpoint_id = "YourEndpointId"
speech_config.speech_synthesis_voice_name = "YourCustomVoiceName"
Aby użyć głosu niestandardowego za pomocą języka SSML (Speech Synthesis Markup Language), określ nazwę modelu jako nazwę głosu. W tym przykładzie użyto głosu YourCustomVoiceName.
<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>
Uruchamianie i używanie kontenera
Kontenery umożliwiające przetwarzanie mowy udostępniają interfejsy API punktów końcowych zapytań opartych na websocketach, które są dostępne za pośrednictwem SDK Przetwarzania Mowy i CLI usługi Przetwarzania Mowy. Domyślnie zestaw SDK usługi Mowa i interfejs wiersza polecenia usługi Mowa używają publicznej usługi rozpoznawania mowy. Aby użyć kontenera, należy zmienić metodę inicjowania. Użyj adresu URL hosta kontenera zamiast klucza i regionu.
Aby uzyskać więcej informacji na temat kontenerów, zobacz Instalowanie i uruchamianie kontenerów usługi Mowa za pomocą platformy Docker.
Dokumentacja referencyjna | Pakiet (NuGet) | Dodatkowe przykłady na GitHubie
W tym przewodniku z instrukcjami poznasz typowe wzorce projektowe służące do wykonywania syntezy mowy w tekście.
Aby uzyskać więcej informacji na temat następujących obszarów, zobacz Co to jest zamiana tekstu na mowę?
- Uzyskiwanie odpowiedzi jako strumieni w pamięci.
- Dostosowywanie szybkości próbkowania danych wyjściowych i szybkości bitów.
- Przesyłanie żądań syntezy przy użyciu języka znaczników syntezy mowy (SSML).
- Korzystanie z głosów neuronowych.
- Subskrybowanie eventów i reagowanie na wyniki.
Wybieranie języka syntezy i głosu
Funkcja zamiany tekstu na mowę w usłudze Mowa obsługuje ponad 400 głosów i ponad 140 języków i wariantów. Pełną listę możesz uzyskać lub wypróbować w galerii głosów.
Określ język lub głos SpeechConfig, aby dopasować do tekstu wejściowego i użyć określonego głosu. Poniższy fragment kodu pokazuje, jak działa ta technika:
static async Task SynthesizeAudioAsync()
{
var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
// Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
speechConfig.SpeechSynthesisLanguage = "en-US";
speechConfig.SpeechSynthesisVoiceName = "en-US-Ava:DragonHDLatestNeural";
}
Wszystkie neuronowe głosy są wielojęzyczne i płynne we własnym języku i języku angielskim. Na przykład, jeśli tekst wejściowy w języku angielskim to "Jestem podekscytowany, aby spróbować zamiany tekstu na mowę", a Ty wybierzesz es-ES-Ximena:DragonHDLatestNeural, tekst będzie przemawiany w języku angielskim z hiszpańskim akcentem.
Jeśli głos nie mówi w języku tekstu wejściowego, usługa rozpoznawania mowy nie tworzy syntetyzowanego dźwięku. Aby uzyskać pełną listę obsługiwanych głosów neuronowych, zobacz Obsługa języka i głosu dla usługi mowy.
Uwaga
Domyślny głos to pierwszy głos zwracany dla lokalizacji z interfejsu API Listy Głosów.
Głos, który mówi, jest określany w kolejności priorytetu w następujący sposób:
- Jeśli nie ustawisz
SpeechSynthesisVoiceNamelubSpeechSynthesisLanguage, domyślny głos dlaen-USbędzie użyty. - Jeśli tylko ustawisz
SpeechSynthesisLanguage, mówi domyślny głos dla określonego ustawienia regionalnego. - Jeśli zarówno
SpeechSynthesisVoiceName, jak iSpeechSynthesisLanguagesą ustawione, ustawienieSpeechSynthesisLanguagejest ignorowane. Głos, który określisz przy użyciuSpeechSynthesisVoiceName, mówi. - Jeśli element głosowy jest ustawiony przy użyciu języka znaczników syntezy mowy (SSML), ustawienia
SpeechSynthesisVoiceNameiSpeechSynthesisLanguagesą ignorowane.
Podsumowując, kolejność priorytetu można opisać jako:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Wynik |
|---|---|---|---|
| ✗ | ✗ | ✗ | Domyślny głos dla en-US wypowiedzi |
| ✗ | ✔ | ✗ | Domyślny głos dla określonych ustawień regionalnych mówi. |
| ✔ | ✔ | ✗ | Głos, który określisz przy użyciu SpeechSynthesisVoiceName, mówi. |
| ✔ | ✔ | ✔ | Głos, który określisz za pomocą języka znaczników SSML, przemawia. |
Syntetyzowanie mowy do pliku
Utwórz obiekt SpeechSynthesizer. Ten obiekt pokazany w poniższych fragmentach uruchamia konwersje tekstu na mowę i wysyła dane wyjściowe do głośników, plików lub innych strumieni wyjściowych.
SpeechSynthesizer akceptuje jako parametry:
- Obiekt SpeechConfig utworzony w poprzednim kroku.
- Obiekt AudioConfig określający sposób obsługi wyników wyjściowych.
AudioConfigUtwórz wystąpienie, które automatycznie zapisuje dane wyjściowe do pliku .wav przy użyciu funkcjiFromWavFileOutput(). Utwórz wystąpienie za pomocą instrukcjiusing.static async Task SynthesizeAudioAsync() { var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion"); using var audioConfig = AudioConfig.FromWavFileOutput("path/to/write/file.wav"); }Instrukcja
usingw tym kontekście automatycznie usuwa niezarządzane zasoby i powoduje, że obiekt wykracza poza zakres po usunięciu.Utwórz instancję przy użyciu innej instrukcji
SpeechSynthesizerusing. Przekaż obiektspeechConfigi obiektaudioConfigjako parametry. Aby syntetyzować mowę i zapisywać w pliku, uruchom polecenieSpeakTextAsync()z ciągiem tekstu.
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");
}
Po uruchomieniu programu program tworzy syntetyzowany plik .wav , który jest zapisywany w określonej lokalizacji. Ten wynik jest dobrym przykładem najbardziej podstawowego użycia. Następnie możesz dostosować dane wyjściowe i obsłużyć odpowiedź wyjściową jako strumień w pamięci na potrzeby pracy ze scenariuszami niestandardowymi.
Syntezowanie do wyjścia głośnikowego
Aby wyprowadzić syntetyzowaną mowę do bieżącego aktywnego urządzenia wyjściowego, takiego jak głośnik, pomiń AudioConfig parametr podczas tworzenia instancji SpeechSynthesizer. Oto przykład:
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");
}
Uzyskaj wynik w postaci strumienia w pamięci
Możesz użyć wynikowych danych dźwiękowych jako strumienia w pamięci, zamiast bezpośredniego zapisywania do pliku. Za pomocą strumienia w pamięci można tworzyć niestandardowe zachowanie:
- Zabstrakcjonuj wynikową tablicę bajtów jako strumień z możliwością wyszukiwania dla usług podrzędnych niestandardowych.
- Zintegruj wynik z innymi interfejsami API lub usługami.
- Zmodyfikuj dane audio, zapisz niestandardowe nagłówki .wav i wykonaj powiązane zadania.
Tę zmianę można wprowadzić w poprzednim przykładzie. Najpierw usuń blok AudioConfig, ponieważ od tej pory ręcznie zarządzasz zachowaniem danych wyjściowych w celu zwiększenia kontroli. Przekaż null dla AudioConfig w konstruktorze SpeechSynthesizer.
Uwaga
Przekazywanie null dla AudioConfig zamiast jego pominięcia, jak w poprzednim przykładzie wyjściowym, nie powoduje domyślnego odtwarzania dźwięku na bieżącym aktywnym urządzeniu audio.
Zapisz wynik w zmiennej SpeechSynthesisResult . Właściwość AudioData zawiera wystąpienie byte [] dla danych wyjściowych. Możesz pracować z tym byte [] wystąpieniem ręcznie lub użyć klasy AudioDataStream do zarządzania strumieniem w pamięci.
W tym przykładzie użyjesz funkcji statycznej AudioDataStream.FromResult() , aby pobrać strumień z wyniku:
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);
}
W tym momencie można zaimplementować dowolne zachowanie niestandardowe przy użyciu wynikowego stream obiektu.
Dostosowywanie formatu audio
Możesz dostosować atrybuty danych wyjściowych dźwięku, w tym:
- Typ pliku audio
- Częstotliwość próbkowania
- Głębokość bitu
Aby zmienić format dźwięku, należy użyć SetSpeechSynthesisOutputFormat() funkcji w SpeechConfig obiekcie . Ta funkcja oczekuje enum wystąpienia typu SpeechSynthesisOutputFormat. Użyj polecenia , enum aby wybrać format danych wyjściowych. Aby uzyskać dostępne formaty, zobacz listę formatów audio.
Istnieją różne opcje dla różnych typów plików, w zależności od wymagań. Z definicji nieprzetworzone formaty, takie jak Raw24Khz16BitMonoPcm nie zawierają nagłówków dźwięku. Używaj formatów pierwotnych tylko w jednej z następujących sytuacji:
- Wiesz, że implementacja podrzędna może dekodować nieprzetworzone strumienie bitowe.
- Planujesz ręcznie tworzyć nagłówki na podstawie czynników, takich jak głębokość bitów, częstotliwość próbkowania i liczba kanałów.
W tym przykładzie określono format Riff24Khz16BitMonoPcm RIFF o wysokiej wierności, ustawiając SpeechSynthesisOutputFormat dla SpeechConfig obiektu. Podobnie jak w przykładzie w poprzedniej sekcji, użyj AudioDataStream aby uzyskać strumień w pamięci wyniku, a następnie zapisać go w pliku.
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");
}
Po uruchomieniu programu zapisuje plik .wav do określonej ścieżki.
Dostosowywanie cech mowy przy użyciu języka SSML
Za pomocą języka SSML można dostroić intonację, wymowę, szybkość mówienia, głośność i inne aspekty w wyniku zamiany tekstu na mowę, przesyłając żądania przy użyciu schematu XML. W tej sekcji przedstawiono przykład zmiany głosu. Aby uzyskać więcej informacji, zobacz Omówienie języka znaczników syntezy mowy.
Aby rozpocząć korzystanie z języka SSML do dostosowywania, należy wprowadzić niewielką zmianę, która przełącza głos.
Utwórz nowy plik XML dla konfiguracji SSML w katalogu głównym projektu.
<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US"> <voice name="en-US-Ava:DragonHDLatestNeural"> When you're on the freeway, it's a good idea to use a GPS. </voice> </speak>W tym przykładzie plik jest ssml.xml. Element główny to zawsze
<speak>. Zawijanie tekstu w elemecie<voice>umożliwia zmianę głosu przy użyciu parametruname. Aby uzyskać pełną listę obsługiwanych głosów neuronowych, zobacz Obsługiwane języki.Zmień żądanie syntezy mowy, aby odwołać się do pliku XML. Żądanie jest w większości takie samo, ale zamiast używać funkcji
SpeakTextAsync(), należy użyć funkcjiSpeakSsmlAsync(). Ta funkcja oczekuje ciągu XML. Najpierw załaduj konfigurację SSML jako ciąg przy użyciu poleceniaFile.ReadAllText(). Od tego momentu obiekt wynikowy jest dokładnie taki sam jak w poprzednich przykładach.Uwaga
Jeśli używasz programu Visual Studio, konfiguracja kompilacji prawdopodobnie nie znajdzie pliku XML domyślnie. Kliknij prawym przyciskiem myszy plik XML i wybierz polecenie Właściwości. Zmień Akcja kompilacji na Zawartość. Zmień Kopiuj do katalogu wyjściowego na Zawsze kopiuj.
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"); }
Uwaga
Aby zmienić głos bez użycia języka SSML, możesz ustawić właściwość przy SpeechConfig użyciu polecenia SpeechConfig.SpeechSynthesisVoiceName = "en-US-Ava:DragonHDLatestNeural";.
Subskrypcja zdarzeń syntezatora
Możesz chcieć uzyskać więcej szczegółowych informacji na temat przetwarzania i wyników zamiany tekstu na mowę. Na przykład możesz chcieć wiedzieć, kiedy syntetyzator uruchamia się i zatrzymuje, lub możesz chcieć wiedzieć o innych zdarzeniach napotkanych podczas syntezy.
Używając narzędzia SpeechSynthesizer do zamiany tekstu na mowę, możesz subskrybować zdarzenia w tej tabeli:
| Wydarzenie | opis | Przypadek użycia |
|---|---|---|
BookmarkReached |
Sygnał, że osiągnięto zakładkę. Aby wyzwolić zdarzenie osiągnięcia zakładki, w bookmark wymagany jest element . To zdarzenie zgłasza czas, jaki upłynął w danych wyjściowych audio między rozpoczęciem syntezy a elementem bookmark . Właściwość zdarzenia Text to wartość typu string, którą ustawiłeś w atrybucie mark zakładki. Elementy bookmark nie są wypowiadane. |
Możesz użyć elementu bookmark, aby wstawić niestandardowe znaczniki w SSML w celu uzyskania przesunięcia każdego znacznika w strumieniu audio. Element bookmark może służyć do odwoływania się do określonej lokalizacji w sekwencji tekstu lub tagu. |
SynthesisCanceled |
Sygnały, że synteza mowy została anulowana. | Możesz potwierdzić, kiedy synteza zostanie anulowana. |
SynthesisCompleted |
Sygnały, że synteza mowy jest kompletna. | Można potwierdzić, kiedy synteza jest zakończona. |
SynthesisStarted |
Sygnały, że rozpoczęła się synteza mowy. | Możesz potwierdzić, kiedy rozpoczęto syntezę. |
Synthesizing |
Sygnały, że synteza mowy jest w toku. To zdarzenie jest uruchamiane za każdym razem, gdy zestaw SDK otrzymuje fragment dźwięku z usługi Mowa. | Możesz potwierdzić, kiedy synteza jest w toku. |
VisemeReceived |
Sygnały, że odebrano zdarzenie viseme. | Visemes są często używane do reprezentowania kluczowych pozycji w obserwowanej wypowiedzi. Kluczowe pozy obejmują położenie ust, szczęki i języka w produkcji konkretnej fonemy. Możesz użyć visemów, aby animować twarz postaci w trakcie odtwarzania dźwięku mowy. |
WordBoundary |
Sygnalizuje, że została odebrana granica słowa. To zdarzenie jest wywoływane na początku każdego nowego słowa mówionego, znaku interpunkcyjnego i zdania. Zdarzenie zgłasza przesunięcie czasowe bieżącego słowa w znacznikach od początku sygnału dźwięku wyjściowego. To zdarzenie zgłasza również położenie znaku w tekście wejściowym lub SSML bezpośrednio przed wyrazem, który ma być wypowiadany. | To zdarzenie jest często używane do pobierania względnych pozycji tekstu i odpowiadającego mu dźwięku. Możesz chcieć wiedzieć o nowym słowie, a następnie podjąć działania na podstawie czasu. Możesz na przykład uzyskać informacje, które mogą pomóc w podjęciu decyzji o tym, kiedy i na jak długo akcentować wyrazy podczas ich wypowiadania. |
Uwaga
Zdarzenia są zgłaszane, gdy dane wyjściowe audio stają się dostępne, co następuje szybciej niż odtwarzanie na urządzeniu wyjściowym. Obiekt wywołujący musi odpowiednio synchronizować procesy przesyłania strumieniowego i w czasie rzeczywistym.
Oto przykład pokazujący sposób subskrybowania zdarzeń na potrzeby syntezy mowy.
Ważne
Używaj kluczy interfejsu API z ostrożnością. Nie dołączaj klucza interfejsu API bezpośrednio do kodu i nigdy nie publikuj go publicznie. Jeśli używasz klucza interfejsu API, zapisz go bezpiecznie w usłudze Azure Key Vault. Aby uzyskać więcej informacji na temat bezpiecznego używania kluczy interfejsu API w aplikacjach, zobacz Klucze interfejsu API w usłudze Azure Key Vault.
Aby uzyskać więcej informacji na temat zabezpieczeń usług sztucznej inteligencji, zobacz Uwierzytelnianie żądań w usługach Azure AI.
Postępuj zgodnie z instrukcjami w przewodniku Szybki start, ale zastąp zawartość tego pliku Program.cs następującym kodem języka C#:
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();
}
}
Więcej przykładów zamiany tekstu na mowę można znaleźć w witrynie GitHub.
Używanie niestandardowego punktu końcowego
Własny punkt końcowy jest funkcjonalnie identyczny ze standardowym punktem końcowym używanym do realizacji żądań zamiany tekstu na mowę.
Jedną z różnic jest to, że EndpointId należy określić, aby używać niestandardowego głosu za pośrednictwem zestawu Speech SDK. Możesz rozpocząć od szybkiego startu z tekstem na mowę, a następnie zaktualizować kod zawierając EndpointId i SpeechSynthesisVoiceName.
var speechConfig = SpeechConfig.FromSubscription(speechKey, speechRegion);
speechConfig.SpeechSynthesisVoiceName = "YourCustomVoiceName";
speechConfig.EndpointId = "YourEndpointId";
Aby użyć głosu niestandardowego za pomocą języka SSML (Speech Synthesis Markup Language), określ nazwę modelu jako nazwę głosu. W tym przykładzie użyto głosu YourCustomVoiceName.
<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>
Uruchamianie i używanie kontenera
Kontenery umożliwiające przetwarzanie mowy udostępniają interfejsy API punktów końcowych zapytań opartych na websocketach, które są dostępne za pośrednictwem SDK Przetwarzania Mowy i CLI usługi Przetwarzania Mowy. Domyślnie zestaw SDK usługi Mowa i interfejs wiersza polecenia usługi Mowa używają publicznej usługi rozpoznawania mowy. Aby użyć kontenera, należy zmienić metodę inicjowania. Użyj adresu URL hosta kontenera zamiast klucza i regionu.
Aby uzyskać więcej informacji na temat kontenerów, zobacz Instalowanie i uruchamianie kontenerów usługi Mowa za pomocą platformy Docker.
Dokumentacja referencyjna | Pakiet (npm) | Dodatkowe przykłady na GitHub | Kod źródłowy biblioteki
W tym przewodniku z instrukcjami poznasz typowe wzorce projektowe służące do wykonywania syntezy mowy w tekście.
Aby uzyskać więcej informacji na temat następujących obszarów, zobacz Co to jest zamiana tekstu na mowę?
- Uzyskiwanie odpowiedzi jako strumieni w pamięci.
- Dostosowywanie szybkości próbkowania danych wyjściowych i szybkości bitów.
- Przesyłanie żądań syntezy przy użyciu języka znaczników syntezy mowy (SSML).
- Korzystanie z głosów neuronowych.
- Subskrybowanie eventów i reagowanie na wyniki.
Wybieranie języka syntezy i głosu
Funkcja zamiany tekstu na mowę w usłudze Mowa obsługuje ponad 400 głosów i ponad 140 języków i wariantów. Pełną listę możesz uzyskać lub wypróbować w galerii głosów.
Określ język lub głos SpeechConfig, aby dopasować do tekstu wejściowego i użyć określonego głosu:
function synthesizeSpeech() {
const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
// Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
speechConfig.speechSynthesisLanguage = "en-US";
speechConfig.speechSynthesisVoiceName = "en-US-Ava:DragonHDLatestNeural";
}
synthesizeSpeech();
Wszystkie neuronowe głosy są wielojęzyczne i płynne we własnym języku i języku angielskim. Jeśli na przykład tekst wejściowy w języku angielskim to "Cieszę się na możliwość wypróbowania funkcji zamiany tekstu na mowę", a następnie wybierzesz es-ES-Ximena:DragonHDLatestNeural, to tekst jest mówiony po angielsku z hiszpańskim akcentem.
Jeśli głos nie mówi w języku tekstu wejściowego, usługa rozpoznawania mowy nie tworzy syntetyzowanego dźwięku. Aby uzyskać pełną listę obsługiwanych głosów neuronowych, zobacz Obsługa języka i głosu dla usługi mowy.
Uwaga
Domyślny głos to pierwszy głos zwracany dla lokalizacji z interfejsu API Listy Głosów.
Głos, który mówi, jest określany w kolejności priorytetu w następujący sposób:
- Jeśli nie ustawisz
SpeechSynthesisVoiceNamelubSpeechSynthesisLanguage, domyślny głos dlaen-USbędzie użyty. - Jeśli tylko ustawisz
SpeechSynthesisLanguage, mówi domyślny głos dla określonego ustawienia regionalnego. - Jeśli zarówno
SpeechSynthesisVoiceName, jak iSpeechSynthesisLanguagesą ustawione, ustawienieSpeechSynthesisLanguagejest ignorowane. Głos, który określisz przy użyciuSpeechSynthesisVoiceName, mówi. - Jeśli element głosowy jest ustawiony przy użyciu języka znaczników syntezy mowy (SSML), ustawienia
SpeechSynthesisVoiceNameiSpeechSynthesisLanguagesą ignorowane.
Podsumowując, kolejność priorytetu można opisać jako:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Wynik |
|---|---|---|---|
| ✗ | ✗ | ✗ | Domyślny głos dla en-US wypowiedzi |
| ✗ | ✔ | ✗ | Domyślny głos dla określonych ustawień regionalnych mówi. |
| ✔ | ✔ | ✗ | Głos, który określisz przy użyciu SpeechSynthesisVoiceName, mówi. |
| ✔ | ✔ | ✔ | Głos, który określisz za pomocą języka znaczników SSML, przemawia. |
Syntetyzowanie tekstu na mowę
Aby wyprowadzić zsyntezowaną mowę do bieżącego aktywnego urządzenia wyjściowego, takiego jak głośnik, utwórz instancję AudioConfig za pomocą funkcji statycznej fromDefaultSpeakerOutput(). Oto przykład:
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();
});
}
Po uruchomieniu programu syntetyzowany dźwięk jest odtwarzany z głośnika. Ten wynik jest dobrym przykładem najbardziej podstawowego użycia. Następnie możesz dostosować dane wyjściowe i obsłużyć odpowiedź wyjściową jako strumień w pamięci na potrzeby pracy ze scenariuszami niestandardowymi.
Uzyskaj wynik w postaci strumienia w pamięci
Możesz użyć wynikowych danych dźwiękowych jako strumienia w pamięci, zamiast bezpośredniego zapisywania do pliku. Za pomocą strumienia w pamięci można tworzyć niestandardowe zachowanie:
- Zabstrakcjonuj wynikową tablicę bajtów jako strumień z możliwością wyszukiwania dla usług podrzędnych niestandardowych.
- Zintegruj wynik z innymi interfejsami API lub usługami.
- Zmodyfikuj dane audio, napisz nagłówki niestandardowe
.wavi wykonaj powiązane zadania.
Tę zmianę można wprowadzić w poprzednim przykładzie. Usuń blok AudioConfig, ponieważ od tego momentu ręcznie zarządzasz zachowaniem danych wyjściowych dla zwiększonej kontroli. Następnie przekaż null dla AudioConfig w konstruktorze SpeechSynthesizer.
Uwaga
Przekazywanie null dla AudioConfig, zamiast pomijania go jak w poprzednim przykładzie wyjściowym, nie odtwarza domyślnie dźwięku na bieżącym aktywnym urządzeniu wyjściowym.
Zapisz wynik w zmiennej SpeechSynthesisResult . Właściwość SpeechSynthesisResult.audioData zwraca ArrayBuffer wartość danych wyjściowych— domyślny typ strumienia przeglądarki. W przypadku kodu po stronie serwera przekonwertuj ArrayBuffer na strumień buforu.
Następujący kod działa po stronie klienta:
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();
});
}
Dowolne zachowanie niestandardowe można zaimplementować przy użyciu wynikowego ArrayBuffer obiektu.
ArrayBuffer jest typowym formatem do odbioru w przeglądarce i odtwarzania w tym formacie.
W przypadku dowolnego kodu opartego na serwerze, jeśli musisz pracować z danymi jako strumieniem, musisz przekonwertować ArrayBuffer obiekt na strumień:
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();
});
}
Dostosowywanie formatu audio
Możesz dostosować atrybuty danych wyjściowych dźwięku, w tym:
- Typ pliku audio
- Częstotliwość próbkowania
- Głębokość bitu
Aby zmienić format audio, użyj speechSynthesisOutputFormat właściwości w SpeechConfig obiekcie . Ta właściwość oczekuje enum wystąpienia typu SpeechSynthesisOutputFormat. Użyj polecenia , enum aby wybrać format danych wyjściowych. Aby uzyskać dostępne formaty, zobacz listę formatów audio.
Istnieją różne opcje dla różnych typów plików, w zależności od wymagań. Z definicji nieprzetworzone formaty, takie jak Raw24Khz16BitMonoPcm nie zawierają nagłówków dźwięku. Używaj formatów pierwotnych tylko w jednej z następujących sytuacji:
- Wiesz, że implementacja podrzędna może dekodować nieprzetworzone strumienie bitowe.
- Planujesz ręcznie tworzyć nagłówki na podstawie czynników, takich jak głębokość bitów, częstotliwość próbkowania i liczba kanałów.
W tym przykładzie określono format Riff24Khz16BitMonoPcm RIFF o wysokiej wierności, ustawiając speechSynthesisOutputFormat dla SpeechConfig obiektu. Podobnie jak w przykładzie w poprzedniej sekcji, pobierz dane audio ArrayBuffer i wejdź z nim w interakcję.
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();
});
}
Dostosowywanie cech mowy przy użyciu języka SSML
Za pomocą języka SSML można dostroić intonację, wymowę, szybkość mówienia, głośność i inne aspekty w wyniku zamiany tekstu na mowę, przesyłając żądania przy użyciu schematu XML. W tej sekcji przedstawiono przykład zmiany głosu. Aby uzyskać więcej informacji, zobacz Omówienie języka znaczników syntezy mowy.
Aby rozpocząć korzystanie z języka SSML do dostosowywania, należy wprowadzić niewielką zmianę, która przełącza głos.
Utwórz nowy plik XML dla konfiguracji SSML w katalogu głównym projektu.
<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US"> <voice name="en-US-Ava:DragonHDLatestNeural"> When you're on the freeway, it's a good idea to use a GPS. </voice> </speak>W tym przykładzie to ssml.xml. Element główny to zawsze
<speak>. Zawijanie tekstu w elemecie<voice>umożliwia zmianę głosu przy użyciu parametruname. Aby uzyskać pełną listę obsługiwanych głosów neuronowych, zobacz Obsługiwane języki.Zmień żądanie syntezy mowy, aby odwołać się do pliku XML. Żądanie jest w większości takie samo, ale zamiast używać funkcji
speakTextAsync(), należy użyć funkcjispeakSsmlAsync(). Ta funkcja oczekuje ciągu XML. Utwórz funkcję, aby załadować plik XML i zwrócić go jako ciąg:function xmlToString(filePath) { const xml = readFileSync(filePath, "utf8"); return xml; }Aby uzyskać więcej informacji na temat
readFileSync, zobacz system plików Node.js.Obiekt wynikowy jest dokładnie taki sam jak w poprzednich przykładach:
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(); }); }
Uwaga
Aby zmienić głos bez użycia języka SSML, możesz ustawić właściwość przy SpeechConfig użyciu polecenia SpeechConfig.speechSynthesisVoiceName = "en-US-Ava:DragonHDLatestNeural";.
Subskrypcja zdarzeń syntezatora
Możesz chcieć uzyskać więcej szczegółowych informacji na temat przetwarzania i wyników zamiany tekstu na mowę. Na przykład możesz chcieć wiedzieć, kiedy syntetyzator uruchamia się i zatrzymuje, lub możesz chcieć wiedzieć o innych zdarzeniach napotkanych podczas syntezy.
Używając narzędzia SpeechSynthesizer do zamiany tekstu na mowę, możesz subskrybować zdarzenia w tej tabeli:
| Wydarzenie | opis | Przypadek użycia |
|---|---|---|
BookmarkReached |
Sygnał, że osiągnięto zakładkę. Aby wyzwolić zdarzenie osiągnięcia zakładki, w bookmark wymagany jest element . To zdarzenie zgłasza czas, jaki upłynął w danych wyjściowych audio między rozpoczęciem syntezy a elementem bookmark . Właściwość zdarzenia Text to wartość typu string, którą ustawiłeś w atrybucie mark zakładki. Elementy bookmark nie są wypowiadane. |
Możesz użyć elementu bookmark, aby wstawić niestandardowe znaczniki w SSML w celu uzyskania przesunięcia każdego znacznika w strumieniu audio. Element bookmark może służyć do odwoływania się do określonej lokalizacji w sekwencji tekstu lub tagu. |
SynthesisCanceled |
Sygnały, że synteza mowy została anulowana. | Możesz potwierdzić, kiedy synteza zostanie anulowana. |
SynthesisCompleted |
Sygnały, że synteza mowy jest kompletna. | Można potwierdzić, kiedy synteza jest zakończona. |
SynthesisStarted |
Sygnały, że rozpoczęła się synteza mowy. | Możesz potwierdzić, kiedy rozpoczęto syntezę. |
Synthesizing |
Sygnały, że synteza mowy jest w toku. To zdarzenie jest uruchamiane za każdym razem, gdy zestaw SDK otrzymuje fragment dźwięku z usługi Mowa. | Możesz potwierdzić, kiedy synteza jest w toku. |
VisemeReceived |
Sygnały, że odebrano zdarzenie viseme. | Visemes są często używane do reprezentowania kluczowych pozycji w obserwowanej wypowiedzi. Kluczowe pozy obejmują położenie ust, szczęki i języka w produkcji konkretnej fonemy. Możesz użyć visemów, aby animować twarz postaci w trakcie odtwarzania dźwięku mowy. |
WordBoundary |
Sygnalizuje, że została odebrana granica słowa. To zdarzenie jest wywoływane na początku każdego nowego słowa mówionego, znaku interpunkcyjnego i zdania. Zdarzenie zgłasza przesunięcie czasowe bieżącego słowa w znacznikach od początku sygnału dźwięku wyjściowego. To zdarzenie zgłasza również położenie znaku w tekście wejściowym lub SSML bezpośrednio przed wyrazem, który ma być wypowiadany. | To zdarzenie jest często używane do pobierania względnych pozycji tekstu i odpowiadającego mu dźwięku. Możesz chcieć wiedzieć o nowym słowie, a następnie podjąć działania na podstawie czasu. Możesz na przykład uzyskać informacje, które mogą pomóc w podjęciu decyzji o tym, kiedy i na jak długo akcentować wyrazy podczas ich wypowiadania. |
Uwaga
Zdarzenia są zgłaszane, gdy dane wyjściowe audio stają się dostępne, co następuje szybciej niż odtwarzanie na urządzeniu wyjściowym. Obiekt wywołujący musi odpowiednio synchronizować procesy przesyłania strumieniowego i w czasie rzeczywistym.
Oto przykład pokazujący sposób subskrybowania zdarzeń na potrzeby syntezy mowy.
Ważne
Używaj kluczy interfejsu API z ostrożnością. Nie dołączaj klucza interfejsu API bezpośrednio do kodu i nigdy nie publikuj go publicznie. Jeśli używasz klucza interfejsu API, zapisz go bezpiecznie w usłudze Azure Key Vault. Aby uzyskać więcej informacji na temat bezpiecznego używania kluczy interfejsu API w aplikacjach, zobacz Klucze interfejsu API w usłudze Azure Key Vault.
Aby uzyskać więcej informacji na temat zabezpieczeń usług sztucznej inteligencji, zobacz Uwierzytelnianie żądań w usługach Azure AI.
Możesz postępować zgodnie z instrukcjami w przewodniku Szybki start, ale zastąp zawartość tego pliku SpeechSynthesis.js następującym kodem JavaScript.
(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;
});
}());
Więcej przykładów zamiany tekstu na mowę można znaleźć w witrynie GitHub.
Uruchamianie i używanie kontenera
Kontenery umożliwiające przetwarzanie mowy udostępniają interfejsy API punktów końcowych zapytań opartych na websocketach, które są dostępne za pośrednictwem SDK Przetwarzania Mowy i CLI usługi Przetwarzania Mowy. Domyślnie zestaw SDK usługi Mowa i interfejs wiersza polecenia usługi Mowa używają publicznej usługi rozpoznawania mowy. Aby użyć kontenera, należy zmienić metodę inicjowania. Użyj adresu URL hosta kontenera zamiast klucza i regionu.
Aby uzyskać więcej informacji na temat kontenerów, zobacz Instalowanie i uruchamianie kontenerów usługi Mowa za pomocą platformy Docker.
| Dokumentacja referencyjna Dodatkowe przykłady w usłudze GitHub
W tym przewodniku z instrukcjami poznasz typowe wzorce projektowe służące do wykonywania syntezy mowy w tekście.
Aby uzyskać więcej informacji na temat następujących obszarów, zobacz Co to jest zamiana tekstu na mowę?
- Uzyskiwanie odpowiedzi jako strumieni w pamięci.
- Dostosowywanie szybkości próbkowania danych wyjściowych i szybkości bitów.
- Przesyłanie żądań syntezy przy użyciu języka znaczników syntezy mowy (SSML).
- Korzystanie z głosów neuronowych.
- Subskrybowanie eventów i reagowanie na wyniki.
Wybieranie języka syntezy i głosu
Funkcja zamiany tekstu na mowę w usłudze Mowa obsługuje ponad 400 głosów i ponad 140 języków i wariantów. Pełną listę możesz uzyskać lub wypróbować w galerii głosów.
Określ język lub głos funkcji SpeechConfig , aby dopasować tekst wejściowy i użyć określonego głosu. Poniższy fragment kodu pokazuje, jak działa ta technika:
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-Ava:DragonHDLatestNeural");
}
Wszystkie neuronowe głosy są wielojęzyczne i płynne we własnym języku i języku angielskim. Jeśli na przykład tekst wejściowy w języku angielskim to "Cieszę się na możliwość wypróbowania funkcji zamiany tekstu na mowę", a następnie wybierzesz es-ES-Ximena:DragonHDLatestNeural, to tekst jest mówiony po angielsku z hiszpańskim akcentem.
Jeśli głos nie mówi w języku tekstu wejściowego, usługa rozpoznawania mowy nie tworzy syntetyzowanego dźwięku. Aby uzyskać pełną listę obsługiwanych głosów neuronowych, zobacz Obsługa języka i głosu dla usługi mowy.
Uwaga
Domyślny głos to pierwszy głos zwracany dla lokalizacji z interfejsu API Listy Głosów.
Głos, który mówi, jest określany w kolejności priorytetu w następujący sposób:
- Jeśli nie ustawisz
SpeechSynthesisVoiceNamelubSpeechSynthesisLanguage, domyślny głos dlaen-USbędzie użyty. - Jeśli tylko ustawisz
SpeechSynthesisLanguage, mówi domyślny głos dla określonego ustawienia regionalnego. - Jeśli zarówno
SpeechSynthesisVoiceName, jak iSpeechSynthesisLanguagesą ustawione, ustawienieSpeechSynthesisLanguagejest ignorowane. Głos określony przy użyciuSpeechSynthesisVoiceNamemówi. - Jeśli element głosowy jest ustawiony przy użyciu języka znaczników syntezy mowy (SSML), ustawienia
SpeechSynthesisVoiceNameiSpeechSynthesisLanguagesą ignorowane.
Podsumowując, kolejność priorytetu można opisać jako:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Wynik |
|---|---|---|---|
| ✗ | ✗ | ✗ | Domyślny głos dla en-US wypowiedzi |
| ✗ | ✔ | ✗ | Domyślny głos dla określonych ustawień regionalnych mówi. |
| ✔ | ✔ | ✗ | Głos, który określisz przy użyciu SpeechSynthesisVoiceName, mówi. |
| ✔ | ✔ | ✔ | Głos, który określisz za pomocą języka znaczników SSML, przemawia. |
Syntetyzowanie mowy do pliku
Utwórz SpeechSynthesizer obiekt. Obiekt ten uruchamia konwersje tekstu na mowę i dane wyjściowe do głośników, plików lub innych strumieni wyjściowych.
SpeechSynthesizer akceptuje jako parametry:
-
SpeechConfigObiekt utworzony w poprzednim kroku. -
AudioConfigObiekt określający sposób obsługi wyników wyjściowych.
AudioConfigUtwórz instancję, aby automatycznie zapisywać wynik w pliku .wav przy użyciu funkcji statycznejfromWavFileOutput().public static void main(String[] args) { SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion"); AudioConfig audioConfig = AudioConfig.fromWavFileOutput("path/to/write/file.wav"); }Utwórz instancję
SpeechSynthesizer. Przekaż obiektspeechConfigi obiektaudioConfigjako parametry. Aby syntetyzować mowę i zapisywać w pliku, uruchom polecenieSpeakText()z ciągiem tekstu.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"); }
Po uruchomieniu programu program tworzy syntetyzowany plik .wav , który jest zapisywany w określonej lokalizacji. Ten wynik jest dobrym przykładem najbardziej podstawowego użycia. Następnie możesz dostosować dane wyjściowe i obsłużyć odpowiedź wyjściową jako strumień w pamięci na potrzeby pracy ze scenariuszami niestandardowymi.
Syntezowanie do wyjścia głośnikowego
Możesz chcieć uzyskać więcej szczegółowych informacji na temat przetwarzania i wyników zamiany tekstu na mowę. Na przykład możesz chcieć wiedzieć, kiedy syntetyzator uruchamia się i zatrzymuje, lub możesz chcieć wiedzieć o innych zdarzeniach napotkanych podczas syntezy.
Aby wyprowadzić zsyntezowaną mowę do bieżącego aktywnego urządzenia wyjściowego, takiego jak głośnik, utwórz instancję AudioConfig za pomocą funkcji statycznej fromDefaultSpeakerOutput(). Oto przykład:
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");
}
Uzyskaj wynik w postaci strumienia w pamięci
Możesz użyć wynikowych danych dźwiękowych jako strumienia w pamięci, zamiast bezpośredniego zapisywania do pliku. Za pomocą strumienia w pamięci można tworzyć niestandardowe zachowanie:
- Zabstrakcjonuj wynikową tablicę bajtów jako strumień z możliwością wyszukiwania dla usług podrzędnych niestandardowych.
- Zintegruj wynik z innymi interfejsami API lub usługami.
- Zmodyfikuj dane audio, zapisz niestandardowe nagłówki .wav i wykonaj powiązane zadania.
Tę zmianę można wprowadzić w poprzednim przykładzie. Najpierw usuń blok AudioConfig, ponieważ od tej pory ręcznie zarządzasz zachowaniem danych wyjściowych w celu zwiększenia kontroli. Następnie przekaż null dla AudioConfig w konstruktorze SpeechSynthesizer.
Uwaga
Przekazywanie null dla AudioConfig, zamiast pomijania go jak w poprzednim przykładzie wyjściowym, nie odtwarza domyślnie dźwięku na bieżącym aktywnym urządzeniu wyjściowym.
Zapisz wynik w zmiennej SpeechSynthesisResult . Funkcja SpeechSynthesisResult.getAudioData() zwraca wystąpienie byte [] danych wyjściowych. Możesz pracować z tym byte [] wystąpieniem ręcznie lub użyć klasy AudioDataStream do zarządzania strumieniem w pamięci.
W tym przykładzie użyj funkcji statycznej AudioDataStream.fromResult() , aby pobrać strumień z wyniku:
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());
}
W tym momencie można zaimplementować dowolne zachowanie niestandardowe przy użyciu wynikowego stream obiektu.
Dostosowywanie formatu audio
Możesz dostosować atrybuty danych wyjściowych dźwięku, w tym:
- Typ pliku audio
- Częstotliwość próbkowania
- Głębokość bitu
Aby zmienić format dźwięku, należy użyć setSpeechSynthesisOutputFormat() funkcji w SpeechConfig obiekcie . Ta funkcja oczekuje enum wystąpienia typu SpeechSynthesisOutputFormat. Użyj polecenia , enum aby wybrać format danych wyjściowych. Aby uzyskać dostępne formaty, zobacz listę formatów audio.
Istnieją różne opcje dla różnych typów plików, w zależności od wymagań. Z definicji nieprzetworzone formaty, takie jak Raw24Khz16BitMonoPcm nie zawierają nagłówków dźwięku. Używaj formatów pierwotnych tylko w jednej z następujących sytuacji:
- Wiesz, że implementacja podrzędna może dekodować nieprzetworzone strumienie bitowe.
- Planujesz ręcznie tworzyć nagłówki na podstawie czynników, takich jak głębokość bitów, częstotliwość próbkowania i liczba kanałów.
W tym przykładzie określono format Riff24Khz16BitMonoPcm RIFF o wysokiej wierności, ustawiając SpeechSynthesisOutputFormat dla SpeechConfig obiektu. Podobnie jak w przykładzie w poprzedniej sekcji, użyj AudioDataStream, aby uzyskać strumień w pamięci wyniku, a następnie zapisać go w pliku.
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");
}
Po uruchomieniu programu zapisuje plik .wav do określonej ścieżki.
Dostosowywanie cech mowy przy użyciu języka SSML
Za pomocą języka SSML można dostroić intonację, wymowę, szybkość mówienia, głośność i inne aspekty w wyniku zamiany tekstu na mowę, przesyłając żądania przy użyciu schematu XML. W tej sekcji przedstawiono przykład zmiany głosu. Aby uzyskać więcej informacji, zobacz artykuł z instrukcjami dotyczącymi języka SSML.
Aby rozpocząć korzystanie z języka SSML do dostosowywania, należy wprowadzić niewielką zmianę, która przełącza głos.
Utwórz nowy plik XML dla konfiguracji SSML w katalogu głównym projektu.
<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US"> <voice name="en-US-Ava:DragonHDLatestNeural"> When you're on the freeway, it's a good idea to use a GPS. </voice> </speak>W tym przykładzie plik jest ssml.xml. Element główny to zawsze
<speak>. Zawijanie tekstu w elemecie<voice>umożliwia zmianę głosu przy użyciu parametruname. Aby uzyskać pełną listę obsługiwanych głosów neuronowych, zobacz Obsługiwane języki.Zmień żądanie syntezy mowy, aby odwołać się do pliku XML. Żądanie jest w większości takie samo. Zamiast używać funkcji
SpeakText(), używaszSpeakSsml(). Ta funkcja oczekuje ciągu XML, więc najpierw utwórz funkcję, aby załadować plik XML i zwrócić go jako ciąg: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."; } }W tym momencie obiekt wynikowy jest dokładnie taki sam jak w poprzednich przykładach:
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"); }
Uwaga
Aby zmienić głos bez użycia SSML, ustaw właściwość na SpeechConfig za pomocą SpeechConfig.setSpeechSynthesisVoiceName("en-US-Ava:DragonHDLatestNeural");.
Subskrypcja zdarzeń syntezatora
Możesz chcieć uzyskać więcej szczegółowych informacji na temat przetwarzania i wyników zamiany tekstu na mowę. Na przykład możesz chcieć wiedzieć, kiedy syntetyzator uruchamia się i zatrzymuje, lub możesz chcieć wiedzieć o innych zdarzeniach napotkanych podczas syntezy.
Używając narzędzia SpeechSynthesizer do zamiany tekstu na mowę, możesz subskrybować zdarzenia w tej tabeli:
| Wydarzenie | opis | Przypadek użycia |
|---|---|---|
BookmarkReached |
Sygnał, że osiągnięto zakładkę. Aby wyzwolić zdarzenie osiągnięcia zakładki, w bookmark wymagany jest element . To zdarzenie zgłasza czas, jaki upłynął w danych wyjściowych audio między rozpoczęciem syntezy a elementem bookmark . Właściwość zdarzenia Text to wartość typu string, którą ustawiłeś w atrybucie mark zakładki. Elementy bookmark nie są wypowiadane. |
Możesz użyć elementu bookmark, aby wstawić niestandardowe znaczniki w SSML w celu uzyskania przesunięcia każdego znacznika w strumieniu audio. Element bookmark może służyć do odwoływania się do określonej lokalizacji w sekwencji tekstu lub tagu. |
SynthesisCanceled |
Sygnały, że synteza mowy została anulowana. | Możesz potwierdzić, kiedy synteza zostanie anulowana. |
SynthesisCompleted |
Sygnały, że synteza mowy jest kompletna. | Można potwierdzić, kiedy synteza jest zakończona. |
SynthesisStarted |
Sygnały, że rozpoczęła się synteza mowy. | Możesz potwierdzić, kiedy rozpoczęto syntezę. |
Synthesizing |
Sygnały, że synteza mowy jest w toku. To zdarzenie jest uruchamiane za każdym razem, gdy zestaw SDK otrzymuje fragment dźwięku z usługi Mowa. | Możesz potwierdzić, kiedy synteza jest w toku. |
VisemeReceived |
Sygnały, że odebrano zdarzenie viseme. | Visemes są często używane do reprezentowania kluczowych pozycji w obserwowanej wypowiedzi. Kluczowe pozy obejmują położenie ust, szczęki i języka w produkcji konkretnej fonemy. Możesz użyć visemów, aby animować twarz postaci w trakcie odtwarzania dźwięku mowy. |
WordBoundary |
Sygnalizuje, że została odebrana granica słowa. To zdarzenie jest wywoływane na początku każdego nowego słowa mówionego, znaku interpunkcyjnego i zdania. Zdarzenie zgłasza przesunięcie czasowe bieżącego słowa w znacznikach od początku sygnału dźwięku wyjściowego. To zdarzenie zgłasza również położenie znaku w tekście wejściowym lub SSML bezpośrednio przed wyrazem, który ma być wypowiadany. | To zdarzenie jest często używane do pobierania względnych pozycji tekstu i odpowiadającego mu dźwięku. Możesz chcieć wiedzieć o nowym słowie, a następnie podjąć działania na podstawie czasu. Możesz na przykład uzyskać informacje, które mogą pomóc w podjęciu decyzji o tym, kiedy i na jak długo akcentować wyrazy podczas ich wypowiadania. |
Uwaga
Zdarzenia są zgłaszane, gdy dane wyjściowe audio stają się dostępne, co następuje szybciej niż odtwarzanie na urządzeniu wyjściowym. Obiekt wywołujący musi odpowiednio synchronizować procesy przesyłania strumieniowego i w czasie rzeczywistym.
Oto przykład pokazujący sposób subskrybowania zdarzeń na potrzeby syntezy mowy.
Ważne
Używaj kluczy interfejsu API z ostrożnością. Nie dołączaj klucza interfejsu API bezpośrednio do kodu i nigdy nie publikuj go publicznie. Jeśli używasz klucza interfejsu API, zapisz go bezpiecznie w usłudze Azure Key Vault. Aby uzyskać więcej informacji na temat bezpiecznego używania kluczy interfejsu API w aplikacjach, zobacz Klucze interfejsu API w usłudze Azure Key Vault.
Aby uzyskać więcej informacji na temat zabezpieczeń usług sztucznej inteligencji, zobacz Uwierzytelnianie żądań w usługach Azure AI.
Postępuj zgodnie z instrukcjami w przewodniku Szybki start, ale zastąp zawartość tego pliku SpeechSynthesis.java następującym kodem Java:
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);
}
}
Więcej przykładów zamiany tekstu na mowę można znaleźć w witrynie GitHub.
Używanie niestandardowego punktu końcowego
Niestandardowy punkt końcowy jest funkcjonalnie identyczny ze standardowym punktem końcowym używanym do obsługi żądań zamiany tekstu na mowę.
Jedną z różnic jest to, że EndpointId należy określić, aby używać niestandardowego głosu za pośrednictwem zestawu Speech SDK. Możesz rozpocząć od szybkiego startu z tekstem na mowę, a następnie zaktualizować kod zawierając EndpointId i SpeechSynthesisVoiceName.
SpeechConfig speechConfig = SpeechConfig.fromSubscription(speechKey, speechRegion);
speechConfig.setSpeechSynthesisVoiceName("YourCustomVoiceName");
speechConfig.setEndpointId("YourEndpointId");
Aby użyć głosu niestandardowego za pomocą języka SSML (Speech Synthesis Markup Language), określ nazwę modelu jako nazwę głosu. W tym przykładzie użyto głosu YourCustomVoiceName.
<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>
Uruchamianie i używanie kontenera
Kontenery umożliwiające przetwarzanie mowy udostępniają interfejsy API punktów końcowych zapytań opartych na websocketach, które są dostępne za pośrednictwem SDK Przetwarzania Mowy i CLI usługi Przetwarzania Mowy. Domyślnie zestaw SDK usługi Mowa i interfejs wiersza polecenia usługi Mowa używają publicznej usługi rozpoznawania mowy. Aby użyć kontenera, należy zmienić metodę inicjowania. Użyj adresu URL hosta kontenera zamiast klucza i regionu.
Aby uzyskać więcej informacji na temat kontenerów, zobacz Instalowanie i uruchamianie kontenerów usługi Mowa za pomocą platformy Docker.
Dokumentacja referencyjna | Pakiet (NuGet) | Dodatkowe przykłady na GitHubie
W tym przewodniku z instrukcjami poznasz typowe wzorce projektowe służące do wykonywania syntezy mowy w tekście.
Aby uzyskać więcej informacji na temat następujących obszarów, zobacz Co to jest zamiana tekstu na mowę?
- Uzyskiwanie odpowiedzi jako strumieni w pamięci.
- Dostosowywanie szybkości próbkowania danych wyjściowych i szybkości bitów.
- Przesyłanie żądań syntezy przy użyciu języka znaczników syntezy mowy (SSML).
- Korzystanie z głosów neuronowych.
- Subskrybowanie eventów i reagowanie na wyniki.
Wybieranie języka syntezy i głosu
Funkcja zamiany tekstu na mowę w usłudze Mowa obsługuje ponad 400 głosów i ponad 140 języków i wariantów. Zapoznaj się z pełną listą obsługiwanych ustawień regionalnych zamiany tekstu na mowę lub wypróbuj je w galerii głosów.
Określ język lub głos klasy SpeechConfig , aby dopasować tekst wejściowy i użyć określonego głosu. Poniższy fragment kodu pokazuje, jak działa ta technika:
void synthesizeSpeech()
{
auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
// Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
speechConfig->SetSpeechSynthesisLanguage("en-US");
speechConfig->SetSpeechSynthesisVoiceName("en-US-Ava:DragonHDLatestNeural");
}
Wszystkie neuronowe głosy są wielojęzyczne i płynne we własnym języku i języku angielskim. Jeśli na przykład tekst wejściowy w języku angielskim to "Cieszę się na możliwość wypróbowania funkcji zamiany tekstu na mowę", a następnie wybierzesz es-ES-Ximena:DragonHDLatestNeural, to tekst jest mówiony po angielsku z hiszpańskim akcentem.
Jeśli głos nie mówi w języku tekstu wejściowego, usługa rozpoznawania mowy nie tworzy syntetyzowanego dźwięku. Aby uzyskać pełną listę obsługiwanych głosów neuronowych, zobacz Obsługa języka i głosu dla usługi mowy.
Uwaga
Domyślny głos to pierwszy głos zwracany dla lokalizacji z interfejsu API Listy Głosów.
Głos, który mówi, jest określany w kolejności priorytetu w następujący sposób:
- Jeśli nie ustawisz
SpeechSynthesisVoiceNamelubSpeechSynthesisLanguage, domyślny głos dlaen-USbędzie użyty. - Jeśli tylko ustawisz
SpeechSynthesisLanguage, mówi domyślny głos dla określonego ustawienia regionalnego. - Jeśli zarówno
SpeechSynthesisVoiceName, jak iSpeechSynthesisLanguagesą ustawione, ustawienieSpeechSynthesisLanguagejest ignorowane. Głos, który określisz przy użyciuSpeechSynthesisVoiceName, mówi. - Jeśli element głosowy jest ustawiony przy użyciu języka znaczników syntezy mowy (SSML), ustawienia
SpeechSynthesisVoiceNameiSpeechSynthesisLanguagesą ignorowane.
Podsumowując, kolejność priorytetu można opisać jako:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Wynik |
|---|---|---|---|
| ✗ | ✗ | ✗ | Domyślny głos dla en-US wypowiedzi |
| ✗ | ✔ | ✗ | Domyślny głos dla określonych ustawień regionalnych mówi. |
| ✔ | ✔ | ✗ | Głos, który określisz przy użyciu SpeechSynthesisVoiceName, mówi. |
| ✔ | ✔ | ✔ | Głos, który określisz za pomocą języka znaczników SSML, przemawia. |
Syntetyzowanie mowy do pliku
Utwórz obiekt SpeechSynthesizer. Ten obiekt pokazany w poniższych fragmentach uruchamia konwersje tekstu na mowę i wysyła dane wyjściowe do głośników, plików lub innych strumieni wyjściowych.
SpeechSynthesizer akceptuje jako parametry:
- Obiekt SpeechConfig utworzony w poprzednim kroku.
- Obiekt AudioConfig określający sposób obsługi wyników wyjściowych.
Utwórz wystąpienie
AudioConfig, aby przy użyciu funkcji automatycznie zapisywać dane wyjściowe w plikuFromWavFileOutput().void synthesizeSpeech() { auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion"); auto audioConfig = AudioConfig::FromWavFileOutput("path/to/write/file.wav"); }Utwórz instancję
SpeechSynthesizer. Przekaż obiektspeechConfigi obiektaudioConfigjako parametry. Aby syntetyzować mowę i zapisywać w pliku, uruchom polecenieSpeakTextAsync()z ciągiem tekstu.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(); }
Po uruchomieniu programu program tworzy syntetyzowany plik .wav , który jest zapisywany w określonej lokalizacji. Ten wynik jest dobrym przykładem najbardziej podstawowego użycia. Następnie możesz dostosować dane wyjściowe i obsłużyć odpowiedź wyjściową jako strumień w pamięci na potrzeby pracy ze scenariuszami niestandardowymi.
Syntezowanie do wyjścia głośnikowego
Aby uzyskać syntetyzowaną mowę do bieżącego aktywnego urządzenia wyjściowego, takiego jak głośnik, pomiń AudioConfig parametr podczas tworzenia wystąpienia SpeechSynthesizer. Oto przykład:
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();
}
Uzyskaj wynik w postaci strumienia w pamięci
Możesz użyć wynikowych danych dźwiękowych jako strumienia w pamięci, zamiast bezpośredniego zapisywania do pliku. Za pomocą strumienia w pamięci można tworzyć niestandardowe zachowanie:
- Zabstrakcjonuj wynikową tablicę bajtów jako strumień z możliwością wyszukiwania dla usług podrzędnych niestandardowych.
- Zintegruj wynik z innymi interfejsami API lub usługami.
- Zmodyfikuj dane audio, zapisz niestandardowe nagłówki .wav i wykonaj powiązane zadania.
Tę zmianę można wprowadzić w poprzednim przykładzie. Najpierw usuń blok AudioConfig, ponieważ od tej pory ręcznie zarządzasz zachowaniem danych wyjściowych w celu zwiększenia kontroli. Przekaż NULL dla AudioConfig w konstruktorze SpeechSynthesizer.
Uwaga
Przekazywanie NULL dla AudioConfig zamiast jego pominięcia, jak w poprzednim przykładzie wyjściowym, nie powoduje domyślnego odtwarzania dźwięku na bieżącym aktywnym urządzeniu audio.
Zapisz wynik w zmiennej SpeechSynthesisResult . Getter GetAudioData zwraca byte [] wystąpienie dla danych wyjściowych. Możesz pracować z tym byte [] wystąpieniem ręcznie lub użyć klasy AudioDataStream do zarządzania strumieniem w pamięci.
W tym przykładzie użyj funkcji statycznej AudioDataStream.FromResult() , aby pobrać strumień z wyniku:
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);
}
W tym momencie można zaimplementować dowolne zachowanie niestandardowe przy użyciu wynikowego stream obiektu.
Dostosowywanie formatu audio
Możesz dostosować atrybuty danych wyjściowych dźwięku, w tym:
- Typ pliku audio
- Częstotliwość próbkowania
- Głębokość bitu
Aby zmienić format dźwięku, użyj SetSpeechSynthesisOutputFormat() funkcji w SpeechConfig obiekcie . Ta funkcja oczekuje enum wystąpienia typu SpeechSynthesisOutputFormat. Użyj polecenia , enum aby wybrać format danych wyjściowych. Aby uzyskać dostępne formaty, zobacz listę formatów audio.
Istnieją różne opcje dla różnych typów plików, w zależności od wymagań. Z definicji nieprzetworzone formaty, takie jak Raw24Khz16BitMonoPcm nie zawierają nagłówków dźwięku. Używaj formatów pierwotnych tylko w jednej z następujących sytuacji:
- Wiesz, że implementacja podrzędna może dekodować nieprzetworzone strumienie bitowe.
- Planujesz ręcznie tworzyć nagłówki na podstawie czynników, takich jak głębokość bitów, częstotliwość próbkowania i liczba kanałów.
W tym przykładzie określono format Riff24Khz16BitMonoPcm RIFF o wysokiej wierności, ustawiając SpeechSynthesisOutputFormat dla SpeechConfig obiektu. Podobnie jak w przykładzie w poprzedniej sekcji, użyj AudioDataStream, aby uzyskać strumień w pamięci wyniku, a następnie zapisać go w pliku.
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();
}
Po uruchomieniu programu zapisuje plik .wav do określonej ścieżki.
Dostosowywanie cech mowy przy użyciu języka SSML
Za pomocą języka SSML można dostroić intonację, wymowę, szybkość mówienia, głośność i inne aspekty w wyniku zamiany tekstu na mowę, przesyłając żądania przy użyciu schematu XML. W tej sekcji przedstawiono przykład zmiany głosu. Aby uzyskać więcej informacji, zobacz Omówienie języka znaczników syntezy mowy.
Aby rozpocząć korzystanie z języka SSML do dostosowywania, wprowadź niewielką zmianę, która przełącza głos.
Utwórz nowy plik XML dla konfiguracji SSML w katalogu głównym projektu.
<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US"> <voice name="en-US-Ava:DragonHDLatestNeural"> When you're on the freeway, it's a good idea to use a GPS. </voice> </speak>W tym przykładzie plik jest ssml.xml. Element główny to zawsze
<speak>. Zawijanie tekstu w elemecie<voice>umożliwia zmianę głosu przy użyciu parametruname. Aby uzyskać pełną listę obsługiwanych głosów neuronowych, zobacz Obsługiwane języki.Zmień żądanie syntezy mowy, aby odwołać się do pliku XML. Żądanie jest w większości takie samo. Zamiast używać funkcji
SpeakTextAsync(), używaszSpeakSsmlAsync(). Ta funkcja oczekuje ciągu XML. Najpierw załaduj konfigurację SSML jako ciąg. Od tego momentu obiekt wynikowy jest dokładnie taki sam jak w poprzednich przykładach.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(); }
Uwaga
Aby zmienić głos bez użycia języka SSML, możesz ustawić właściwość przy SpeechConfig użyciu polecenia SpeechConfig.SetSpeechSynthesisVoiceName("en-US-Ava:DragonHDLatestNeural").
Subskrypcja zdarzeń syntezatora
Możesz chcieć uzyskać więcej szczegółowych informacji na temat przetwarzania i wyników zamiany tekstu na mowę. Na przykład możesz chcieć wiedzieć, kiedy syntetyzator uruchamia się i zatrzymuje, lub możesz chcieć wiedzieć o innych zdarzeniach napotkanych podczas syntezy.
Używając narzędzia SpeechSynthesizer do zamiany tekstu na mowę, możesz subskrybować zdarzenia w tej tabeli:
| Wydarzenie | opis | Przypadek użycia |
|---|---|---|
BookmarkReached |
Sygnał, że osiągnięto zakładkę. Aby wyzwolić zdarzenie osiągnięcia zakładki, w bookmark wymagany jest element . To zdarzenie zgłasza czas, jaki upłynął w danych wyjściowych audio między rozpoczęciem syntezy a elementem bookmark . Właściwość zdarzenia Text to wartość typu string, którą ustawiłeś w atrybucie mark zakładki. Elementy bookmark nie są wypowiadane. |
Możesz użyć elementu bookmark, aby wstawić niestandardowe znaczniki w SSML w celu uzyskania przesunięcia każdego znacznika w strumieniu audio. Element bookmark może służyć do odwoływania się do określonej lokalizacji w sekwencji tekstu lub tagu. |
SynthesisCanceled |
Sygnały, że synteza mowy została anulowana. | Możesz potwierdzić, kiedy synteza zostanie anulowana. |
SynthesisCompleted |
Sygnały, że synteza mowy jest kompletna. | Można potwierdzić, kiedy synteza jest zakończona. |
SynthesisStarted |
Sygnały, że rozpoczęła się synteza mowy. | Możesz potwierdzić, kiedy rozpoczęto syntezę. |
Synthesizing |
Sygnały, że synteza mowy jest w toku. To zdarzenie jest uruchamiane za każdym razem, gdy zestaw SDK otrzymuje fragment dźwięku z usługi Mowa. | Możesz potwierdzić, kiedy synteza jest w toku. |
VisemeReceived |
Sygnały, że odebrano zdarzenie viseme. | Visemes są często używane do reprezentowania kluczowych pozycji w obserwowanej wypowiedzi. Kluczowe pozy obejmują położenie ust, szczęki i języka w produkcji konkretnej fonemy. Możesz użyć visemów, aby animować twarz postaci w trakcie odtwarzania dźwięku mowy. |
WordBoundary |
Sygnalizuje, że została odebrana granica słowa. To zdarzenie jest wywoływane na początku każdego nowego słowa mówionego, znaku interpunkcyjnego i zdania. Zdarzenie zgłasza przesunięcie czasowe bieżącego słowa w znacznikach od początku sygnału dźwięku wyjściowego. To zdarzenie zgłasza również położenie znaku w tekście wejściowym lub SSML bezpośrednio przed wyrazem, który ma być wypowiadany. | To zdarzenie jest często używane do pobierania względnych pozycji tekstu i odpowiadającego mu dźwięku. Możesz chcieć wiedzieć o nowym słowie, a następnie podjąć działania na podstawie czasu. Możesz na przykład uzyskać informacje, które mogą pomóc w podjęciu decyzji o tym, kiedy i na jak długo akcentować wyrazy podczas ich wypowiadania. |
Uwaga
Zdarzenia są zgłaszane, gdy dane wyjściowe audio stają się dostępne, co następuje szybciej niż odtwarzanie na urządzeniu wyjściowym. Obiekt wywołujący musi odpowiednio synchronizować procesy przesyłania strumieniowego i w czasie rzeczywistym.
Oto przykład pokazujący sposób subskrybowania zdarzeń na potrzeby syntezy mowy.
Ważne
Używaj kluczy interfejsu API z ostrożnością. Nie dołączaj klucza interfejsu API bezpośrednio do kodu i nigdy nie publikuj go publicznie. Jeśli używasz klucza interfejsu API, zapisz go bezpiecznie w usłudze Azure Key Vault. Aby uzyskać więcej informacji na temat bezpiecznego używania kluczy interfejsu API w aplikacjach, zobacz Klucze interfejsu API w usłudze Azure Key Vault.
Aby uzyskać więcej informacji na temat zabezpieczeń usług sztucznej inteligencji, zobacz Uwierzytelnianie żądań w usługach Azure AI.
Postępuj zgodnie z instrukcjami w przewodniku Szybki start, ale zastąp zawartość tego pliku main.cpp następującym kodem:
#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 (std::string(speechKey).empty() || std::string(endpoint).empty()) {
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
}
Więcej przykładów zamiany tekstu na mowę można znaleźć w witrynie GitHub.
Używanie niestandardowego punktu końcowego
Niestandardowy punkt końcowy jest funkcjonalnie identyczny ze standardowym punktem końcowym używanym do obsługi żądań zamiany tekstu na mowę.
Jedną z różnic jest to, że EndpointId należy określić, aby używać niestandardowego głosu za pośrednictwem zestawu Speech SDK. Możesz rozpocząć od szybkiego startu z tekstem na mowę, a następnie zaktualizować kod zawierając EndpointId i SpeechSynthesisVoiceName.
auto speechConfig = SpeechConfig::FromSubscription(speechKey, speechRegion);
speechConfig->SetSpeechSynthesisVoiceName("YourCustomVoiceName");
speechConfig->SetEndpointId("YourEndpointId");
Aby użyć głosu niestandardowego za pomocą języka SSML (Speech Synthesis Markup Language), określ nazwę modelu jako nazwę głosu. W tym przykładzie użyto głosu YourCustomVoiceName.
<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>
Uruchamianie i używanie kontenera
Kontenery umożliwiające przetwarzanie mowy udostępniają interfejsy API punktów końcowych zapytań opartych na websocketach, które są dostępne za pośrednictwem SDK Przetwarzania Mowy i CLI usługi Przetwarzania Mowy. Domyślnie zestaw SDK usługi Mowa i interfejs wiersza polecenia usługi Mowa używają publicznej usługi rozpoznawania mowy. Aby użyć kontenera, należy zmienić metodę inicjowania. Użyj adresu URL hosta kontenera zamiast klucza i regionu.
Aby uzyskać więcej informacji na temat kontenerów, zobacz Instalowanie i uruchamianie kontenerów usługi Mowa za pomocą platformy Docker.
Dokumentacja referencyjna | Package (Go) | Dodatkowe przykłady na GitHubie
W tym przewodniku z instrukcjami poznasz typowe wzorce projektowe służące do wykonywania syntezy mowy w tekście.
Aby uzyskać więcej informacji na temat następujących obszarów, zobacz Co to jest zamiana tekstu na mowę?
- Uzyskiwanie odpowiedzi jako strumieni w pamięci.
- Dostosowywanie szybkości próbkowania danych wyjściowych i szybkości bitów.
- Przesyłanie żądań syntezy przy użyciu języka znaczników syntezy mowy (SSML).
- Korzystanie z głosów neuronowych.
- Subskrybowanie eventów i reagowanie na wyniki.
Wymagania wstępne
- Subskrypcja platformy Azure. Możesz utworzyć go bezpłatnie.
- Utwórz zasób Foundry dla usługi Speech w portalu Azure.
- Pobierz klucz zasobu Mowy oraz region. Po wdrożeniu zasobu usługi Mowa wybierz pozycję Przejdź do zasobu , aby wyświetlić klucze i zarządzać nimi.
Zainstaluj zestaw SDK Mowy
Zanim cokolwiek zrobisz, musisz zainstalować Speech SDK dla języka Go.
Zamiana tekstu na mowę do głośnika
Użyj poniższego przykładu kodu, aby uruchomić syntezę mowy na domyślnym urządzeniu wyjściowym audio. Zastąp zmienne subscription i region kluczem mowy i lokalizacją/regionem. Uruchomienie skryptu powoduje, że tekst wejściowy jest czytany przez domyślnego lektora.
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)
}
}
}
}
Uruchom następujące polecenia, aby utworzyć plik go.mod , który łączy się ze składnikami hostowanymi w usłudze GitHub:
go mod init quickstart
go get github.com/Microsoft/cognitive-services-speech-sdk-go
Teraz skompiluj i uruchom kod:
go build
go run quickstart
Aby uzyskać szczegółowe informacje o klasach, zapoznaj się z dokumentacją odniesienia SpeechConfig i SpeechSynthesizer.
Zamiana tekstu na mowę bezpośrednio do strumienia w pamięci
Możesz użyć wynikowych danych dźwiękowych jako strumienia w pamięci, zamiast bezpośredniego zapisywania do pliku. Za pomocą strumienia w pamięci można tworzyć niestandardowe zachowanie:
- Zabstrakcjonuj wynikową tablicę bajtów jako strumień z możliwością wyszukiwania dla usług podrzędnych niestandardowych.
- Zintegruj wynik z innymi interfejsami API lub usługami.
- Zmodyfikuj dane audio, zapisz niestandardowe nagłówki .wav i wykonaj powiązane zadania.
Tę zmianę można wprowadzić w poprzednim przykładzie. Usuń blok AudioConfig, ponieważ od tego momentu ręcznie zarządzasz zachowaniem danych wyjściowych dla zwiększonej kontroli. Następnie przekaż nil dla AudioConfig w konstruktorze SpeechSynthesizer.
Uwaga
Przekazywanie nil dla AudioConfig, zamiast jego pominięcia jak w poprzednim przykładzie wyjścia głośnika, spowoduje, że dźwięk nie będzie odtwarzany domyślnie na aktualnym aktywnym urządzeniu wyjściowym.
Zapisz wynik w zmiennej SpeechSynthesisResult . Właściwość AudioData zwraca instancję []byte dla danych wyjściowych. Możesz pracować z tym []byte wystąpieniem ręcznie lub użyć klasy AudioDataStream do zarządzania strumieniem w pamięci.
W tym przykładzie użyjesz funkcji statycznej NewAudioDataStreamFromSpeechSynthesisResult() , aby pobrać strumień z wyniku.
Zastąp zmienne subscription i region kluczem mowy i lokalizacją/regionem:
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))
}
}
Uruchom następujące polecenia, aby utworzyć plik go.mod , który łączy się ze składnikami hostowanymi w usłudze GitHub:
go mod init quickstart
go get github.com/Microsoft/cognitive-services-speech-sdk-go
Teraz skompiluj i uruchom kod:
go build
go run quickstart
Aby uzyskać szczegółowe informacje o klasach, zapoznaj się z dokumentacją odniesienia SpeechConfig i SpeechSynthesizer.
Wybieranie języka syntezy i głosu
Funkcja zamiany tekstu na mowę w usłudze Mowa obsługuje ponad 400 głosów i ponad 140 języków i wariantów. Pełną listę możesz uzyskać lub wypróbować w galerii głosów.
Określ język lub głos SpeechConfig, aby dopasować do tekstu wejściowego i użyć określonego głosu:
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-Ava:DragonHDLatestNeural")
Wszystkie neuronowe głosy są wielojęzyczne i płynne we własnym języku i języku angielskim. Jeśli na przykład tekst wejściowy w języku angielskim to "Cieszę się na możliwość wypróbowania funkcji zamiany tekstu na mowę", a następnie wybierzesz es-ES-Ximena:DragonHDLatestNeural, to tekst jest mówiony po angielsku z hiszpańskim akcentem.
Jeśli głos nie mówi w języku tekstu wejściowego, usługa rozpoznawania mowy nie tworzy syntetyzowanego dźwięku. Aby uzyskać pełną listę obsługiwanych głosów neuronowych, zobacz Obsługa języka i głosu dla usługi mowy.
Uwaga
Domyślny głos to pierwszy głos zwracany dla lokalizacji z interfejsu API Listy Głosów.
Głos, który mówi, jest określany w kolejności priorytetu w następujący sposób:
- Jeśli nie ustawisz
SpeechSynthesisVoiceNamelubSpeechSynthesisLanguage, domyślny głos dlaen-USbędzie użyty. - Jeśli tylko ustawisz
SpeechSynthesisLanguage, mówi domyślny głos dla określonego ustawienia regionalnego. - Jeśli zarówno
SpeechSynthesisVoiceName, jak iSpeechSynthesisLanguagesą ustawione, ustawienieSpeechSynthesisLanguagejest ignorowane. Głos, który określisz przy użyciuSpeechSynthesisVoiceName, mówi. - Jeśli element głosowy jest ustawiony przy użyciu języka znaczników syntezy mowy (SSML), ustawienia
SpeechSynthesisVoiceNameiSpeechSynthesisLanguagesą ignorowane.
Podsumowując, kolejność priorytetu można opisać jako:
SpeechSynthesisVoiceName |
SpeechSynthesisLanguage |
SSML | Wynik |
|---|---|---|---|
| ✗ | ✗ | ✗ | Domyślny głos dla en-US wypowiedzi |
| ✗ | ✔ | ✗ | Domyślny głos dla określonych ustawień regionalnych mówi. |
| ✔ | ✔ | ✗ | Głos, który określisz przy użyciu SpeechSynthesisVoiceName, mówi. |
| ✔ | ✔ | ✔ | Głos, który określisz za pomocą języka znaczników SSML, przemawia. |
Dostosowywanie cech mowy przy użyciu języka SSML
Możesz użyć Języka Znaczników Syntezy Mowy (SSML), aby dostosować tonację, wymowę, szybkość mówienia, głośność i inne parametry w wyjściowym tekście mowy, przesyłając żądania zgodnie ze schematem XML. W tej sekcji przedstawiono przykład zmiany głosu. Aby uzyskać więcej informacji, zobacz Omówienie języka znaczników syntezy mowy.
Aby rozpocząć korzystanie z języka SSML do dostosowywania, należy wprowadzić niewielką zmianę, która przełącza głos.
Najpierw utwórz nowy plik XML konfiguracji SSML w katalogu głównym projektu. W tym przykładzie jest to ssml.xml. Element główny to zawsze <speak>. Zawijanie tekstu w elemecie <voice> umożliwia zmianę głosu przy użyciu parametru name . Aby uzyskać pełną listę obsługiwanych głosów neuronowych, zobacz Obsługiwane języki.
<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
<voice name="en-US-Ava:DragonHDLatestNeural">
When you're on the freeway, it's a good idea to use a GPS.
</voice>
</speak>
Następnie należy zmienić żądanie syntezy mowy, aby odwołać się do pliku XML. Żądanie jest w większości takie samo, ale zamiast używać funkcji SpeakTextAsync(), należy użyć funkcji SpeakSsmlAsync(). Ta funkcja oczekuje ciągu XML, więc najpierw załadujesz konfigurację SSML jako ciąg. Od tego momentu obiekt wynikowy jest dokładnie taki sam jak w poprzednich przykładach.
Uwaga
Aby ustawić głos bez użycia języka SSML, możesz ustawić właściwość na SpeechConfig używając speechConfig.SetSpeechSynthesisVoiceName("en-US-Ava:DragonHDLatestNeural").
Subskrypcja zdarzeń syntezatora
Możesz chcieć uzyskać więcej szczegółowych informacji na temat przetwarzania i wyników zamiany tekstu na mowę. Na przykład możesz chcieć wiedzieć, kiedy syntetyzator uruchamia się i zatrzymuje, lub możesz chcieć wiedzieć o innych zdarzeniach napotkanych podczas syntezy.
Używając narzędzia SpeechSynthesizer do zamiany tekstu na mowę, możesz subskrybować zdarzenia w tej tabeli:
| Wydarzenie | opis | Przypadek użycia |
|---|---|---|
BookmarkReached |
Sygnał, że osiągnięto zakładkę. Aby wyzwolić zdarzenie osiągnięcia zakładki, w bookmark wymagany jest element . To zdarzenie zgłasza czas, jaki upłynął w danych wyjściowych audio między rozpoczęciem syntezy a elementem bookmark . Właściwość zdarzenia Text to wartość typu string, którą ustawiłeś w atrybucie mark zakładki. Elementy bookmark nie są wypowiadane. |
Możesz użyć elementu bookmark, aby wstawić niestandardowe znaczniki w SSML w celu uzyskania przesunięcia każdego znacznika w strumieniu audio. Element bookmark może służyć do odwoływania się do określonej lokalizacji w sekwencji tekstu lub tagu. |
SynthesisCanceled |
Sygnały, że synteza mowy została anulowana. | Możesz potwierdzić, kiedy synteza zostanie anulowana. |
SynthesisCompleted |
Sygnały, że synteza mowy jest kompletna. | Można potwierdzić, kiedy synteza jest zakończona. |
SynthesisStarted |
Sygnały, że rozpoczęła się synteza mowy. | Możesz potwierdzić, kiedy rozpoczęto syntezę. |
Synthesizing |
Sygnały, że synteza mowy jest w toku. To zdarzenie jest uruchamiane za każdym razem, gdy zestaw SDK otrzymuje fragment dźwięku z usługi Mowa. | Możesz potwierdzić, kiedy synteza jest w toku. |
VisemeReceived |
Sygnały, że odebrano zdarzenie viseme. | Visemes są często używane do reprezentowania kluczowych pozycji w obserwowanej wypowiedzi. Kluczowe pozy obejmują położenie ust, szczęki i języka w produkcji konkretnej fonemy. Możesz użyć visemów, aby animować twarz postaci w trakcie odtwarzania dźwięku mowy. |
WordBoundary |
Sygnalizuje, że została odebrana granica słowa. To zdarzenie jest wywoływane na początku każdego nowego słowa mówionego, znaku interpunkcyjnego i zdania. Zdarzenie zgłasza przesunięcie czasowe bieżącego słowa w znacznikach od początku sygnału dźwięku wyjściowego. To zdarzenie zgłasza również położenie znaku w tekście wejściowym lub SSML bezpośrednio przed wyrazem, który ma być wypowiadany. | To zdarzenie jest często używane do pobierania względnych pozycji tekstu i odpowiadającego mu dźwięku. Możesz chcieć wiedzieć o nowym słowie, a następnie podjąć działania na podstawie czasu. Możesz na przykład uzyskać informacje, które mogą pomóc w podjęciu decyzji o tym, kiedy i na jak długo akcentować wyrazy podczas ich wypowiadania. |
Uwaga
Zdarzenia są zgłaszane, gdy dane wyjściowe audio stają się dostępne, co następuje szybciej niż odtwarzanie na urządzeniu wyjściowym. Obiekt wywołujący musi odpowiednio synchronizować procesy przesyłania strumieniowego i w czasie rzeczywistym.
Oto przykład pokazujący sposób subskrybowania zdarzeń na potrzeby syntezy mowy.
Ważne
Używaj kluczy interfejsu API z ostrożnością. Nie dołączaj klucza interfejsu API bezpośrednio do kodu i nigdy nie publikuj go publicznie. Jeśli używasz klucza interfejsu API, zapisz go bezpiecznie w usłudze Azure Key Vault. Aby uzyskać więcej informacji na temat bezpiecznego używania kluczy interfejsu API w aplikacjach, zobacz Klucze interfejsu API w usłudze Azure Key Vault.
Aby uzyskać więcej informacji na temat zabezpieczeń usług sztucznej inteligencji, zobacz Uwierzytelnianie żądań w usługach Azure AI.
Możesz postępować zgodnie z instrukcjami w szybkim starcie, ale zastąp zawartość tego speech-synthesis.go pliku następującym kodem w języku Go:
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)
}
}
}
Więcej przykładów zamiany tekstu na mowę można znaleźć w witrynie GitHub.
Uruchamianie i używanie kontenera
Kontenery umożliwiające przetwarzanie mowy udostępniają interfejsy API punktów końcowych zapytań opartych na websocketach, które są dostępne za pośrednictwem SDK Przetwarzania Mowy i CLI usługi Przetwarzania Mowy. Domyślnie zestaw SDK usługi Mowa i interfejs wiersza polecenia usługi Mowa używają publicznej usługi rozpoznawania mowy. Aby użyć kontenera, należy zmienić metodę inicjowania. Użyj adresu URL hosta kontenera zamiast klucza i regionu.
Aby uzyskać więcej informacji na temat kontenerów, zobacz Instalowanie i uruchamianie kontenerów usługi Mowa za pomocą platformy Docker.
Dokumentacja referencyjna | Pakiet (do pobrania) | Dodatkowe przykłady na GitHub
W tym przewodniku z instrukcjami poznasz typowe wzorce projektowe służące do wykonywania syntezy mowy w tekście.
Aby uzyskać więcej informacji na temat następujących obszarów, zobacz Co to jest zamiana tekstu na mowę?
- Uzyskiwanie odpowiedzi jako strumieni w pamięci.
- Dostosowywanie szybkości próbkowania danych wyjściowych i szybkości bitów.
- Przesyłanie żądań syntezy przy użyciu języka znaczników syntezy mowy (SSML).
- Korzystanie z głosów neuronowych.
- Subskrybowanie eventów i reagowanie na wyniki.
Wymagania wstępne
- Subskrypcja platformy Azure. Możesz utworzyć go bezpłatnie.
- Utwórz zasób Foundry dla usługi Speech w portalu Azure.
- Pobierz klucz zasobu Mowy oraz region. Po wdrożeniu zasobu usługi Mowa wybierz pozycję Przejdź do zasobu , aby wyświetlić klucze i zarządzać nimi.
Instalowanie zestawu SPEECH SDK i przykładów
Repozytorium Azure-Samples/cognitive-services-speech-sdk zawiera przykłady napisane w języku Objective-C dla systemów iOS i Mac. Wybierz link, aby wyświetlić instrukcje instalacji dla każdego przykładu:
- Syntetyzowanie mowy w języku Objective-C w systemie macOS
- Syntetyzowanie mowy w języku Objective-C w systemie iOS
- Więcej przykładów dla języka Objective-C w systemie iOS
Używanie niestandardowego punktu końcowego
Niestandardowy punkt końcowy jest funkcjonalnie identyczny ze standardowym punktem końcowym używanym do obsługi żądań zamiany tekstu na mowę.
Jedną z różnic jest to, że EndpointId należy określić, aby używać niestandardowego głosu za pośrednictwem zestawu Speech SDK. Możesz rozpocząć od szybkiego startu z tekstem na mowę, a następnie zaktualizować kod zawierając EndpointId i SpeechSynthesisVoiceName.
SPXSpeechConfiguration *speechConfig = [[SPXSpeechConfiguration alloc] initWithSubscription:speechKey region:speechRegion];
speechConfig.speechSynthesisVoiceName = @"YourCustomVoiceName";
speechConfig.EndpointId = @"YourEndpointId";
Aby użyć głosu niestandardowego za pomocą języka SSML (Speech Synthesis Markup Language), określ nazwę modelu jako nazwę głosu. W tym przykładzie użyto głosu YourCustomVoiceName.
<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>
Uruchamianie i używanie kontenera
Kontenery umożliwiające przetwarzanie mowy udostępniają interfejsy API punktów końcowych zapytań opartych na websocketach, które są dostępne za pośrednictwem SDK Przetwarzania Mowy i CLI usługi Przetwarzania Mowy. Domyślnie zestaw SDK usługi Mowa i interfejs wiersza polecenia usługi Mowa używają publicznej usługi rozpoznawania mowy. Aby użyć kontenera, należy zmienić metodę inicjowania. Użyj adresu URL hosta kontenera zamiast klucza i regionu.
Aby uzyskać więcej informacji na temat kontenerów, zobacz Instalowanie i uruchamianie kontenerów usługi Mowa za pomocą platformy Docker.
W tym przewodniku z instrukcjami poznasz typowe wzorce projektowe służące do wykonywania syntezy mowy w tekście.
Aby uzyskać więcej informacji na temat następujących obszarów, zobacz Co to jest zamiana tekstu na mowę?
- Uzyskiwanie odpowiedzi jako strumieni w pamięci.
- Dostosowywanie szybkości próbkowania danych wyjściowych i szybkości bitów.
- Przesyłanie żądań syntezy przy użyciu języka znaczników syntezy mowy (SSML).
- Korzystanie z głosów neuronowych.
- Subskrybowanie eventów i reagowanie na wyniki.
Wymagania wstępne
- Subskrypcja platformy Azure. Możesz utworzyć go bezpłatnie.
- Utwórz zasób Foundry dla usługi Speech w portalu Azure.
- Pobierz klucz zasobu Mowy oraz region. Po wdrożeniu zasobu usługi Mowa wybierz pozycję Przejdź do zasobu , aby wyświetlić klucze i zarządzać nimi.
Pobierz i zainstaluj
Wykonaj następujące kroki i zapoznaj się z przewodnikiem szybkiego startu CLI Mowa w celu uzyskania innych wymagań dla Twojej platformy.
Uruchom następujące polecenie .NET CLI, aby zainstalować Speech CLI:
dotnet tool install --global Microsoft.CognitiveServices.Speech.CLIUruchom następujące polecenia, aby skonfigurować klucz zasobu Speech i region. Zastąp
SUBSCRIPTION-KEYkluczem zasobu usługi Mowa i zastąpREGIONregionem zasobu.spx config @key --set SUBSCRIPTION-KEY spx config @region --set REGION
Syntetyzowanie mowy przy użyciu głośnika
Teraz jesteś gotowy do uruchomienia interfejsu wiersza polecenia (CLI) usługi Syntezy Mowy, aby syntetyzować mowę z tekstu.
W oknie konsoli zmień katalog na ten zawierający plik binarny Interfejsu wiersza polecenia Mowy. Uruchom następujące polecenie:
spx synthesize --text "I'm excited to try text to speech"
Interfejs wiersza polecenia Speech CLI generuje język naturalny w języku angielskim przez głośnik komputera.
Syntetyzowanie mowy do pliku
Uruchom następujące polecenie, aby zmienić dane wyjściowe z głośnika na plik .wav :
spx synthesize --text "I'm excited to try text to speech" --audio output greetings.wav
Usługa CLI Mowy generuje naturalny język angielski i zapisuje do pliku audio greetings.wav.
Uruchamianie i używanie kontenera
Kontenery umożliwiające przetwarzanie mowy udostępniają interfejsy API punktów końcowych zapytań opartych na websocketach, które są dostępne za pośrednictwem SDK Przetwarzania Mowy i CLI usługi Przetwarzania Mowy. Domyślnie zestaw SDK usługi Mowa i interfejs wiersza polecenia usługi Mowa używają publicznej usługi rozpoznawania mowy. Aby użyć kontenera, należy zmienić metodę inicjowania. Użyj adresu URL hosta kontenera zamiast klucza i regionu.
Aby uzyskać więcej informacji na temat kontenerów, zobacz Instalowanie i uruchamianie kontenerów usługi Mowa za pomocą platformy Docker.
Dokumentacja referencyjna | Pakiet (do pobrania) | Dodatkowe przykłady na GitHub
W tym przewodniku z instrukcjami poznasz typowe wzorce projektowe służące do wykonywania syntezy mowy w tekście.
Aby uzyskać więcej informacji na temat następujących obszarów, zobacz Co to jest zamiana tekstu na mowę?
- Uzyskiwanie odpowiedzi jako strumieni w pamięci.
- Dostosowywanie szybkości próbkowania danych wyjściowych i szybkości bitów.
- Przesyłanie żądań syntezy przy użyciu języka znaczników syntezy mowy (SSML).
- Korzystanie z głosów neuronowych.
- Subskrybowanie eventów i reagowanie na wyniki.
Wymagania wstępne
- Subskrypcja platformy Azure. Możesz utworzyć go bezpłatnie.
- Utwórz zasób Foundry dla usługi Speech w portalu Azure.
- Pobierz klucz zasobu Mowy oraz region. Po wdrożeniu zasobu usługi Mowa wybierz pozycję Przejdź do zasobu , aby wyświetlić klucze i zarządzać nimi.
Instalowanie zestawu SPEECH SDK i przykładów
Repozytorium Azure-Samples/cognitive-services-speech-sdk zawiera przykłady napisane w języku Swift dla systemów iOS i Mac. Wybierz link, aby wyświetlić instrukcje instalacji dla każdego przykładu:
- Syntetyzowanie mowy w języku Swift w systemie macOS
- Syntetyzowanie mowy w języku Swift w systemie iOS
Uruchamianie i używanie kontenera
Kontenery umożliwiające przetwarzanie mowy udostępniają interfejsy API punktów końcowych zapytań opartych na websocketach, które są dostępne za pośrednictwem SDK Przetwarzania Mowy i CLI usługi Przetwarzania Mowy. Domyślnie zestaw SDK usługi Mowa i interfejs wiersza polecenia usługi Mowa używają publicznej usługi rozpoznawania mowy. Aby użyć kontenera, należy zmienić metodę inicjowania. Użyj adresu URL hosta kontenera zamiast klucza i regionu.
Aby uzyskać więcej informacji na temat kontenerów, zobacz Instalowanie i uruchamianie kontenerów usługi Mowa za pomocą platformy Docker.