CoeFontをC#で使ってみる

CoeFontを使う機会があったので軽くまとめます。

## CoeFontって？
自分の声をAI合成音声化するサービスです
さらにみんなが登録した声も使うことができます

https://coefont.cloud/


CoeFontを利用するには、クレジットカードを必要とするアカウント登録が必要となります。
30日間は、無料ですので興味があれば試してみてください。

coeFontごとにポイントが指定されており、そのポイントを使用して利用することができます。
※５ptのcoeFontを使用した場合は、最大１０，０００文字まで利用可能


## CoeFont Cloud APIを使ってみる
### CoeFont Cloud API
CoeFont Cloudを使用するためにAPIです。
このAPIを使うことで外部から自由に音声を作成することができます。

https://docs.coefont.cloud/

pythonや、nodejsのサンプルコードがありますので、これらを使う場合は比較的簡単に扱えると思います。


### アクセスキーと、クライアントシークレットを取得する
[CoeFont Cloud](https://coefont.cloud/)にログインをしたら、右上の人型アイコンをクリックし、「アカウント設定」を選択します。

![アカウント設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/fd9c1307-fbe4-bcf9-01c0-6943a90c588b.png)


アカウント設定画面が表示されたら、「API情報」のメニューがあるので、クリックし、「アクセス情報」を発行します（以下の画像は既に発行済み）
![API情報](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/ec26fc9f-406d-0114-fa44-cd80a8ce14cf.png)





###　C#でAPIを使ってみる
Azure FunctionsをC#で使うことが多いため、今回はC#で使えるサンプルを記載します。

利用までの手順は以下の通りです。

1. UNIX時間(UTC)を取得する
2. 送信用のjsonを作成する
3. １と2を使用しHMAC-SHA256でハッシュ化しhex値を取得する
4. HeaderとBodyを設定する
5. APIを呼び出して、音声を取得する

#### 1. UNIX時間（UTC）を取得する
```c#
// UTCのUnixTimeStampを取得する
string unixTime = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds().ToString();
```

#### 2.送信用のjsonリクエストBodyを作成する

```c#
// 送信用の情報を生成します。
var body = new Dictionary<string, object>()
{
    { "coefont", << CoeFontのUUID >> },
    { "text"   , << 変換する文字列 >> },
    { "format" , "wav"}
};
            
// 送信用のパラメータをJONS化する 
var body_json = JsonConvert.SerializeObject(body);
```

##### CoeFontのUUID
CoeFontのUUIDは、各種CoeFontの紹介ページのURLに表示されているものになります。
利用するCoeFontによっては、本人への申請が必要なものもあります。
承諾がない場合は、エラーとなりますのでご注意ください。
![UUID](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/f0a2dba1-a635-3a1b-217b-8a94d91b0fbc.png)

##### 送信パラメータについて
音声のピッチや、抑揚、句点の間隔（秒）などを細かく設定することができます。
coeFontの情報と、音声変換テキストは必須ですが、あとは任意です。

詳しくは、以下のURLをご参照ください

https://docs.coefont.cloud/#tag/Text2speech/paths/~1text2speech/post

#### 3.１と2を使用しHMAC-SHA256でハッシュ化しhex値を取得する

クライアントシークレットを用いて、UNIX時間（UTC)と、JSON情報をからHMAC-SHA256でハッシュ化した結果のhex値の文字列として取得します。

```C#
// シークレットキーのByte情報を取得            
var hmac_key = Encoding.UTF8.GetBytes( <<クライアントシークレット>> );
// UNIX時間(UTC) + 本文のJSONが、ハッシュ化対象となります。
var hmac_body = Encoding.UTF8.GetBytes(unixTime + body_json);
 
string signature = "";
using (HMACSHA256 hmac = new HMACSHA256(hmac_key)){
    //ハッシュ化します。
    var hash = hmac.ComputeHash(hmac_body, 0, hmac_body.Length);
    //ハッシュ化したデータをHEX化します。                
    signature = BitConverter.ToString(hash);    
}
//HEXから「ー」を削除します。
signature = signature.Replace("-", "").ToLower();
```

#### 4. HeaderとBodyを設定する
1で取得したUNIX時間（UTC)と、3で取得したhex値の文字列、アクセスキーをHeaderに設定します。
Bodyには、２で作成したJSONの文字列を設定します。

```C#
// ヘッダを設定します
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post,"https://api.coefont.cloud/v1/text2speech");
request.Headers.Add("X-Coefont-Date", unixTime);
request.Headers.Add("X-Coefont-Content", << 3で作成したハッシュのhex文字列 >> );
request.Headers.Add("Authorization", << アクセスキー >>);
           
//# Bodyの指定
var httpContent = new StringContent(body_json, Encoding.UTF8, "application/json");  
request.Content = httpContent;
```

#### APIを呼び出して、音声を取得する

あとは、APIを呼び出します。
リクエストボディで指定した形式の音声が取得されますので、受信データを好きにご活用ください。

```C#
using (var client = new HttpClient()){

    var response = await httpClient.SendAsync(request);
    if(response.IsSuccessStatusCode){
      //~受信後の処理~
    }
}
```

## まとめ
CoeFont恐るべき性能です。