はじめに
-
Elixir楽しんでいますか
- 長い間お世話になりましたdocomo Developer supportさんが3/31をもってサービス終了とのことです
- 私は音声合成【Powered by NTTテクノクロス】をNervesアプリで利用させていただいておりました
- ありがとうございました
- @takasehideki先生と、Interface 2021年1月号にてこのAPIの使い方を記載させていただきました
- 残念ながら終了とのことで他のものにのせ替えを検討していました
- 「Raspberry PIを喋らせよう クラウドいろいろ」を拝見して、AzureのText to Speechサービスを使うことにしました
- なにせ私は「日本マイクロソフト賞④」受賞者ですから
- もう一回いいます
- $\huge{日本マイクロソフト賞④}$
- 受賞していますから
- ありがとうございます!
- 本記事は2021/3/15(金)開催のautoracex #16という純粋なもくもく会での成果です
2021/03/20 追記
- ElixirでText to Speech REST API(Azure, ニューラル音声)を使ってみる の記事の内容のほうがソースコードが洗練されていますし、フレンドリーなボイスを聞くことができます
ドキュメント
依存関係
mix.exs
defp deps do
[
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
{:httpoison, "~> 1.8"},
{:jason, "~> 1.2"}
]
end
$ mix deps.get
ソースコード
lib/azure/text_to_speech.ex
defmodule Azure.TextToSpeech do
@subscription_key "ひみつ"
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://japaneast.api.cognitive.microsoft.com/sts/v1.0/issuetoken"
|> HTTPoison.post!("", headers)
|> Map.get(:body)
end
def voices_list(token) do
"https://japaneast.tts.speech.microsoft.com/cognitiveservices/voices/list"
|> HTTPoison.get!(authorization_header(token))
|> Map.get(:body)
|> Jason.decode!()
end
def voice(token, text) do
headers =
authorization_header(token)
|> Keyword.merge(
"Content-Type": "application/ssml+xml",
"X-Microsoft-OutputFormat": "riff-24khz-16bit-mono-pcm",
"User-Agent": "awesome"
)
locale = "ja-JP"
gender = "Female"
%{"Name" => name} =
voices_list(token)
|> Enum.filter(fn %{"Locale" => l} -> l == locale end)
|> Enum.filter(fn %{"Gender" => g} -> g == gender end)
|> Enum.random()
body = """
<speak version='1.0' xml:lang='#{locale}'>
<voice xml:lang='#{locale}' xml:gender='#{gender}' name='#{name}'>
<prosody volume="100.0">
#{text}
</prosody>
</voice>
</speak>
"""
"https://japaneast.tts.speech.microsoft.com/cognitiveservices/v1"
|> HTTPoison.post!(body, headers)
|> Map.get(:body)
end
defp authorization_header(token) do
[Authorization: "Bearer #{token}"]
end
end
-
User-Agent
は必須って書いてあるけど、サンプルにはないし、実際なくても動いたしどうなんだろう? - という件はIssueを書いてみました
- どうなるでしょう
サブスクリプションキーの取得方法
- Azureにサインアップしましょう
-
Text to Speechのページにて「Azure のご利用者なら、このサービスを今すぐ無料でお試しください」のリンクから飛ぶのがわかりやすいです
- 逆にコンソールから順にたどっていくやりかたではMarketplace? だかなんだかでてきて私にはよくわからなかったです
- 飛んだ先のフォームでは、価格レベルは、Free F0を選びました
- Cognitive Services の価格—Speech Servicesにあるように、standardの使い方なら、1 か月あたり 5 million 文字まで無料とのことらしいです
- (5 million 文字とか言われてもピンときていません)
- 毎朝ちょっとした天気予報をしゃべらせるくらいならきっと範囲内でしょう
Run
$ iex -S mix
iex> Azure.TextToSpeech.run!("こんにちは Azure awesome") |> (&(File.write("output.wav", &1))).()
-
output.wav
というファイルに書き出しています -
(&(File.write("output.wav", &1))).()
はカッコばかり書いて - $\huge{カッコつけているだけです}$
macOSなら
$ afplay output.wav
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 さん作 )