はじめに
- Elixir楽しんでいますか
- What's new in Azure Cognitive Servicesをみました
- 07:50くらいから紹介されているNeural VoiceをElixirで使ってみます
- COVID-19のAssessment(Azure Health Bot)を例にその話の流れからNeural Voiceが紹介されています
- You might need to hear a friendly voice, especially when you're sick and worried.
- フレンドリーなヴォイスを聞きたいよね、特に病気のときや心配ごとがあるときには。
- 私のNervesアプリケーションに組み込んで、朝、素敵なボイスで起こしてもらいたいとおもっています
- Nervesとは、ElixirでIoTが楽しめるナウでヤングでCoolなすごいやつです
-
An Evaluation of Real-Time Performance for Nerves
- 2:00あたりをご覧ください
-
TORIFUKUKaiou/hello_nerves
- 私のごった煮Nervesプロジェクト
前提
Text to Speech
ドキュメント
-
Text to Speech REST API
- ここを参考にします
Text to Speechが使えるようにする
- 今回はニューラル音声を使いたいので、サポートしているリージョンを選んでおいてください
-
https://docs.microsoft.com/ja-jp/azure/cognitive-services/speech-service/rest-text-to-speech#standard-and-neural-voices
- どのリージョンを選べばよいのかについては、を参照してください
- 私は「(US) 米国東部」を選びました
料金
- 料金は、https://azure.microsoft.com/ja-jp/pricing/details/cognitive-services/speech-services/ をご参照ください
- 1 か月あたり 0.5 million 文字まで無料
- 「0.5 million 文字」というのは私にはあんまりピンときていませんが、毎朝ちょっとしたテキストを話すくらいなら全然だいじょうぶなのではないかとおもっちょります
- 今日から使い始めますので、また1ヶ月後くらいに更新したいとおもいます
ソースコード
mix.exs
defp deps do
[
...
{:httpoison, "~> 1.8"},
{:jason, "~> 1.2"}
]
end
lib/azure/text_to_speech.ex
defmodule Azure.TextToSpeech do
@subscription_key "secret"
@locale "ja-JP"
@gender "Female"
@voice_type "Neural"
def run!(text) do
access_token()
|> voice(text)
end
def access_token do
headers = [
"Ocp-Apim-Subscription-Key": @subscription_key,
"Content-type": "application/x-www-form-urlencoded"
]
"https://eastus.api.cognitive.microsoft.com/sts/v1.0/issuetoken"
|> HTTPoison.post!("", headers)
|> Map.get(:body)
end
def voices_list(token) do
"https://eastus.tts.speech.microsoft.com/cognitiveservices/voices/list"
|> HTTPoison.get!(authorization_header(token))
|> Map.get(:body)
|> Jason.decode!()
end
def voice(token, text) do
%{"Name" => name} = select_voice(token)
headers =
authorization_header(token)
|> Keyword.merge(
"Content-Type": "application/ssml+xml",
"X-Microsoft-OutputFormat": "riff-24khz-16bit-mono-pcm",
"User-Agent": "awesome"
)
"https://eastus.tts.speech.microsoft.com/cognitiveservices/v1"
|> HTTPoison.post!(ssml(text, name), headers)
|> Map.get(:body)
end
defp authorization_header(token) do
[Authorization: "Bearer #{token}"]
end
defp select_voice(token) do
voices_list(token)
|> Enum.filter(fn %{"Locale" => l} -> l == @locale end)
|> Enum.filter(fn %{"Gender" => g} -> g == @gender end)
|> Enum.filter(fn %{"VoiceType" => vt} -> vt == @voice_type end)
|> Enum.random()
end
defp ssml(text, name) do
"""
<speak version='1.0' xml:lang='#{@locale}'>
<voice xml:lang='#{@locale}' xml:gender='#{@gender}' name='#{name}'>
<prosody volume="100.0">
#{text}
</prosody>
</voice>
</speak>
"""
end
end
-
@subscription_key
にはAzureのポータル画面からキーを取得して値をセットしてください - 「同じトークンを 9 分間使用することをお勧めします」は未実装
- たぶんAgentを使えばうまく書ける気がします
- この記事では取り扱いません(サボり)
Run!
$ mix deps.get
$ iex -S mix
iex> (
Azure.TextToSpeech.run!("Azure最高です!。Microsoft Igniteに参加してイベントに関する記事を投稿しよう! 詳しくはこちらをご参照ください。https://qiita.com/official-events/a50e99d62dc62d68a9c9")
|> (&(File.write("output", &1))).()
)
iex> :os.cmd('afplay output')
- 再生コマンドはmacOSの例です
- Raspberry Piの場合は、
aplay -q /tmp/output
な感じで再生してください-
Nervesの場合は、
/tmp/output
等に音声データを書き出してください
-
Nervesの場合は、
Wrapping Up
- フレンドリーなヴォイスが得られました!
- みなさんもお好きなプログラミング言語で、フレンドリーな音声を楽しんでみてください
- Enjoy Elixir
最後の最後に
Elixirってなによという方へ
- 2020/12/26時点くらいのスクリーンショット
- Elixirについてもっと知りたい方は下記の本をオススメします
-
elixir.jp Slackの
#autoracex
というところに私は入り浸っておりますのでお気軽にお声がけください -
勉強会が頻繁に行われています
- 私がよく参加している勉強会です
- autoracex 【毎週月曜】 主催
- Sapporo.beam 【毎週水曜】
- OkazaKirin.beam 【毎週木曜】
- fukuoka.ex/kokura.ex 【毎月2~3回】
- NervesJP 【毎月1回】
(@piacerex さん作 )