基于 Azure 的认知服务将文本合成语音
基于 Azure 的認(rèn)知服務(wù)將文本合成語音
Intro
前幾天發(fā)了一個(gè) .NET 20 周年祝福視頻,語音是通過 Azure 的認(rèn)知服務(wù)合成的,
下面就來介紹一下如何將使用 Azure 的認(rèn)識(shí)服務(wù)實(shí)現(xiàn)將文本合成為語音
Prepare
你可以在 Azure Portal 上創(chuàng)建一個(gè)免費(fèi)的語音服務(wù),搜索 Speech 即可,在創(chuàng)建的時(shí)候可以 Pricing tier 可以選擇 Free F0 就是對(duì)應(yīng)的免費(fèi)版本,免費(fèi)版有調(diào)用次數(shù)限制,但是對(duì)于測(cè)試應(yīng)該足夠了,詳細(xì)可以參考:
https://azure.microsoft.com/zh-cn/pricing/details/cognitive-services/speech-services/
在創(chuàng)建成功之后可以在對(duì)應(yīng)的資源界面中 “密鑰和終結(jié)點(diǎn)” 頁面里找到調(diào)用 API 需要的密鑰
微軟的語音服務(wù)支持很多不同的語言,不同的語音類型,我們可以根據(jù)需要進(jìn)行選擇,你可以在這個(gè)頁面試用,來選擇合適的語音
https://azure.microsoft.com/zh-cn/services/cognitive-services/text-to-speech/#features
Sample
首先我們需要使用到語音服務(wù)的 SDK ,引用 NuGet 包Microsoft.CognitiveServices.Speech
文本合成語音首先需要指定一個(gè)語音類型,語音類型是分語言的,我們可以指定語言直接合成:
const?string?locale?=?"zh-CN"; //?將?key?直接替換為自己的密鑰或者設(shè)置環(huán)境變量值為自己的密鑰 var?key?=?Environment.GetEnvironmentVariable("SpeechSubscriptionKey"); var?config?=?SpeechConfig.FromSubscription(key,?"eastasia");//?支持的語言列表:https://docs.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support config.SpeechSynthesisLanguage?=?locale;using?var?synthesizer?=?new?SpeechSynthesizer(config); await?synthesizer.SpeakTextAsync(text);除了指定的語言,我們也可以指定語言對(duì)應(yīng)的語音類型,可以通過 SDK 獲取指定語言的語音類型,支持的語言列表可以參考:https://docs.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support
//?Creates?a?speech?synthesizer using?var?synthesizer?=?new?SpeechSynthesizer(config); using?var?voicesResult?=?await?synthesizer.GetVoicesAsync(locale); var?voices?=?voicesResult.Voices;每個(gè)語音類型支持不同的語音風(fēng)格
可以在微軟的線上示例 https://azure.microsoft.com/zh-cn/services/cognitive-services/text-to-speech/#features 嘗試不同的語音類型,選擇合適的語音類型,然后就可以進(jìn)行下一步的語音合成
語音對(duì)應(yīng)的 value 就是對(duì)應(yīng)的語音類型,配置 config 的 SpeechSynthesisVoiceName,也可以使用上面獲取到的語音對(duì)應(yīng)的 ShortName
var?text?=?@".NET?20?周年生日快樂"; var?voiceName?=?"zh-CN-XiaoxiaoNeural";config.SpeechSynthesisVoiceName?=?voiceName; using?var?speechSynthesizer?=?new?SpeechSynthesizer(config); await?speechSynthesizer.SpeakTextAsync(text);我們可以使用多種方式進(jìn)行合成語音,前面使用是默認(rèn)方式,默認(rèn)方式語音會(huì)直接通過本地的麥克風(fēng)直接播放
我們也可以輸出語音到指定文件,示例如下:
var?text?=?@".NET?20?周年生日快樂"; var?voiceName?=?voices[0].ShortName; config.SpeechSynthesisVoiceName?=?voiceName; var?outputFileName?=?$"output-{voice.ShortName}.wav"; using?(var?output?=?AudioConfig.FromWavFileOutput(outputFileName)) {using?var?speechSynthesizer?=?new?SpeechSynthesizer(config,?output);using?var?speechSynthesisResult?=?await?speechSynthesizer.SpeakTextAsync(text);Console.WriteLine($"Result:?{speechSynthesisResult.Reason}"); }除此之外我們還可以輸出到一個(gè)數(shù)據(jù)流中,我們可以使用 AuditDataStream 來實(shí)現(xiàn):
using?var?streamSynthesizer?=?new?SpeechSynthesizer(config,?null); var?streamResult?=?await?streamSynthesizer.SpeakTextAsync(text); using?var?audioDataStream?=?AudioDataStream.FromResult(streamResult);//?SaveToFile //await?audioDataStream.SaveToWaveFileAsync(outputFileName);//?Reads?data?from?the?stream using?var?ms?=?new?MemoryStream(); var?buffer?=?new?byte[32000]; uint?filledSize; while?((filledSize?=?audioDataStream.ReadData(buffer))?>?0) {ms.Write(buffer,?0,?(int)filledSize); } Console.WriteLine($"Totally?{ms.Length}?bytes?received.");除了前面之前使用一段文本,我們還可以使用 SSML 來定制語音
語音合成標(biāo)記語言 (SSML) 是一種基于 XML 的標(biāo)記語言,可讓開發(fā)人員指定如何使用文本轉(zhuǎn)語音服務(wù)將輸入文本轉(zhuǎn)換為合成語音。與純文本相比,SSML 可讓開發(fā)人員微調(diào)音節(jié)、發(fā)音、語速、音量以及文本轉(zhuǎn)語音輸出的其他屬性。SSML 可自動(dòng)處理正常的停頓(例如,在句號(hào)后面暫停片刻),或者在以問號(hào)結(jié)尾的句子中使用正確的音調(diào)。
使用 SSML 時(shí)請(qǐng)注意,特殊字符必須要轉(zhuǎn)義
var?ssml?=?$@"<speak?xmlns=""http://www.w3.org/2001/10/synthesis""?xmlns:mstts=""http://www.w3.org/2001/mstts""?xmlns:emo=""http://www.w3.org/2009/10/emotionml""?version=""1.0""?xml:lang=""en-US""><voice?name=""zh-CN-XiaoxiaoNeural""><prosody?rate=""0%""?pitch=""50%"">{text}</prosody></voice></speak>"; using?var?ssmlSynthesisResult?=?await?synthesizer.SpeakSsmlAsync(ssml); Console.WriteLine($"Result:?{ssmlSynthesisResult.Reason}");可以通過 <voice name="zh-CN-XiaoxiaoNeural">測(cè)試</voice> 來指定某一段文本要使用的語音類型,不同的文本可以使用不同的語音類型,語音可以通過 style 來配置,支持的 style 需要從前面的語音支持的 StyleList 中獲取,如:
<voice?name="zh-CN-XiaoxiaoNeural"><mstts:express-as?style="cheerful">你可將此文本替換為所需的任何文本。你可在此文本框中編寫或在此處粘貼你自己的文本</mstts:express-as> </voice>也可以配置語音的語速和音調(diào),如下面的 prosody 中的 rate 就是語速,0是正常語速,rate="10%" 就是加快 10%,pitch 是音調(diào)的控制,pitch="10%" 就是音調(diào)提高 10%
<speakxmlns="http://www.w3.org/2001/10/synthesis"xmlns:mstts="http://www.w3.org/2001/mstts"xmlns:emo="http://www.w3.org/2009/10/emotionml"?version="1.0"?xml:lang="en-US"><voice?name="zh-CN-XiaoxiaoNeural"><mstts:express-as?style="cheerful"?><prosody?rate="10%"?pitch="10%">你可將此文本替換為所需的任何文本。你可在此文本框中編寫或在此處粘貼你自己的文本。</prosody></mstts:express-as></voice> </speak>使用 SSML 生成語音示例如下:
var?ssml?=?$@"<speak?xmlns=""http://www.w3.org/2001/10/synthesis""?xmlns:mstts=""http://www.w3.org/2001/mstts""?xmlns:emo=""http://www.w3.org/2009/10/emotionml""?version=""1.0""?xml:lang=""en-US""><voice?name=""zh-CN-XiaoxiaoNeural""><prosody?rate=""0%""?pitch=""50%"">{text}</prosody></voice></speak>"; using?var?ssmlSynthesisResult?=?await?synthesizer.SpeakSsmlAsync(ssml); Console.WriteLine($"Result:?{ssmlSynthesisResult.Reason}");More
一般的我們基本可以使用普通的文本合成語音,如果要實(shí)現(xiàn)高級(jí)的語音服務(wù),可以嘗試一下 SSML 用法
使用 SSML 時(shí),SSML 里定義的語音類型優(yōu)先級(jí)最高,不會(huì)被 config 中的語音類型覆蓋
更多用法可以自己再去發(fā)掘一下~~
References
https://azure.microsoft.com/zh-cn/services/cognitive-services/text-to-speech/
https://docs.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support
https://github.com/WeihanLi/SamplesInPractice/blob/master/AzureSamples/SpeechSample/Program.cs
https://docs.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support
https://docs.microsoft.com/zh-cn/azure/cognitive-services/speech-service/speech-synthesis-markup?tabs=csharp
https://github.com/Azure-Samples/cognitive-services-speech-sdk
總結(jié)
以上是生活随笔為你收集整理的基于 Azure 的认知服务将文本合成语音的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何对一组 IP 地址 进行排序?
- 下一篇: 如何编译 dotnet/runtime